Revert "TODO epan/dissectors/asn1/kerberos/packet-kerberos-template.c new GSS flags"
[wireshark-sm.git] / epan / dissectors / packet-sua.c
blob9c0ca235c593f9a4833d5fde5237333661fd29bb
1 /* packet-sua.c
2 * Routines for SS7 SCCP-User Adaptation Layer (SUA) dissection
3 * It is hopefully (needs testing) compliant to
4 * https://tools.ietf.org/html/draft-ietf-sigtran-sua-08
5 * https://tools.ietf.org/html/rfc3868
7 * Copyright 2002, 2003, 2004 Michael Tuexen <tuexen [AT] fh-muenster.de>
9 * Wireshark - Network traffic analyzer
10 * By Gerald Combs <gerald@wireshark.org>
11 * Copyright 1998 Gerald Combs
13 * Copied from README.developer
15 * SPDX-License-Identifier: GPL-2.0-or-later
18 #include "config.h"
20 #include <epan/packet.h>
21 #include <epan/address_types.h>
22 #include <epan/prefs.h>
23 #include <epan/sctpppids.h>
24 #include <epan/tap.h>
25 #include <epan/to_str.h>
26 #include <epan/tfs.h>
28 #include <wsutil/array.h>
29 #include <wsutil/str_util.h>
30 #include <wsutil/ws_roundup.h>
32 #include "packet-mtp3.h"
33 #include "packet-sccp.h"
34 void proto_register_sua(void);
35 void proto_reg_handoff_sua(void);
37 #define SCTP_PORT_SUA 14001
39 #define RESERVED_1_LENGTH 1
40 #define RESERVED_2_LENGTH 2
41 #define RESERVED_3_LENGTH 3
43 #define VERSION_LENGTH 1
44 #define RESERVED_LENGTH 1
45 #define MESSAGE_CLASS_LENGTH 1
46 #define MESSAGE_TYPE_LENGTH 1
47 #define MESSAGE_LENGTH_LENGTH 4
48 #define COMMON_HEADER_LENGTH (VERSION_LENGTH + RESERVED_LENGTH + MESSAGE_CLASS_LENGTH + \
49 MESSAGE_TYPE_LENGTH + MESSAGE_LENGTH_LENGTH)
51 #define COMMON_HEADER_OFFSET 0
52 #define VERSION_OFFSET COMMON_HEADER_OFFSET
53 #define RESERVED_OFFSET (VERSION_OFFSET + VERSION_LENGTH)
54 #define MESSAGE_CLASS_OFFSET (RESERVED_OFFSET + RESERVED_LENGTH)
55 #define MESSAGE_TYPE_OFFSET (MESSAGE_CLASS_OFFSET + MESSAGE_CLASS_LENGTH)
56 #define MESSAGE_LENGTH_OFFSET (MESSAGE_TYPE_OFFSET + MESSAGE_TYPE_LENGTH)
58 #define PARAMETER_TAG_LENGTH 2
59 #define PARAMETER_LENGTH_LENGTH 2
60 #define PARAMETER_HEADER_LENGTH (PARAMETER_TAG_LENGTH + PARAMETER_LENGTH_LENGTH)
62 #define PARAMETER_TAG_OFFSET 0
63 #define PARAMETER_LENGTH_OFFSET (PARAMETER_TAG_OFFSET + PARAMETER_TAG_LENGTH)
64 #define PARAMETER_VALUE_OFFSET (PARAMETER_LENGTH_OFFSET + PARAMETER_LENGTH_LENGTH)
65 #define PARAMETER_HEADER_OFFSET PARAMETER_TAG_OFFSET
67 #define PROTOCOL_VERSION_RELEASE_1 1
69 static const value_string protocol_version_values[] = {
70 { PROTOCOL_VERSION_RELEASE_1, "Release 1" },
71 { 0, NULL } };
73 #define MESSAGE_CLASS_MGMT_MESSAGE 0
74 #define MESSAGE_CLASS_TFER_MESSAGE 1
75 #define MESSAGE_CLASS_SSNM_MESSAGE 2
76 #define MESSAGE_CLASS_ASPSM_MESSAGE 3
77 #define MESSAGE_CLASS_ASPTM_MESSAGE 4
78 #define MESSAGE_CLASS_CL_MESSAGE 7
79 #define MESSAGE_CLASS_CO_MESSAGE 8
80 #define MESSAGE_CLASS_RKM_MESSAGE 9
82 static const value_string message_class_values[] = {
83 { MESSAGE_CLASS_MGMT_MESSAGE, "Management messages" },
84 { MESSAGE_CLASS_SSNM_MESSAGE, "SS7 signalling network management messages" },
85 { MESSAGE_CLASS_ASPSM_MESSAGE, "ASP state maintenance messages" },
86 { MESSAGE_CLASS_ASPTM_MESSAGE, "ASP traffic maintenance messages" },
87 { MESSAGE_CLASS_CL_MESSAGE, "Connectionless messages" },
88 { MESSAGE_CLASS_CO_MESSAGE, "Connection-Oriented messages" },
89 { MESSAGE_CLASS_RKM_MESSAGE, "Routing key management Messages" },
90 { 0, NULL } };
92 #define MESSAGE_TYPE_ERR 0
93 #define MESSAGE_TYPE_NTFY 1
95 #define MESSAGE_TYPE_DUNA 1
96 #define MESSAGE_TYPE_DAVA 2
97 #define MESSAGE_TYPE_DAUD 3
98 #define MESSAGE_TYPE_SCON 4
99 #define MESSAGE_TYPE_DUPU 5
100 #define MESSAGE_TYPE_DRST 6
102 #define MESSAGE_TYPE_UP 1
103 #define MESSAGE_TYPE_DOWN 2
104 #define MESSAGE_TYPE_BEAT 3
105 #define MESSAGE_TYPE_UP_ACK 4
106 #define MESSAGE_TYPE_DOWN_ACK 5
107 #define MESSAGE_TYPE_BEAT_ACK 6
109 #define MESSAGE_TYPE_ACTIVE 1
110 #define MESSAGE_TYPE_INACTIVE 2
111 #define MESSAGE_TYPE_ACTIVE_ACK 3
112 #define MESSAGE_TYPE_INACTIVE_ACK 4
114 #define MESSAGE_TYPE_CLDT 1
115 #define MESSAGE_TYPE_CLDR 2
117 #define MESSAGE_TYPE_CORE 1
118 #define MESSAGE_TYPE_COAK 2
119 #define MESSAGE_TYPE_COREF 3
120 #define MESSAGE_TYPE_RELRE 4
121 #define MESSAGE_TYPE_RELCO 5
122 #define MESSAGE_TYPE_RESCO 6
123 #define MESSAGE_TYPE_RESRE 7
124 #define MESSAGE_TYPE_CODT 8
125 #define MESSAGE_TYPE_CODA 9
126 #define MESSAGE_TYPE_COERR 10
127 #define MESSAGE_TYPE_COIT 11
129 #define MESSAGE_TYPE_REG_REQ 1
130 #define MESSAGE_TYPE_REG_RSP 2
131 #define MESSAGE_TYPE_DEREG_REQ 3
132 #define MESSAGE_TYPE_DEREG_RSP 4
135 static const value_string message_class_type_values[] = {
136 { MESSAGE_CLASS_MGMT_MESSAGE * 256 + MESSAGE_TYPE_ERR, "Error (ERR)" },
137 { MESSAGE_CLASS_MGMT_MESSAGE * 256 + MESSAGE_TYPE_NTFY, "Notify (NTFY)" },
138 { MESSAGE_CLASS_SSNM_MESSAGE * 256 + MESSAGE_TYPE_DUNA, "Destination unavailable (DUNA)" },
139 { MESSAGE_CLASS_SSNM_MESSAGE * 256 + MESSAGE_TYPE_DAVA, "Destination available (DAVA)" },
140 { MESSAGE_CLASS_SSNM_MESSAGE * 256 + MESSAGE_TYPE_DAUD, "Destination state audit (DAUD)" },
141 { MESSAGE_CLASS_SSNM_MESSAGE * 256 + MESSAGE_TYPE_SCON, "SS7 Network congestion state (SCON)" },
142 { MESSAGE_CLASS_SSNM_MESSAGE * 256 + MESSAGE_TYPE_DUPU, "Destination userpart unavailable (DUPU)" },
143 { MESSAGE_CLASS_SSNM_MESSAGE * 256 + MESSAGE_TYPE_DRST, "Destination Restricted (DRST)" },
144 { MESSAGE_CLASS_ASPSM_MESSAGE * 256 + MESSAGE_TYPE_UP, "ASP up (UP)" },
145 { MESSAGE_CLASS_ASPSM_MESSAGE * 256 + MESSAGE_TYPE_DOWN, "ASP down (DOWN)" },
146 { MESSAGE_CLASS_ASPSM_MESSAGE * 256 + MESSAGE_TYPE_BEAT, "Heartbeat (BEAT)" },
147 { MESSAGE_CLASS_ASPSM_MESSAGE * 256 + MESSAGE_TYPE_UP_ACK, "ASP up ack (UP ACK)" },
148 { MESSAGE_CLASS_ASPSM_MESSAGE * 256 + MESSAGE_TYPE_DOWN_ACK, "ASP down ack (DOWN ACK)" },
149 { MESSAGE_CLASS_ASPSM_MESSAGE * 256 + MESSAGE_TYPE_BEAT_ACK, "Heartbeat ack (BEAT ACK)" },
150 { MESSAGE_CLASS_ASPTM_MESSAGE * 256 + MESSAGE_TYPE_ACTIVE , "ASP active (ACTIVE)" },
151 { MESSAGE_CLASS_ASPTM_MESSAGE * 256 + MESSAGE_TYPE_INACTIVE , "ASP inactive (INACTIVE)" },
152 { MESSAGE_CLASS_ASPTM_MESSAGE * 256 + MESSAGE_TYPE_ACTIVE_ACK , "ASP active ack (ACTIVE ACK)" },
153 { MESSAGE_CLASS_ASPTM_MESSAGE * 256 + MESSAGE_TYPE_INACTIVE_ACK , "ASP inactive ack (INACTIVE ACK)" },
154 { MESSAGE_CLASS_CL_MESSAGE * 256 + MESSAGE_TYPE_CLDR , "Connectionless Data Response (CLDR)" },
155 { MESSAGE_CLASS_CL_MESSAGE * 256 + MESSAGE_TYPE_CLDT , "Connectionless Data Transfer (CLDT)" },
156 { MESSAGE_CLASS_CO_MESSAGE * 256 + MESSAGE_TYPE_CORE , "Connection Request (CORE)" },
157 { MESSAGE_CLASS_CO_MESSAGE * 256 + MESSAGE_TYPE_COAK , "Connection Acknowledge (COAK)" },
158 { MESSAGE_CLASS_CO_MESSAGE * 256 + MESSAGE_TYPE_COREF , "Connection Refused (COREF)" },
159 { MESSAGE_CLASS_CO_MESSAGE * 256 + MESSAGE_TYPE_RELRE , "Release Request (RELRE)" },
160 { MESSAGE_CLASS_CO_MESSAGE * 256 + MESSAGE_TYPE_RELCO , "Release Complete (RELCO)" },
161 { MESSAGE_CLASS_CO_MESSAGE * 256 + MESSAGE_TYPE_RESCO , "Reset Confirm (RESCO)" },
162 { MESSAGE_CLASS_CO_MESSAGE * 256 + MESSAGE_TYPE_RESRE , "Reset Request (RESRE)" },
163 { MESSAGE_CLASS_CO_MESSAGE * 256 + MESSAGE_TYPE_CODT , "Connection Oriented Data Transfer (CODT)" },
164 { MESSAGE_CLASS_CO_MESSAGE * 256 + MESSAGE_TYPE_CODA , "Connection Oriented Data Acknowledge (CODA)" },
165 { MESSAGE_CLASS_CO_MESSAGE * 256 + MESSAGE_TYPE_COERR , "Connection Oriented Error (COERR)" },
166 { MESSAGE_CLASS_CO_MESSAGE * 256 + MESSAGE_TYPE_COIT , "Inactivity Test (COIT)" },
167 { MESSAGE_CLASS_RKM_MESSAGE * 256 + MESSAGE_TYPE_REG_REQ , "Registration Request (REG_REQ)" },
168 { MESSAGE_CLASS_RKM_MESSAGE * 256 + MESSAGE_TYPE_REG_RSP , "Registration Response (REG_RSP)" },
169 { MESSAGE_CLASS_RKM_MESSAGE * 256 + MESSAGE_TYPE_DEREG_REQ , "Deregistration Request (DEREG_REQ)" },
170 { MESSAGE_CLASS_RKM_MESSAGE * 256 + MESSAGE_TYPE_DEREG_RSP , "Deregistration Response (DEREG_RSP)" },
171 { 0, NULL } };
173 static const value_string message_class_type_acro_values[] = {
174 { MESSAGE_CLASS_MGMT_MESSAGE * 256 + MESSAGE_TYPE_ERR, "ERR" },
175 { MESSAGE_CLASS_MGMT_MESSAGE * 256 + MESSAGE_TYPE_NTFY, "NTFY" },
176 { MESSAGE_CLASS_SSNM_MESSAGE * 256 + MESSAGE_TYPE_DUNA, "DUNA" },
177 { MESSAGE_CLASS_SSNM_MESSAGE * 256 + MESSAGE_TYPE_DAVA, "DAVA" },
178 { MESSAGE_CLASS_SSNM_MESSAGE * 256 + MESSAGE_TYPE_DAUD, "DAUD" },
179 { MESSAGE_CLASS_SSNM_MESSAGE * 256 + MESSAGE_TYPE_SCON, "SCON" },
180 { MESSAGE_CLASS_SSNM_MESSAGE * 256 + MESSAGE_TYPE_DUPU, "DUPU" },
181 { MESSAGE_CLASS_SSNM_MESSAGE * 256 + MESSAGE_TYPE_DRST, "DRST" },
182 { MESSAGE_CLASS_ASPSM_MESSAGE * 256 + MESSAGE_TYPE_UP, "ASP_UP" },
183 { MESSAGE_CLASS_ASPSM_MESSAGE * 256 + MESSAGE_TYPE_DOWN, "ASP_DOWN" },
184 { MESSAGE_CLASS_ASPSM_MESSAGE * 256 + MESSAGE_TYPE_BEAT, "BEAT" },
185 { MESSAGE_CLASS_ASPSM_MESSAGE * 256 + MESSAGE_TYPE_UP_ACK, "ASP_UP_ACK" },
186 { MESSAGE_CLASS_ASPSM_MESSAGE * 256 + MESSAGE_TYPE_DOWN_ACK, "ASP_DOWN_ACK" },
187 { MESSAGE_CLASS_ASPSM_MESSAGE * 256 + MESSAGE_TYPE_BEAT_ACK, "BEAT_ACK" },
188 { MESSAGE_CLASS_ASPTM_MESSAGE * 256 + MESSAGE_TYPE_ACTIVE , "ASP_ACTIVE" },
189 { MESSAGE_CLASS_ASPTM_MESSAGE * 256 + MESSAGE_TYPE_INACTIVE , "ASP_INACTIVE" },
190 { MESSAGE_CLASS_ASPTM_MESSAGE * 256 + MESSAGE_TYPE_ACTIVE_ACK , "ASP_ACTIVE_ACK" },
191 { MESSAGE_CLASS_ASPTM_MESSAGE * 256 + MESSAGE_TYPE_INACTIVE_ACK , "ASP_INACTIVE_ACK" },
192 { MESSAGE_CLASS_CL_MESSAGE * 256 + MESSAGE_TYPE_CLDR , "CLDR" },
193 { MESSAGE_CLASS_CL_MESSAGE * 256 + MESSAGE_TYPE_CLDT , "CLDT" },
194 { MESSAGE_CLASS_CO_MESSAGE * 256 + MESSAGE_TYPE_CORE , "CORE" },
195 { MESSAGE_CLASS_CO_MESSAGE * 256 + MESSAGE_TYPE_COAK , "COAK" },
196 { MESSAGE_CLASS_CO_MESSAGE * 256 + MESSAGE_TYPE_COREF , "COREF" },
197 { MESSAGE_CLASS_CO_MESSAGE * 256 + MESSAGE_TYPE_RELRE , "RELRE" },
198 { MESSAGE_CLASS_CO_MESSAGE * 256 + MESSAGE_TYPE_RELCO , "RELCO" },
199 { MESSAGE_CLASS_CO_MESSAGE * 256 + MESSAGE_TYPE_RESCO , "RESCO" },
200 { MESSAGE_CLASS_CO_MESSAGE * 256 + MESSAGE_TYPE_RESRE , "RESRE" },
201 { MESSAGE_CLASS_CO_MESSAGE * 256 + MESSAGE_TYPE_CODT , "CODT" },
202 { MESSAGE_CLASS_CO_MESSAGE * 256 + MESSAGE_TYPE_CODA , "CODA" },
203 { MESSAGE_CLASS_CO_MESSAGE * 256 + MESSAGE_TYPE_COERR , "COERR" },
204 { MESSAGE_CLASS_CO_MESSAGE * 256 + MESSAGE_TYPE_COIT , "COIT" },
205 { MESSAGE_CLASS_RKM_MESSAGE * 256 + MESSAGE_TYPE_REG_REQ , "REG_REQ" },
206 { MESSAGE_CLASS_RKM_MESSAGE * 256 + MESSAGE_TYPE_REG_RSP , "REG_RSP" },
207 { MESSAGE_CLASS_RKM_MESSAGE * 256 + MESSAGE_TYPE_DEREG_REQ , "DEREG_REQ" },
208 { MESSAGE_CLASS_RKM_MESSAGE * 256 + MESSAGE_TYPE_DEREG_RSP , "DEREG_RSP" },
209 { 0, NULL } };
211 const value_string sua_co_class_type_acro_values[] = {
212 { MESSAGE_TYPE_CORE , "CORE" },
213 { MESSAGE_TYPE_COAK , "COAK" },
214 { MESSAGE_TYPE_COREF , "COREF" },
215 { MESSAGE_TYPE_RELRE , "RELRE" },
216 { MESSAGE_TYPE_RELCO , "RELCO" },
217 { MESSAGE_TYPE_RESCO , "RESCO" },
218 { MESSAGE_TYPE_RESRE , "RESRE" },
219 { MESSAGE_TYPE_CODT , "CODT" },
220 { MESSAGE_TYPE_CODA , "CODA" },
221 { MESSAGE_TYPE_COERR , "COERR" },
222 { MESSAGE_TYPE_COIT , "COIT" },
223 { 0, NULL }
226 /* Initialize the protocol and registered fields */
227 static int proto_sua;
228 static int hf_sua_version;
229 static int hf_sua_reserved;
230 static int hf_sua_message_class;
231 static int hf_sua_message_type;
232 static int hf_sua_message_length;
233 static int hf_sua_parameter_tag;
234 static int hf_sua_v8_parameter_tag;
235 static int hf_sua_parameter_length;
236 static int hf_sua_parameter_value;
237 static int hf_sua_parameter_padding;
238 static int hf_sua_info_string;
239 static int hf_sua_routing_context;
240 static int hf_sua_diagnostic_information_info;
241 static int hf_sua_heartbeat_data;
242 static int hf_sua_traffic_mode_type;
243 static int hf_sua_error_code;
244 static int hf_sua_v8_error_code;
245 static int hf_sua_status_type;
246 static int hf_sua_status_info;
247 static int hf_sua_congestion_level;
248 static int hf_sua_asp_identifier;
249 static int hf_sua_mask;
250 static int hf_sua_dpc;
251 static int hf_sua_registration_status;
252 static int hf_sua_deregistration_status;
253 static int hf_sua_local_routing_key_identifier;
255 static int hf_sua_source_address_routing_indicator;
256 static int hf_sua_source_address_reserved_bits;
257 static int hf_sua_source_address_gt_bit;
258 static int hf_sua_source_address_pc_bit;
259 static int hf_sua_source_address_ssn_bit;
260 static int hf_sua_source_gt_reserved;
261 static int hf_sua_source_gti;
262 static int hf_sua_source_number_of_digits;
263 static int hf_sua_source_translation_type;
264 static int hf_sua_source_numbering_plan;
265 static int hf_sua_source_nature_of_address;
266 static int hf_sua_source_global_title_digits;
267 static int hf_sua_source_point_code;
268 static int hf_sua_source_ssn_reserved;
269 static int hf_sua_source_ssn_number;
270 static int hf_sua_source_ipv4;
271 static int hf_sua_source_hostname;
272 static int hf_sua_source_ipv6;
274 static int hf_sua_destination_address_routing_indicator;
275 static int hf_sua_destination_address_reserved_bits;
276 static int hf_sua_destination_address_gt_bit;
277 static int hf_sua_destination_address_pc_bit;
278 static int hf_sua_destination_address_ssn_bit;
279 static int hf_sua_dest_gt_reserved;
280 static int hf_sua_dest_gti;
281 static int hf_sua_dest_number_of_digits;
282 static int hf_sua_dest_translation_type;
283 static int hf_sua_dest_numbering_plan;
284 static int hf_sua_dest_nature_of_address;
285 static int hf_sua_dest_global_title_digits;
286 static int hf_sua_dest_point_code;
287 static int hf_sua_dest_ssn_reserved;
288 static int hf_sua_dest_ssn_number;
289 static int hf_sua_dest_ipv4;
290 static int hf_sua_dest_hostname;
291 static int hf_sua_dest_ipv6;
293 static int hf_sua_ss7_hop_counter_counter;
294 static int hf_sua_ss7_hop_counter_reserved;
295 static int hf_sua_destination_reference_number;
296 static int hf_sua_source_reference_number;
297 static int hf_sua_cause_reserved;
298 static int hf_sua_cause_type;
299 static int hf_sua_cause_value;
300 static int hf_sua_sequence_number_reserved;
301 static int hf_sua_sequence_number_rec_number;
302 static int hf_sua_sequence_number_spare_bit;
303 static int hf_sua_sequence_number_sent_number;
304 static int hf_sua_sequence_number_more_data_bit;
305 static int hf_sua_receive_sequence_number_reserved;
306 static int hf_sua_receive_sequence_number_number;
307 static int hf_sua_receive_sequence_number_spare_bit;
308 static int hf_sua_protocol_classes;
309 static int hf_sua_protocol_class_flags;
310 static int hf_sua_asp_capabilities_reserved;
311 static int hf_sua_asp_capabilities_reserved_bits;
312 static int hf_sua_asp_capabilities_a_bit;
313 static int hf_sua_asp_capabilities_b_bit;
314 static int hf_sua_asp_capabilities_c_bit;
315 static int hf_sua_asp_capabilities_d_bit;
316 static int hf_sua_asp_capabilities_interworking;
317 static int hf_sua_credit;
318 static int hf_sua_data;
319 static int hf_sua_cause;
320 static int hf_sua_user;
321 static int hf_sua_network_appearance;
322 static int hf_sua_correlation_id;
323 static int hf_sua_importance_reserved;
324 static int hf_sua_importance;
325 static int hf_sua_message_priority_reserved;
326 static int hf_sua_message_priority;
327 static int hf_sua_protocol_class_reserved;
328 static int hf_sua_return_on_error_bit;
329 static int hf_sua_protocol_class;
330 static int hf_sua_sequence_control;
331 static int hf_sua_first_remaining;
332 static int hf_sua_first_bit;
333 static int hf_sua_number_of_remaining_segments;
334 static int hf_sua_segmentation_reference;
335 static int hf_sua_smi;
336 static int hf_sua_smi_reserved;
337 static int hf_sua_tid_label_start;
338 static int hf_sua_tid_label_end;
339 static int hf_sua_tid_label_value;
340 static int hf_sua_drn_label_start;
341 static int hf_sua_drn_label_end;
342 static int hf_sua_drn_label_value;
344 static int hf_sua_assoc_id;
346 /* Initialize the subtree pointers */
347 static int ett_sua;
348 static int ett_sua_parameter;
349 static int ett_sua_source_address_indicator;
350 static int ett_sua_destination_address_indicator;
351 static int ett_sua_affected_destination;
352 static int ett_sua_first_remaining;
353 static int ett_sua_sequence_number_rec_number;
354 static int ett_sua_sequence_number_sent_number;
355 static int ett_sua_receive_sequence_number_number;
356 static int ett_sua_return_on_error_bit_and_protocol_class;
357 static int ett_sua_protocol_classes;
358 static int ett_sua_assoc;
360 static int sua_tap;
362 static mtp3_addr_pc_t *sua_dpc;
363 static mtp3_addr_pc_t *sua_opc;
364 static uint16_t sua_ri;
365 static char *sua_source_gt;
366 static char *sua_destination_gt;
368 static dissector_handle_t sua_handle;
369 static dissector_handle_t sua_info_str_handle;
370 static dissector_table_t sua_parameter_table;
371 static dissector_table_t sccp_ssn_dissector_table;
372 static heur_dissector_list_t heur_subdissector_list;
374 static uint32_t message_class, message_type, drn, srn;
376 static int ss7pc_address_type = -1;
378 #define INVALID_SSN 0xff
379 static unsigned next_assoc_id = 1;
381 /* Based om association tracking in the SCCP dissector */
382 typedef struct _sua_assoc_info_t {
383 unsigned assoc_id;
384 uint32_t calling_routing_ind;
385 uint32_t called_routing_ind;
386 uint32_t calling_dpc;
387 uint32_t called_dpc;
388 uint8_t calling_ssn;
389 uint8_t called_ssn;
390 bool has_bw_key;
391 bool has_fw_key;
392 } sua_assoc_info_t;
394 static wmem_tree_t* assocs;
395 static sua_assoc_info_t* assoc;
396 static sua_assoc_info_t no_sua_assoc = {
397 0, /* assoc_id */
398 0, /* calling_routing_ind */
399 0, /* called_routing_ind */
400 0, /* calling_dpc */
401 0, /* called_dpc */
402 INVALID_SSN, /* calling_ssn */
403 INVALID_SSN, /* called_ssn */
404 false, /* has_bw_key */
405 false /* has_fw_key */
408 static sua_assoc_info_t *
409 new_assoc(uint32_t calling, uint32_t called)
411 sua_assoc_info_t *a = wmem_new0(wmem_file_scope(), sua_assoc_info_t);
413 a->assoc_id = next_assoc_id++;
414 a->calling_routing_ind = 0;
415 a->called_routing_ind = 0;
416 a->calling_dpc = calling;
417 a->called_dpc = called;
418 a->calling_ssn = INVALID_SSN;
419 a->called_ssn = INVALID_SSN;
421 return a;
424 static sua_assoc_info_t*
425 sua_assoc(packet_info* pinfo, address* opc, address* dpc, unsigned src_rn, unsigned dst_rn)
427 uint32_t opck, dpck;
429 if (!src_rn && !dst_rn) {
430 return &no_sua_assoc;
433 opck = opc->type == ss7pc_address_type ? mtp3_pc_hash((const mtp3_addr_pc_t *)opc->data) : g_str_hash(address_to_str(pinfo->pool, opc));
434 dpck = dpc->type == ss7pc_address_type ? mtp3_pc_hash((const mtp3_addr_pc_t *)dpc->data) : g_str_hash(address_to_str(pinfo->pool, dpc));
436 switch (message_type) {
437 case MESSAGE_TYPE_CORE:
439 /* Calling and called is seen from initiator of CORE */
440 wmem_tree_key_t bw_key[4];
442 bw_key[0].length = 1;
443 bw_key[0].key = &dpck;
445 bw_key[1].length = 1;
446 bw_key[1].key = &opck;
448 bw_key[2].length = 1;
449 bw_key[2].key = &src_rn;
451 bw_key[3].length = 0;
452 bw_key[3].key = NULL;
455 if ( !(assoc = (sua_assoc_info_t *)wmem_tree_lookup32_array(assocs,bw_key)) && ! pinfo->fd->visited) {
456 assoc = new_assoc(opck, dpck);
457 wmem_tree_insert32_array(assocs,bw_key,assoc);
458 assoc->has_bw_key = true;
459 /*ws_warning("CORE dpck %u,opck %u,src_rn %u",dpck,opck,src_rn);*/
461 break;
465 case MESSAGE_TYPE_COAK:
467 wmem_tree_key_t fw_key[4];
468 wmem_tree_key_t bw_key[4];
470 fw_key[0].length = 1;
471 fw_key[0].key = &dpck;
473 fw_key[1].length = 1;
474 fw_key[1].key = &opck;
476 fw_key[2].length = 1;
477 fw_key[2].key = &src_rn;
479 fw_key[3].length = 0;
480 fw_key[3].key = NULL;
483 bw_key[0].length = 1;
484 bw_key[0].key = &opck;
486 bw_key[1].length = 1;
487 bw_key[1].key = &dpck;
489 bw_key[2].length = 1;
490 bw_key[2].key = &dst_rn;
492 bw_key[3].length = 0;
493 bw_key[3].key = NULL;
494 /*ws_warning("MESSAGE_TYPE_COAK dst_rn %u,src_rn %u ",dst_rn,src_rn);*/
495 if ( ( assoc = (sua_assoc_info_t *)wmem_tree_lookup32_array(assocs, bw_key) ) ) {
496 goto got_assoc;
498 if ( (assoc = (sua_assoc_info_t *)wmem_tree_lookup32_array(assocs, fw_key) ) ) {
499 goto got_assoc;
502 assoc = new_assoc(dpck,opck);
504 got_assoc:
506 pinfo->p2p_dir = P2P_DIR_RECV;
508 if ( ! pinfo->fd->visited && ! assoc->has_bw_key ) {
509 wmem_tree_insert32_array(assocs, bw_key, assoc);
510 assoc->has_bw_key = true;
513 if ( ! pinfo->fd->visited && ! assoc->has_fw_key ) {
514 wmem_tree_insert32_array(assocs, fw_key, assoc);
515 assoc->has_fw_key = true;
518 break;
521 default:
523 wmem_tree_key_t key[4];
525 key[0].length = 1;
526 key[0].key = &opck;
528 key[1].length = 1;
529 key[1].key = &dpck;
531 key[2].length = 1;
532 key[2].key = &dst_rn;
534 key[3].length = 0;
535 key[3].key = NULL;
537 assoc = (sua_assoc_info_t *)wmem_tree_lookup32_array(assocs,key);
538 /* Should a check be made on pinfo->p2p_dir ??? */
539 break;
543 return assoc ? assoc : &no_sua_assoc;
546 /* stuff for supporting multiple versions */
547 typedef enum {
548 SUA_V08,
549 SUA_RFC
550 } Version_Type;
552 static int version = SUA_RFC;
553 static bool set_addresses;
555 static void
556 dissect_parameters(tvbuff_t *tlv_tvb, packet_info *pinfo, proto_tree *tree, tvbuff_t **data_tvb, uint8_t *source_ssn, uint8_t *dest_ssn);
558 static void
559 dissect_common_header(tvbuff_t *common_header_tvb, packet_info *pinfo, proto_tree *sua_tree)
562 message_class = tvb_get_uint8(common_header_tvb, MESSAGE_CLASS_OFFSET);
563 message_type = tvb_get_uint8(common_header_tvb, MESSAGE_TYPE_OFFSET);
565 col_add_fstr(pinfo->cinfo, COL_INFO, "%s ", val_to_str_const(message_class * 256 + message_type, message_class_type_acro_values, "reserved"));
567 if (sua_tree) {
568 /* add the components of the common header to the protocol tree */
569 proto_tree_add_item(sua_tree, hf_sua_version, common_header_tvb, VERSION_OFFSET, VERSION_LENGTH, ENC_BIG_ENDIAN);
570 proto_tree_add_item(sua_tree, hf_sua_reserved, common_header_tvb, RESERVED_OFFSET, RESERVED_LENGTH, ENC_NA);
571 proto_tree_add_item(sua_tree, hf_sua_message_class, common_header_tvb, MESSAGE_CLASS_OFFSET, MESSAGE_CLASS_LENGTH, ENC_BIG_ENDIAN);
572 proto_tree_add_uint_format_value(sua_tree, hf_sua_message_type, common_header_tvb, MESSAGE_TYPE_OFFSET, MESSAGE_TYPE_LENGTH, message_type, "%s (%u)",
573 val_to_str_const(message_class * 256 + message_type, message_class_type_values, "reserved"), message_type);
574 proto_tree_add_item(sua_tree, hf_sua_message_length, common_header_tvb, MESSAGE_LENGTH_OFFSET, MESSAGE_LENGTH_LENGTH, ENC_BIG_ENDIAN);
578 #define INFO_STRING_OFFSET PARAMETER_VALUE_OFFSET
580 static void
581 dissect_info_string_parameter(tvbuff_t *parameter_tvb, packet_info *pinfo, proto_tree *parameter_tree, proto_item *parameter_item)
583 uint16_t info_string_length;
584 tvbuff_t *next_tvb;
587 info_string_length = tvb_get_ntohs(parameter_tvb, PARAMETER_LENGTH_OFFSET) - PARAMETER_HEADER_LENGTH;
588 /* If we have a SUA Info String sub dissector call it */
589 if(sua_info_str_handle) {
590 next_tvb = tvb_new_subset_length(parameter_tvb, INFO_STRING_OFFSET, info_string_length);
591 call_dissector(sua_info_str_handle, next_tvb, pinfo, parameter_tree);
592 return;
595 proto_tree_add_item(parameter_tree, hf_sua_info_string, parameter_tvb, INFO_STRING_OFFSET, info_string_length, ENC_UTF_8);
596 proto_item_append_text(parameter_item, " (%s)",
597 tvb_format_text(pinfo->pool, parameter_tvb, INFO_STRING_OFFSET, info_string_length));
600 #define ROUTING_CONTEXT_LENGTH 4
602 static void
603 dissect_routing_context_parameter(tvbuff_t *parameter_tvb, proto_tree *parameter_tree, proto_item *parameter_item)
605 uint16_t number_of_contexts, context_number;
606 int context_offset;
608 number_of_contexts = (tvb_get_ntohs(parameter_tvb, PARAMETER_LENGTH_OFFSET) - PARAMETER_HEADER_LENGTH) / 4;
609 context_offset = PARAMETER_VALUE_OFFSET;
610 for(context_number=0; context_number < number_of_contexts; context_number++) {
611 proto_tree_add_item(parameter_tree, hf_sua_routing_context, parameter_tvb, context_offset, ROUTING_CONTEXT_LENGTH, ENC_BIG_ENDIAN);
612 context_offset += ROUTING_CONTEXT_LENGTH;
614 proto_item_append_text(parameter_item, " (%u context%s)", number_of_contexts, plurality(number_of_contexts, "", "s"));
617 #define DIAGNOSTIC_INFO_OFFSET PARAMETER_VALUE_OFFSET
619 static void
620 dissect_diagnostic_information_parameter(tvbuff_t *parameter_tvb, proto_tree *parameter_tree, proto_item *parameter_item)
622 uint16_t diag_info_length;
624 diag_info_length = tvb_get_ntohs(parameter_tvb, PARAMETER_LENGTH_OFFSET) - PARAMETER_HEADER_LENGTH;
625 proto_tree_add_item(parameter_tree, hf_sua_diagnostic_information_info, parameter_tvb, DIAGNOSTIC_INFO_OFFSET, diag_info_length, ENC_NA);
626 proto_item_append_text(parameter_item, " (%u byte%s)", diag_info_length, plurality(diag_info_length, "", "s"));
629 #define HEARTBEAT_DATA_OFFSET PARAMETER_VALUE_OFFSET
631 static void
632 dissect_heartbeat_data_parameter(tvbuff_t *parameter_tvb, proto_tree *parameter_tree, proto_item *parameter_item)
634 uint16_t heartbeat_data_length;
636 heartbeat_data_length = tvb_get_ntohs(parameter_tvb, PARAMETER_LENGTH_OFFSET) - PARAMETER_HEADER_LENGTH;
637 proto_tree_add_item(parameter_tree, hf_sua_heartbeat_data, parameter_tvb, HEARTBEAT_DATA_OFFSET, heartbeat_data_length, ENC_NA);
638 proto_item_append_text(parameter_item, " (%u byte%s)", heartbeat_data_length, plurality(heartbeat_data_length, "", "s"));
641 #define TRAFFIC_MODE_TYPE_OFFSET PARAMETER_VALUE_OFFSET
642 #define TRAFFIC_MODE_TYPE_LENGTH 4
644 static const value_string traffic_mode_type_values[] = {
645 { 1, "Over-ride" },
646 { 2, "Load-share" },
647 { 3, "Broadcast" },
648 { 0, NULL } };
650 static void
651 dissect_traffic_mode_type_parameter(tvbuff_t *parameter_tvb, proto_tree *parameter_tree, proto_item *parameter_item)
653 proto_tree_add_item(parameter_tree, hf_sua_traffic_mode_type, parameter_tvb, TRAFFIC_MODE_TYPE_OFFSET, TRAFFIC_MODE_TYPE_LENGTH, ENC_BIG_ENDIAN);
654 proto_item_append_text(parameter_item, " (%s)", val_to_str_const(tvb_get_ntohl(parameter_tvb, TRAFFIC_MODE_TYPE_OFFSET), traffic_mode_type_values, "unknown"));
657 #define ERROR_CODE_OFFSET PARAMETER_VALUE_OFFSET
658 #define ERROR_CODE_LENGTH 4
660 static const value_string v8_error_code_values[] = {
661 { 0x01, "Invalid version" },
662 { 0x02, "Invalid interface identifier" },
663 { 0x03, "Unsupported message class" },
664 { 0x04, "Unsupported message type" },
665 { 0x05, "Unsupported traffic handling mode" },
666 { 0x06, "Unexpected message" },
667 { 0x07, "Protocol error" },
668 { 0x09, "Invalid stream identifier" },
669 { 0x0d, "Refused - management blocking" },
670 { 0x0e, "ASP identifier required" },
671 { 0x0f, "Invalid ASP identifier" },
672 { 0x11, "Invalid parameter value" },
673 { 0x12, "Parameter field error" },
674 { 0x13, "Unexpected parameter" },
675 { 0x14, "Destination status unknown" },
676 { 0x15, "Invalid network appearance" },
677 { 0x16, "Missing parameter" },
678 { 0x17, "Routing key change refused" },
679 { 0x18, "Invalid loadsharing label" },
680 { 0, NULL } };
682 static void
683 dissect_v8_error_code_parameter(tvbuff_t *parameter_tvb, proto_tree *parameter_tree, proto_item *parameter_item)
685 proto_tree_add_item(parameter_tree, hf_sua_v8_error_code, parameter_tvb, ERROR_CODE_OFFSET, ERROR_CODE_LENGTH, ENC_BIG_ENDIAN);
686 proto_item_append_text(parameter_item, " (%s)", val_to_str_const(tvb_get_ntohl(parameter_tvb, ERROR_CODE_OFFSET), v8_error_code_values, "unknown"));
689 static const value_string error_code_values[] = {
690 { 0x01, "Invalid version" },
691 { 0x03, "Unsupported message class" },
692 { 0x04, "Unsupported message type" },
693 { 0x05, "Unsupported traffic handling mode" },
694 { 0x06, "Unexpected message" },
695 { 0x07, "Protocol error" },
696 { 0x09, "Invalid stream identifier" },
697 { 0x0d, "Refused - management blocking" },
698 { 0x0e, "ASP identifier required" },
699 { 0x0f, "Invalid ASP identifier" },
700 { 0x11, "Invalid parameter value" },
701 { 0x12, "Parameter field error" },
702 { 0x13, "Unexpected parameter" },
703 { 0x14, "Destination status unknown" },
704 { 0x15, "Invalid network appearance" },
705 { 0x16, "Missing parameter" },
706 { 0x19, "Invalid routing context" },
707 { 0x1a, "No configured AS for ASP" },
708 { 0x1b, "Subsystem status unknown" },
709 { 0x1c, "Invalid loadsharing label" },
710 { 0, NULL } };
712 static void
713 dissect_error_code_parameter(tvbuff_t *parameter_tvb, proto_tree *parameter_tree, proto_item *parameter_item)
715 proto_tree_add_item(parameter_tree, hf_sua_error_code, parameter_tvb, ERROR_CODE_OFFSET, ERROR_CODE_LENGTH, ENC_BIG_ENDIAN);
716 proto_item_append_text(parameter_item, " (%s)", val_to_str_const(tvb_get_ntohl(parameter_tvb, ERROR_CODE_OFFSET), error_code_values, "unknown"));
719 #define STATUS_TYPE_LENGTH 2
720 #define STATUS_INFO_LENGTH 2
721 #define STATUS_TYPE_OFFSET PARAMETER_VALUE_OFFSET
722 #define STATUS_INFO_OFFSET (STATUS_TYPE_OFFSET + STATUS_TYPE_LENGTH)
724 #define AS_STATE_CHANGE_TYPE 1
725 #define OTHER_TYPE 2
727 static const value_string status_type_values[] = {
728 { AS_STATE_CHANGE_TYPE, "Application server state change" },
729 { OTHER_TYPE, "Other" },
730 { 0, NULL } };
732 #define RESERVED_INFO 1
733 #define AS_INACTIVE_INFO 2
734 #define AS_ACTIVE_INFO 3
735 #define AS_PENDING_INFO 4
737 #define INSUFFICIENT_ASP_RES_INFO 1
738 #define ALTERNATE_ASP_ACTIVE_INFO 2
739 #define ASP_FAILURE 3
741 static const value_string status_type_info_values[] = {
742 { AS_STATE_CHANGE_TYPE * 256 * 256 + RESERVED_INFO, "Reserved" },
743 { AS_STATE_CHANGE_TYPE * 256 * 256 + AS_INACTIVE_INFO, "Application server inactive" },
744 { AS_STATE_CHANGE_TYPE * 256 * 256 + AS_ACTIVE_INFO, "Application server active" },
745 { AS_STATE_CHANGE_TYPE * 256 * 256 + AS_PENDING_INFO, "Application server pending" },
746 { OTHER_TYPE * 256 * 256 + INSUFFICIENT_ASP_RES_INFO, "Insufficient ASP resources active in AS" },
747 { OTHER_TYPE * 256 * 256 + ALTERNATE_ASP_ACTIVE_INFO, "Alternate ASP active" },
748 { OTHER_TYPE * 256 * 256 + ASP_FAILURE, "ASP Failure" },
749 {0, NULL } };
751 static void
752 dissect_status_type_parameter(tvbuff_t *parameter_tvb, proto_tree *parameter_tree, proto_item *parameter_item)
754 uint16_t status_type, status_info;
756 status_type = tvb_get_ntohs(parameter_tvb, STATUS_TYPE_OFFSET);
757 status_info = tvb_get_ntohs(parameter_tvb, STATUS_INFO_OFFSET);
759 proto_tree_add_item(parameter_tree, hf_sua_status_type, parameter_tvb, STATUS_TYPE_OFFSET, STATUS_TYPE_LENGTH, ENC_BIG_ENDIAN);
760 proto_tree_add_uint_format_value(parameter_tree, hf_sua_status_info, parameter_tvb, STATUS_INFO_OFFSET, STATUS_INFO_LENGTH,
761 status_info, "%s (%u)", val_to_str_const(status_type * 256 * 256 + status_info, status_type_info_values, "unknown"), status_info);
763 proto_item_append_text(parameter_item, " (%s)", val_to_str_const(status_type * 256 * 256 + status_info, status_type_info_values, "unknown"));
766 #define ASP_IDENTIFIER_LENGTH 4
767 #define ASP_IDENTIFIER_OFFSET PARAMETER_VALUE_OFFSET
769 static void
770 dissect_asp_identifier_parameter(tvbuff_t *parameter_tvb, proto_tree *parameter_tree, proto_item *parameter_item)
772 proto_tree_add_item(parameter_tree, hf_sua_asp_identifier, parameter_tvb, ASP_IDENTIFIER_OFFSET, ASP_IDENTIFIER_LENGTH, ENC_BIG_ENDIAN);
773 proto_item_append_text(parameter_item, " (%u)", tvb_get_ntohl(parameter_tvb, ASP_IDENTIFIER_OFFSET));
776 #define AFFECTED_MASK_LENGTH 1
777 #define AFFECTED_DPC_LENGTH 3
778 #define AFFECTED_DESTINATION_LENGTH (AFFECTED_MASK_LENGTH + AFFECTED_DPC_LENGTH)
780 #define AFFECTED_MASK_OFFSET 0
781 #define AFFECTED_DPC_OFFSET 1
783 static void
784 dissect_affected_destinations_parameter(tvbuff_t *parameter_tvb, proto_tree *parameter_tree, proto_item *parameter_item)
786 uint16_t number_of_destinations, destination_number;
787 int destination_offset;
788 proto_item *dpc_item;
790 number_of_destinations= (tvb_get_ntohs(parameter_tvb, PARAMETER_LENGTH_OFFSET) - PARAMETER_HEADER_LENGTH) / 4;
791 destination_offset = PARAMETER_VALUE_OFFSET;
792 for(destination_number=0; destination_number < number_of_destinations; destination_number++) {
793 proto_tree_add_item(parameter_tree, hf_sua_mask, parameter_tvb, destination_offset + AFFECTED_MASK_OFFSET, AFFECTED_MASK_LENGTH, ENC_BIG_ENDIAN);
794 dpc_item = proto_tree_add_item(parameter_tree, hf_sua_dpc, parameter_tvb, destination_offset + AFFECTED_DPC_OFFSET, AFFECTED_DPC_LENGTH, ENC_BIG_ENDIAN);
795 if (mtp3_pc_structured())
796 proto_item_append_text(dpc_item, " (%s)", mtp3_pc_to_str(tvb_get_ntoh24(parameter_tvb, destination_offset + AFFECTED_DPC_OFFSET)));
797 destination_offset += AFFECTED_DESTINATION_LENGTH;
799 proto_item_append_text(parameter_item, " (%u destination%s)", number_of_destinations, plurality(number_of_destinations, "", "s"));
802 #define CORRELATION_ID_LENGTH 4
803 #define CORRELATION_ID_OFFSET PARAMETER_VALUE_OFFSET
805 static void
806 dissect_correlation_id_parameter(tvbuff_t *parameter_tvb, proto_tree *parameter_tree, proto_item *parameter_item)
808 proto_tree_add_item(parameter_tree, hf_sua_correlation_id, parameter_tvb, CORRELATION_ID_OFFSET, CORRELATION_ID_LENGTH, ENC_BIG_ENDIAN);
809 proto_item_append_text(parameter_item, " (%u)", tvb_get_ntohl(parameter_tvb, CORRELATION_ID_OFFSET));
812 static void
813 // NOLINTNEXTLINE(misc-no-recursion)
814 dissect_registration_result_parameter(tvbuff_t *parameter_tvb, packet_info *pinfo, proto_tree *parameter_tree)
816 tvbuff_t *parameters_tvb;
818 parameters_tvb = tvb_new_subset_remaining(parameter_tvb, PARAMETER_VALUE_OFFSET);
819 dissect_parameters(parameters_tvb, pinfo, parameter_tree, NULL, NULL, NULL);
822 static void
823 // NOLINTNEXTLINE(misc-no-recursion)
824 dissect_deregistration_result_parameter(tvbuff_t *parameter_tvb, packet_info *pinfo, proto_tree *parameter_tree)
826 tvbuff_t *parameters_tvb;
828 parameters_tvb = tvb_new_subset_remaining(parameter_tvb, PARAMETER_VALUE_OFFSET);
829 dissect_parameters(parameters_tvb, pinfo, parameter_tree, NULL, NULL, NULL);
832 #define REGISTRATION_STATUS_LENGTH 4
833 #define REGISTRATION_STATUS_OFFSET PARAMETER_VALUE_OFFSET
835 static const value_string registration_status_values[] = {
836 { 0, "Successfully registered" },
837 { 1, "Error - unknown" },
838 { 2, "Error - invalid destination address" },
839 { 3, "Error - invalid network appearance" },
840 { 4, "Error - invalid routing key" },
841 { 5, "Error - permission denied" },
842 { 6, "Error - cannot support unique routing" },
843 { 7, "Error - routing key not currently provisioned" },
844 { 8, "Error - insufficient resources" },
845 { 9, "Error - unsupported RK parameter field" },
846 { 10, "Error - unsupported/invalid traffic mode type" },
847 { 11, "Error - routing key change refused" },
848 { 0, NULL } };
850 static void
851 dissect_registration_status_parameter(tvbuff_t *parameter_tvb, proto_tree *parameter_tree, proto_item *parameter_item)
853 proto_tree_add_item(parameter_tree, hf_sua_registration_status, parameter_tvb, REGISTRATION_STATUS_OFFSET, REGISTRATION_STATUS_LENGTH, ENC_BIG_ENDIAN);
854 proto_item_append_text(parameter_item, " (%s)", val_to_str_const(tvb_get_ntohl(parameter_tvb, REGISTRATION_STATUS_OFFSET), registration_status_values, "unknown"));
857 #define DEREGISTRATION_STATUS_LENGTH 4
858 #define DEREGISTRATION_STATUS_OFFSET PARAMETER_VALUE_OFFSET
860 static const value_string deregistration_status_values[] = {
861 { 0, "Successfully deregistered" },
862 { 1, "Error - unknown" },
863 { 2, "Error - invalid routing context" },
864 { 3, "Error - permission denied" },
865 { 4, "Error - not registered" },
866 { 5, "Error - ASP currently active for routing context" },
867 { 0, NULL } };
869 static void
870 dissect_deregistration_status_parameter(tvbuff_t *parameter_tvb, proto_tree *parameter_tree, proto_item *parameter_item)
872 proto_tree_add_item(parameter_tree, hf_sua_deregistration_status, parameter_tvb, DEREGISTRATION_STATUS_OFFSET, DEREGISTRATION_STATUS_LENGTH, ENC_BIG_ENDIAN);
873 proto_item_append_text(parameter_item, " (%s)", val_to_str_const(tvb_get_ntohl(parameter_tvb, DEREGISTRATION_STATUS_OFFSET), deregistration_status_values, "unknown"));
876 #define LOCAL_ROUTING_KEY_IDENTIFIER_LENGTH 4
877 #define LOCAL_ROUTING_KEY_IDENTIFIER_OFFSET PARAMETER_VALUE_OFFSET
879 static void
880 dissect_local_routing_key_identifier_parameter(tvbuff_t *parameter_tvb, proto_tree *parameter_tree, proto_item *parameter_item)
882 proto_tree_add_item(parameter_tree, hf_sua_local_routing_key_identifier, parameter_tvb, LOCAL_ROUTING_KEY_IDENTIFIER_OFFSET, LOCAL_ROUTING_KEY_IDENTIFIER_LENGTH, ENC_BIG_ENDIAN);
883 proto_item_append_text(parameter_item, " (%d)", tvb_get_ntohl(parameter_tvb, LOCAL_ROUTING_KEY_IDENTIFIER_OFFSET));
886 #define SS7_HOP_COUNTER_LENGTH 1
887 #define SS7_HOP_COUNTER_OFFSET (PARAMETER_VALUE_OFFSET + RESERVED_3_LENGTH)
889 static void
890 dissect_ss7_hop_counter_parameter(tvbuff_t *parameter_tvb, proto_tree *parameter_tree, proto_item *parameter_item)
892 proto_tree_add_item(parameter_tree, hf_sua_ss7_hop_counter_reserved, parameter_tvb, PARAMETER_VALUE_OFFSET, RESERVED_3_LENGTH, ENC_NA);
893 proto_tree_add_item(parameter_tree, hf_sua_ss7_hop_counter_counter, parameter_tvb, SS7_HOP_COUNTER_OFFSET, SS7_HOP_COUNTER_LENGTH, ENC_BIG_ENDIAN);
894 proto_item_append_text(parameter_item, " (%u)", tvb_get_uint8(parameter_tvb, SS7_HOP_COUNTER_OFFSET));
897 #define ROUTING_INDICATOR_LENGTH 2
898 #define ADDRESS_INDICATOR_LENGTH 2
900 #define ROUTING_INDICATOR_OFFSET PARAMETER_VALUE_OFFSET
901 #define ADDRESS_INDICATOR_OFFSET (ROUTING_INDICATOR_OFFSET + ROUTING_INDICATOR_LENGTH)
902 #define ADDRESS_PARAMETERS_OFFSET (ADDRESS_INDICATOR_OFFSET + ADDRESS_INDICATOR_LENGTH)
904 #define RESERVED_ROUTING_INDICATOR 0
905 #define ROUTE_ON_GT_ROUTING_INDICATOR 1
906 #define ROUTE_ON_SSN_PC_ROUTING_INDICATOR 2
907 #define ROUTE_ON_HOSTNAMEROUTING_INDICATOR 3
908 #define ROUTE_ON_SSN_IP_ROUTING_INDICATOR 4
910 static const value_string routing_indicator_values[] = {
911 { RESERVED_ROUTING_INDICATOR, "Reserved" },
912 { ROUTE_ON_GT_ROUTING_INDICATOR, "Route on Global Title" },
913 { ROUTE_ON_SSN_PC_ROUTING_INDICATOR, "Route on SSN + PC" },
914 { ROUTE_ON_HOSTNAMEROUTING_INDICATOR, "Route on Hostname" },
915 { ROUTE_ON_SSN_IP_ROUTING_INDICATOR, "Route on SSN + IP Address" },
916 { 0, NULL } };
918 #define ADDRESS_RESERVED_BITMASK 0xfff8
919 #define ADDRESS_GT_BITMASK 0x0004
920 #define ADDRESS_PC_BITMASK 0x0002
921 #define ADDRESS_SSN_BITMASK 0x0001
923 static void
924 // NOLINTNEXTLINE(misc-no-recursion)
925 dissect_source_address_parameter(tvbuff_t *parameter_tvb, packet_info *pinfo, proto_tree *parameter_tree, uint8_t *ssn)
927 proto_tree *address_indicator_tree;
928 tvbuff_t *parameters_tvb;
930 sua_ri = tvb_get_ntohs(parameter_tvb, ROUTING_INDICATOR_OFFSET);
932 if(parameter_tree) {
933 proto_tree_add_item(parameter_tree, hf_sua_source_address_routing_indicator, parameter_tvb, ROUTING_INDICATOR_OFFSET, ROUTING_INDICATOR_LENGTH, ENC_BIG_ENDIAN);
934 address_indicator_tree = proto_tree_add_subtree(parameter_tree, parameter_tvb, ADDRESS_INDICATOR_OFFSET, ADDRESS_INDICATOR_LENGTH, ett_sua_source_address_indicator, NULL, "Address Indicator");
935 proto_tree_add_item(address_indicator_tree, hf_sua_source_address_reserved_bits, parameter_tvb, ADDRESS_INDICATOR_OFFSET, ADDRESS_INDICATOR_LENGTH, ENC_BIG_ENDIAN);
936 proto_tree_add_item(address_indicator_tree, hf_sua_source_address_gt_bit, parameter_tvb, ADDRESS_INDICATOR_OFFSET, ADDRESS_INDICATOR_LENGTH, ENC_BIG_ENDIAN);
937 proto_tree_add_item(address_indicator_tree, hf_sua_source_address_pc_bit, parameter_tvb, ADDRESS_INDICATOR_OFFSET, ADDRESS_INDICATOR_LENGTH, ENC_BIG_ENDIAN);
938 proto_tree_add_item(address_indicator_tree, hf_sua_source_address_ssn_bit, parameter_tvb, ADDRESS_INDICATOR_OFFSET, ADDRESS_INDICATOR_LENGTH, ENC_BIG_ENDIAN);
941 parameters_tvb = tvb_new_subset_remaining(parameter_tvb, ADDRESS_PARAMETERS_OFFSET);
942 dissect_parameters(parameters_tvb, pinfo, parameter_tree, NULL, ssn, NULL);
945 static void
946 // NOLINTNEXTLINE(misc-no-recursion)
947 dissect_destination_address_parameter(tvbuff_t *parameter_tvb, packet_info *pinfo, proto_tree *parameter_tree, uint8_t *ssn)
949 proto_tree *address_indicator_tree;
950 tvbuff_t *parameters_tvb;
952 sua_ri = tvb_get_ntohs(parameter_tvb, ROUTING_INDICATOR_OFFSET);
954 if(parameter_tree) {
955 proto_tree_add_item(parameter_tree, hf_sua_destination_address_routing_indicator, parameter_tvb, ROUTING_INDICATOR_OFFSET, ROUTING_INDICATOR_LENGTH, ENC_BIG_ENDIAN);
956 address_indicator_tree = proto_tree_add_subtree(parameter_tree, parameter_tvb, ADDRESS_INDICATOR_OFFSET, ADDRESS_INDICATOR_LENGTH, ett_sua_destination_address_indicator, NULL, "Address Indicator");
957 proto_tree_add_item(address_indicator_tree, hf_sua_destination_address_reserved_bits, parameter_tvb, ADDRESS_INDICATOR_OFFSET, ADDRESS_INDICATOR_LENGTH, ENC_BIG_ENDIAN);
958 proto_tree_add_item(address_indicator_tree, hf_sua_destination_address_gt_bit, parameter_tvb, ADDRESS_INDICATOR_OFFSET, ADDRESS_INDICATOR_LENGTH, ENC_BIG_ENDIAN);
959 proto_tree_add_item(address_indicator_tree, hf_sua_destination_address_pc_bit, parameter_tvb, ADDRESS_INDICATOR_OFFSET, ADDRESS_INDICATOR_LENGTH, ENC_BIG_ENDIAN);
960 proto_tree_add_item(address_indicator_tree, hf_sua_destination_address_ssn_bit, parameter_tvb, ADDRESS_INDICATOR_OFFSET, ADDRESS_INDICATOR_LENGTH, ENC_BIG_ENDIAN);
963 parameters_tvb = tvb_new_subset_remaining(parameter_tvb, ADDRESS_PARAMETERS_OFFSET);
964 dissect_parameters(parameters_tvb, pinfo, parameter_tree, NULL, NULL, ssn);
967 #define SOURCE_REFERENCE_NUMBER_LENGTH 4
968 #define SOURCE_REFERENCE_NUMBER_OFFSET PARAMETER_VALUE_OFFSET
970 static void
971 dissect_source_reference_number_parameter(tvbuff_t *parameter_tvb, proto_tree *parameter_tree, proto_item *parameter_item)
973 srn = tvb_get_ntohl(parameter_tvb, SOURCE_REFERENCE_NUMBER_OFFSET);
974 proto_tree_add_item(parameter_tree, hf_sua_source_reference_number, parameter_tvb, SOURCE_REFERENCE_NUMBER_OFFSET, SOURCE_REFERENCE_NUMBER_LENGTH, ENC_BIG_ENDIAN);
975 proto_item_append_text(parameter_item, " (%u)", tvb_get_ntohl(parameter_tvb, SOURCE_REFERENCE_NUMBER_OFFSET));
978 #define DESTINATION_REFERENCE_NUMBER_LENGTH 4
979 #define DESTINATION_REFERENCE_NUMBER_OFFSET PARAMETER_VALUE_OFFSET
981 static void
982 dissect_destination_reference_number_parameter(tvbuff_t *parameter_tvb, proto_tree *parameter_tree, proto_item *parameter_item)
984 drn = tvb_get_ntohl(parameter_tvb, DESTINATION_REFERENCE_NUMBER_OFFSET);
985 proto_tree_add_item(parameter_tree, hf_sua_destination_reference_number, parameter_tvb, DESTINATION_REFERENCE_NUMBER_OFFSET, DESTINATION_REFERENCE_NUMBER_LENGTH, ENC_BIG_ENDIAN);
986 proto_item_append_text(parameter_item, " (%u)", tvb_get_ntohl(parameter_tvb, DESTINATION_REFERENCE_NUMBER_OFFSET));
989 #define CAUSE_TYPE_LENGTH 1
990 #define CAUSE_VALUE_LENGTH 1
992 #define CAUSE_TYPE_OFFSET (PARAMETER_VALUE_OFFSET + RESERVED_2_LENGTH)
993 #define CAUSE_VALUE_OFFSET (CAUSE_TYPE_OFFSET + CAUSE_TYPE_LENGTH)
995 #define CAUSE_TYPE_RETURN 0x1
996 #define CAUSE_TYPE_REFUSAL 0x2
997 #define CAUSE_TYPE_RELEASE 0x3
998 #define CAUSE_TYPE_RESET 0x4
999 #define CAUSE_TYPE_ERROR 0x5
1000 static const value_string cause_type_values[] = {
1001 { CAUSE_TYPE_RETURN, "Return Cause" },
1002 { CAUSE_TYPE_REFUSAL, "Refusal Cause" },
1003 { CAUSE_TYPE_RELEASE, "Release Cause" },
1004 { CAUSE_TYPE_RESET, "Reset Cause" },
1005 { CAUSE_TYPE_ERROR, "Error cause" },
1006 { 0, NULL } };
1008 static void
1009 dissect_sccp_cause_parameter(tvbuff_t *parameter_tvb, proto_tree *parameter_tree, proto_item *parameter_item)
1011 uint8_t cause_type, cause;
1012 proto_item *pi;
1013 const char *cause_string;
1015 proto_tree_add_item(parameter_tree, hf_sua_cause_reserved, parameter_tvb, PARAMETER_VALUE_OFFSET, RESERVED_2_LENGTH, ENC_NA);
1016 proto_tree_add_item(parameter_tree, hf_sua_cause_type, parameter_tvb, CAUSE_TYPE_OFFSET, CAUSE_TYPE_LENGTH, ENC_BIG_ENDIAN);
1017 cause_type = tvb_get_uint8(parameter_tvb, CAUSE_TYPE_OFFSET);
1018 pi = proto_tree_add_item(parameter_tree, hf_sua_cause_value, parameter_tvb, CAUSE_VALUE_OFFSET, CAUSE_VALUE_LENGTH, ENC_BIG_ENDIAN);
1019 cause = tvb_get_uint8(parameter_tvb, CAUSE_VALUE_OFFSET);
1021 switch (cause_type) {
1022 case CAUSE_TYPE_RETURN:
1023 cause_string = val_to_str_const(cause, sccp_return_cause_values, "unknown");
1024 break;
1025 case CAUSE_TYPE_REFUSAL:
1026 cause_string = val_to_str_const(cause, sccp_refusal_cause_values, "unknown");
1027 break;
1028 case CAUSE_TYPE_RELEASE:
1029 cause_string = val_to_str_const(cause, sccp_release_cause_values, "unknown");
1030 break;
1031 case CAUSE_TYPE_RESET:
1032 cause_string = val_to_str_const(cause, sccp_reset_cause_values, "unknown");
1033 break;
1034 case CAUSE_TYPE_ERROR:
1035 cause_string = val_to_str_const(cause, sccp_error_cause_values, "unknown");
1036 break;
1037 default:
1038 cause_string = "unknown";
1041 proto_item_append_text(pi, " (%s)", cause_string);
1042 proto_item_append_text(parameter_item, " (%s: %s)", val_to_str_const(cause_type, cause_type_values, "unknown"), cause_string);
1045 #define SEQUENCE_NUMBER_REC_SEQ_LENGTH 1
1046 #define SEQUENCE_NUMBER_SENT_SEQ_LENGTH 1
1047 #define SEQUENCE_NUMBER_REC_SEQ_OFFSET (PARAMETER_VALUE_OFFSET + RESERVED_2_LENGTH)
1048 #define SEQUENCE_NUMBER_SENT_SEQ_OFFSET (SEQUENCE_NUMBER_REC_SEQ_OFFSET + SEQUENCE_NUMBER_REC_SEQ_LENGTH)
1050 #define SEQ_NUM_MASK 0xFE
1051 #define SPARE_BIT_MASK 0x01
1052 #define MORE_DATA_BIT_MASK 0x01
1054 static const true_false_string more_data_bit_value = {
1055 "More Data",
1056 "Not More Data"
1059 static void
1060 dissect_sequence_number_parameter(tvbuff_t *parameter_tvb, proto_tree *parameter_tree)
1062 proto_tree *sent_sequence_number_tree;
1063 proto_tree *receive_sequence_number_tree;
1065 proto_tree_add_item(parameter_tree, hf_sua_sequence_number_reserved, parameter_tvb, PARAMETER_VALUE_OFFSET, RESERVED_2_LENGTH, ENC_NA);
1067 receive_sequence_number_tree = proto_tree_add_subtree(parameter_tree, parameter_tvb, SEQUENCE_NUMBER_REC_SEQ_OFFSET, SEQUENCE_NUMBER_REC_SEQ_LENGTH,
1068 ett_sua_sequence_number_rec_number, NULL, "Receive Sequence Number");
1069 proto_tree_add_item(receive_sequence_number_tree, hf_sua_sequence_number_rec_number, parameter_tvb, SEQUENCE_NUMBER_REC_SEQ_OFFSET, SEQUENCE_NUMBER_REC_SEQ_LENGTH, ENC_BIG_ENDIAN);
1070 proto_tree_add_item(receive_sequence_number_tree, hf_sua_sequence_number_more_data_bit, parameter_tvb, SEQUENCE_NUMBER_REC_SEQ_OFFSET, SEQUENCE_NUMBER_REC_SEQ_LENGTH, ENC_BIG_ENDIAN);
1072 sent_sequence_number_tree = proto_tree_add_subtree(parameter_tree, parameter_tvb, SEQUENCE_NUMBER_SENT_SEQ_OFFSET, SEQUENCE_NUMBER_SENT_SEQ_LENGTH,
1073 ett_sua_sequence_number_sent_number, NULL, "Sent Sequence Number");
1074 proto_tree_add_item(sent_sequence_number_tree, hf_sua_sequence_number_sent_number, parameter_tvb, SEQUENCE_NUMBER_SENT_SEQ_OFFSET, SEQUENCE_NUMBER_SENT_SEQ_LENGTH, ENC_BIG_ENDIAN);
1075 proto_tree_add_item(sent_sequence_number_tree, hf_sua_sequence_number_spare_bit, parameter_tvb, SEQUENCE_NUMBER_SENT_SEQ_OFFSET, SEQUENCE_NUMBER_SENT_SEQ_LENGTH, ENC_BIG_ENDIAN);
1078 #define RECEIVE_SEQUENCE_NUMBER_REC_SEQ_LENGTH 1
1079 #define RECEIVE_SEQUENCE_NUMBER_REC_SEQ_OFFSET (PARAMETER_VALUE_OFFSET + RESERVED_3_LENGTH)
1081 static void
1082 dissect_receive_sequence_number_parameter(tvbuff_t *parameter_tvb, proto_tree *parameter_tree)
1084 proto_tree *receive_sequence_number_tree;
1086 proto_tree_add_item(parameter_tree, hf_sua_receive_sequence_number_reserved, parameter_tvb, PARAMETER_VALUE_OFFSET, RESERVED_3_LENGTH, ENC_NA);
1087 receive_sequence_number_tree = proto_tree_add_subtree(parameter_tree, parameter_tvb, RECEIVE_SEQUENCE_NUMBER_REC_SEQ_OFFSET, RECEIVE_SEQUENCE_NUMBER_REC_SEQ_LENGTH,
1088 ett_sua_receive_sequence_number_number, NULL, "Receive Sequence Number");
1089 proto_tree_add_item(receive_sequence_number_tree, hf_sua_receive_sequence_number_number, parameter_tvb, RECEIVE_SEQUENCE_NUMBER_REC_SEQ_OFFSET, RECEIVE_SEQUENCE_NUMBER_REC_SEQ_LENGTH, ENC_BIG_ENDIAN);
1090 proto_tree_add_item(receive_sequence_number_tree, hf_sua_receive_sequence_number_spare_bit, parameter_tvb, RECEIVE_SEQUENCE_NUMBER_REC_SEQ_OFFSET, RECEIVE_SEQUENCE_NUMBER_REC_SEQ_LENGTH, ENC_BIG_ENDIAN);
1093 #define PROTOCOL_CLASSES_LENGTH 1
1094 #define INTERWORKING_LENGTH 1
1095 #define PROTOCOL_CLASSES_OFFSET (PARAMETER_VALUE_OFFSET + RESERVED_2_LENGTH)
1096 #define INTERWORKING_OFFSET (PROTOCOL_CLASSES_OFFSET + PROTOCOL_CLASSES_LENGTH)
1098 #define A_BIT_MASK 0x08
1099 #define B_BIT_MASK 0x04
1100 #define C_BIT_MASK 0x02
1101 #define D_BIT_MASK 0x01
1102 #define RESERVED_BITS_MASK 0xF0
1104 static const value_string interworking_values[] = {
1105 { 0x0, "No Interworking with SS7 Networks" },
1106 { 0x1, "IP-Signalling Endpoint interworking with SS7 networks" },
1107 { 0x2, "Signalling Gateway" },
1108 { 0x3, "Relay Node Support" },
1109 { 0, NULL } };
1111 static void
1112 dissect_asp_capabilities_parameter(tvbuff_t *parameter_tvb, proto_tree *parameter_tree)
1114 static int * const capabilities[] = {
1115 &hf_sua_asp_capabilities_reserved_bits,
1116 &hf_sua_asp_capabilities_a_bit,
1117 &hf_sua_asp_capabilities_b_bit,
1118 &hf_sua_asp_capabilities_c_bit,
1119 &hf_sua_asp_capabilities_d_bit,
1120 NULL
1123 proto_tree_add_item(parameter_tree, hf_sua_asp_capabilities_reserved, parameter_tvb, PARAMETER_VALUE_OFFSET, RESERVED_2_LENGTH, ENC_NA);
1124 proto_tree_add_bitmask(parameter_tree, parameter_tvb, PROTOCOL_CLASSES_OFFSET, hf_sua_protocol_classes, ett_sua_protocol_classes, capabilities, ENC_BIG_ENDIAN);
1125 proto_tree_add_item(parameter_tree, hf_sua_asp_capabilities_interworking, parameter_tvb, INTERWORKING_OFFSET, INTERWORKING_LENGTH, ENC_BIG_ENDIAN);
1128 #define CREDIT_LENGTH 4
1129 #define CREDIT_OFFSET PARAMETER_VALUE_OFFSET
1131 static void
1132 dissect_credit_parameter(tvbuff_t *parameter_tvb, proto_tree *parameter_tree, proto_item *parameter_item)
1134 proto_tree_add_item(parameter_tree, hf_sua_credit, parameter_tvb, CREDIT_OFFSET, CREDIT_LENGTH, ENC_BIG_ENDIAN);
1135 proto_item_append_text(parameter_item, " (%u)", tvb_get_ntohl(parameter_tvb, CREDIT_OFFSET));
1138 #define DATA_PARAMETER_DATA_OFFSET PARAMETER_VALUE_OFFSET
1140 static void
1141 dissect_data_parameter(tvbuff_t *parameter_tvb, proto_tree *parameter_tree, proto_item *parameter_item, tvbuff_t **data_tvb)
1143 uint16_t data_length;
1145 data_length = tvb_get_ntohs(parameter_tvb, PARAMETER_LENGTH_OFFSET) - PARAMETER_HEADER_LENGTH;
1147 if(parameter_tree) {
1148 proto_tree_add_item(parameter_tree, hf_sua_data, parameter_tvb, DATA_PARAMETER_DATA_OFFSET, data_length, ENC_NA);
1149 proto_item_append_text(parameter_item, " (SS7 message of %u byte%s)", data_length, plurality(data_length, "", "s"));
1152 if(data_tvb)
1154 *data_tvb = tvb_new_subset_length(parameter_tvb, PARAMETER_VALUE_OFFSET, data_length);
1159 #define CAUSE_LENGTH 2
1160 #define USER_LENGTH 2
1161 #define CAUSE_OFFSET PARAMETER_VALUE_OFFSET
1162 #define USER_OFFSET (CAUSE_OFFSET + CAUSE_LENGTH)
1164 static const value_string cause_values[] = {
1165 { 0x0, "Remote SCCP unavailable, Reason unknown" },
1166 { 0x2, "Remote SCCP unequipped" },
1167 { 0x3, "Remote SCCP inaccessible" },
1168 { 0, NULL } };
1170 static void
1171 dissect_user_cause_parameter(tvbuff_t *parameter_tvb, proto_tree *parameter_tree)
1173 proto_tree_add_item(parameter_tree, hf_sua_cause, parameter_tvb, CAUSE_OFFSET, CAUSE_LENGTH, ENC_BIG_ENDIAN);
1174 proto_tree_add_item(parameter_tree, hf_sua_user, parameter_tvb, USER_OFFSET, USER_LENGTH, ENC_BIG_ENDIAN);
1177 #define NETWORK_APPEARANCE_LENGTH 4
1178 #define NETWORK_APPEARANCE_OFFSET PARAMETER_VALUE_OFFSET
1180 static void
1181 dissect_network_appearance_parameter(tvbuff_t *parameter_tvb, proto_tree *parameter_tree, proto_item *parameter_item)
1183 proto_tree_add_item(parameter_tree, hf_sua_network_appearance, parameter_tvb, NETWORK_APPEARANCE_OFFSET, NETWORK_APPEARANCE_LENGTH, ENC_BIG_ENDIAN);
1184 proto_item_append_text(parameter_item, " (%u)", tvb_get_ntohl(parameter_tvb, NETWORK_APPEARANCE_OFFSET));
1187 static void
1188 // NOLINTNEXTLINE(misc-no-recursion)
1189 dissect_routing_key_parameter(tvbuff_t *parameter_tvb, packet_info *pinfo, proto_tree *parameter_tree)
1191 tvbuff_t *parameters_tvb;
1193 parameters_tvb = tvb_new_subset_remaining(parameter_tvb, PARAMETER_VALUE_OFFSET);
1194 dissect_parameters(parameters_tvb, pinfo, parameter_tree, NULL, NULL, NULL);
1196 #define DRN_START_LENGTH 1
1197 #define DRN_END_LENGTH 1
1198 #define DRN_VALUE_LENGTH 2
1200 #define DRN_START_OFFSET PARAMETER_VALUE_OFFSET
1201 #define DRN_END_OFFSET (DRN_START_OFFSET + DRN_START_LENGTH)
1202 #define DRN_VALUE_OFFSET (DRN_END_OFFSET + DRN_END_LENGTH)
1204 static void
1205 dissect_drn_label_parameter(tvbuff_t *parameter_tvb, proto_tree *parameter_tree)
1207 proto_tree_add_item(parameter_tree, hf_sua_drn_label_start, parameter_tvb, DRN_START_OFFSET, DRN_START_LENGTH, ENC_BIG_ENDIAN);
1208 proto_tree_add_item(parameter_tree, hf_sua_drn_label_end, parameter_tvb, DRN_END_OFFSET, DRN_END_LENGTH, ENC_BIG_ENDIAN);
1209 proto_tree_add_item(parameter_tree, hf_sua_drn_label_value, parameter_tvb, DRN_VALUE_OFFSET, DRN_VALUE_LENGTH, ENC_BIG_ENDIAN);
1212 #define TID_START_LENGTH 1
1213 #define TID_END_LENGTH 1
1214 #define TID_VALUE_LENGTH 2
1216 #define TID_START_OFFSET PARAMETER_VALUE_OFFSET
1217 #define TID_END_OFFSET (TID_START_OFFSET + TID_START_LENGTH)
1218 #define TID_VALUE_OFFSET (TID_END_OFFSET + TID_END_LENGTH)
1220 static void
1221 dissect_tid_label_parameter(tvbuff_t *parameter_tvb, proto_tree *parameter_tree)
1223 proto_tree_add_item(parameter_tree, hf_sua_tid_label_start, parameter_tvb, TID_START_OFFSET, TID_START_LENGTH, ENC_BIG_ENDIAN);
1224 proto_tree_add_item(parameter_tree, hf_sua_tid_label_end, parameter_tvb, TID_END_OFFSET, TID_END_LENGTH, ENC_BIG_ENDIAN);
1225 proto_tree_add_item(parameter_tree, hf_sua_tid_label_value, parameter_tvb, TID_VALUE_OFFSET, TID_VALUE_LENGTH, ENC_BIG_ENDIAN);
1228 #define ADDRESS_RANGE_ADDRESS_PARAMETERS_OFFSET PARAMETER_VALUE_OFFSET
1230 static void
1231 // NOLINTNEXTLINE(misc-no-recursion)
1232 dissect_address_range_parameter(tvbuff_t *parameter_tvb, packet_info *pinfo, proto_tree *parameter_tree)
1234 tvbuff_t *parameters_tvb;
1236 parameters_tvb = tvb_new_subset_remaining(parameter_tvb, PARAMETER_VALUE_OFFSET);
1237 dissect_parameters(parameters_tvb, pinfo, parameter_tree, NULL, NULL, NULL);
1240 #define SMI_LENGTH 1
1241 #define SMI_OFFSET (PARAMETER_VALUE_OFFSET + RESERVED_3_LENGTH)
1243 static void
1244 dissect_smi_parameter(tvbuff_t *parameter_tvb, proto_tree *parameter_tree, proto_item *parameter_item)
1246 proto_tree_add_item(parameter_tree, hf_sua_smi_reserved, parameter_tvb, PARAMETER_VALUE_OFFSET, RESERVED_3_LENGTH, ENC_NA);
1247 proto_tree_add_item(parameter_tree, hf_sua_smi, parameter_tvb, SMI_OFFSET, SMI_LENGTH, ENC_BIG_ENDIAN);
1248 proto_item_append_text(parameter_item, " (%u)", tvb_get_uint8(parameter_tvb, SMI_OFFSET));
1251 #define IMPORTANCE_LENGTH 1
1252 #define IMPORTANCE_OFFSET (PARAMETER_VALUE_OFFSET + RESERVED_3_LENGTH)
1254 static void
1255 dissect_importance_parameter(tvbuff_t *parameter_tvb, proto_tree *parameter_tree, proto_item *parameter_item)
1257 proto_tree_add_item(parameter_tree, hf_sua_importance_reserved, parameter_tvb, PARAMETER_VALUE_OFFSET, RESERVED_3_LENGTH, ENC_NA);
1258 proto_tree_add_item(parameter_tree, hf_sua_importance, parameter_tvb, IMPORTANCE_OFFSET, IMPORTANCE_LENGTH, ENC_BIG_ENDIAN);
1259 proto_item_append_text(parameter_item, " (%u)", tvb_get_uint8(parameter_tvb, IMPORTANCE_OFFSET));
1262 #define MESSAGE_PRIORITY_LENGTH 1
1263 #define MESSAGE_PRIORITY_OFFSET (PARAMETER_VALUE_OFFSET + RESERVED_3_LENGTH)
1265 static void
1266 dissect_message_priority_parameter(tvbuff_t *parameter_tvb, proto_tree *parameter_tree, proto_item *parameter_item)
1268 proto_tree_add_item(parameter_tree, hf_sua_message_priority_reserved, parameter_tvb, PARAMETER_VALUE_OFFSET, RESERVED_3_LENGTH, ENC_NA);
1269 proto_tree_add_item(parameter_tree, hf_sua_message_priority, parameter_tvb, MESSAGE_PRIORITY_OFFSET, MESSAGE_PRIORITY_LENGTH, ENC_BIG_ENDIAN);
1270 proto_item_append_text(parameter_item, " (%u)", tvb_get_uint8(parameter_tvb, MESSAGE_PRIORITY_OFFSET));
1273 #define PROTOCOL_CLASS_LENGTH 1
1274 #define PROTOCOL_CLASS_OFFSET (PARAMETER_VALUE_OFFSET + RESERVED_3_LENGTH)
1276 #define RETURN_ON_ERROR_BIT_MASK 0x80
1277 #define PROTOCOL_CLASS_MASK 0x7f
1280 static const true_false_string return_on_error_bit_value = {
1281 "Return Message On Error",
1282 "No Special Options"
1285 static void
1286 dissect_protocol_class_parameter(tvbuff_t *parameter_tvb, proto_tree *parameter_tree, proto_item *parameter_item)
1288 static int * const capabilities[] = {
1289 &hf_sua_return_on_error_bit,
1290 &hf_sua_protocol_class,
1291 NULL
1294 proto_tree_add_item(parameter_tree, hf_sua_protocol_class_reserved, parameter_tvb, PARAMETER_VALUE_OFFSET, RESERVED_3_LENGTH, ENC_NA);
1295 proto_tree_add_bitmask(parameter_tree, parameter_tvb, PROTOCOL_CLASS_OFFSET, hf_sua_protocol_class_flags, ett_sua_return_on_error_bit_and_protocol_class, capabilities, ENC_BIG_ENDIAN);
1296 proto_item_append_text(parameter_item, " (%d)", tvb_get_uint8(parameter_tvb, PROTOCOL_CLASS_OFFSET) & PROTOCOL_CLASS_MASK);
1299 #define SEQUENCE_CONTROL_LENGTH 4
1300 #define SEQUENCE_CONTROL_OFFSET PARAMETER_VALUE_OFFSET
1302 static void
1303 dissect_sequence_control_parameter(tvbuff_t *parameter_tvb, proto_tree *parameter_tree, proto_item *parameter_item)
1305 proto_tree_add_item(parameter_tree, hf_sua_sequence_control, parameter_tvb, SEQUENCE_CONTROL_OFFSET, SEQUENCE_CONTROL_LENGTH, ENC_BIG_ENDIAN);
1306 proto_item_append_text(parameter_item, " (%u)", tvb_get_ntohl(parameter_tvb, SEQUENCE_CONTROL_OFFSET));
1309 #define FIRST_REMAINING_LENGTH 1
1310 #define SEGMENTATION_REFERENCE_LENGTH 3
1311 #define FIRST_REMAINING_OFFSET PARAMETER_VALUE_OFFSET
1312 #define SEGMENTATION_REFERENCE_OFFSET (FIRST_REMAINING_OFFSET + FIRST_REMAINING_LENGTH)
1314 #define FIRST_BIT_MASK 0x80
1315 #define NUMBER_OF_SEGMENTS_MASK 0x7f
1317 static const true_false_string first_bit_value = {
1318 "First segment",
1319 "Subsequent segment"
1322 static void
1323 dissect_segmentation_parameter(tvbuff_t *parameter_tvb, proto_tree *parameter_tree)
1325 static int * const first_remaining[] = {
1326 &hf_sua_first_bit,
1327 &hf_sua_number_of_remaining_segments,
1328 NULL
1331 proto_tree_add_bitmask(parameter_tree, parameter_tvb, FIRST_REMAINING_OFFSET, hf_sua_first_remaining, ett_sua_first_remaining, first_remaining, ENC_BIG_ENDIAN);
1332 proto_tree_add_item(parameter_tree, hf_sua_segmentation_reference, parameter_tvb, SEGMENTATION_REFERENCE_OFFSET, SEGMENTATION_REFERENCE_LENGTH, ENC_BIG_ENDIAN);
1335 #define CONGESTION_LEVEL_LENGTH 4
1336 #define CONGESTION_LEVEL_OFFSET PARAMETER_VALUE_OFFSET
1338 static void
1339 dissect_congestion_level_parameter(tvbuff_t *parameter_tvb, proto_tree *parameter_tree, proto_item *parameter_item)
1341 proto_tree_add_item(parameter_tree, hf_sua_congestion_level, parameter_tvb, CONGESTION_LEVEL_OFFSET, CONGESTION_LEVEL_LENGTH, ENC_BIG_ENDIAN);
1342 proto_item_append_text(parameter_item, " (%u)", tvb_get_ntohl(parameter_tvb, CONGESTION_LEVEL_OFFSET));
1345 #define GTI_LENGTH 1
1346 #define NO_OF_DIGITS_LENGTH 1
1347 #define TRANSLATION_TYPE_LENGTH 1
1348 #define NUMBERING_PLAN_LENGTH 1
1349 #define NATURE_OF_ADDRESS_LENGTH 1
1351 #define GTI_OFFSET (PARAMETER_VALUE_OFFSET + RESERVED_3_LENGTH)
1352 #define NO_OF_DIGITS_OFFSET (GTI_OFFSET + GTI_LENGTH)
1353 #define TRANSLATION_TYPE_OFFSET (NO_OF_DIGITS_OFFSET + NO_OF_DIGITS_LENGTH)
1354 #define NUMBERING_PLAN_OFFSET (TRANSLATION_TYPE_OFFSET + TRANSLATION_TYPE_LENGTH)
1355 #define NATURE_OF_ADDRESS_OFFSET (NUMBERING_PLAN_OFFSET + NUMBERING_PLAN_LENGTH)
1356 #define GLOBAL_TITLE_OFFSET (NATURE_OF_ADDRESS_OFFSET + NATURE_OF_ADDRESS_LENGTH)
1358 #define ISDN_TELEPHONY_NUMBERING_PLAN 1
1359 #define GENERIC_NUMBERING_PLAN 2
1360 #define DATA_NUMBERING_PLAN 3
1361 #define TELEX_NUMBERING_PLAN 4
1362 #define MARITIME_MOBILE_NUMBERING_PLAN 5
1363 #define LAND_MOBILE_NUMBERING_PLAN 6
1364 #define ISDN_MOBILE_NUMBERING_PLAN 7
1365 #define PRIVATE_NETWORK_NUMBERING_PLAN 14
1367 static const value_string numbering_plan_values[] = {
1368 { ISDN_TELEPHONY_NUMBERING_PLAN, "ISDN/Telephony Numbering Plan (Rec. E.161 and E.164)" },
1369 { GENERIC_NUMBERING_PLAN, "Generic Numbering Plan" },
1370 { DATA_NUMBERING_PLAN, "Data Numbering Plan (Rec. X.121)" },
1371 { TELEX_NUMBERING_PLAN, "Telex Numbering Plan (Rec. F.69)" },
1372 { MARITIME_MOBILE_NUMBERING_PLAN, "Maritime Mobile Numbering Plan (Rec. E.210 and E.211)" },
1373 { LAND_MOBILE_NUMBERING_PLAN, "Land Mobile Numbering Plan (Rec. E.212)" },
1374 { ISDN_MOBILE_NUMBERING_PLAN, "ISDN/Mobile Numbering Plan (Rec. E.214)" },
1375 { PRIVATE_NETWORK_NUMBERING_PLAN, "Private Network Or Network-Specific Numbering Plan" },
1376 { 0, NULL } };
1378 #define UNKNOWN_NATURE_OF_ADDRESS 0
1379 #define SUBSCRIBER_NUMBER_NATURE_OF_ADDRESS 1
1380 #define RESERVED_FOR_NATIONAL_USE_NATURE_OF_ADDRESS 2
1381 #define NATIONAL_SIGNIFICANT_NUMBER_NATURE_OF_ADDRESS 3
1382 #define INTERNATION_NUMBER_NATURE_OF_ADDRESS 4
1384 static const value_string nature_of_address_values[] = {
1385 { UNKNOWN_NATURE_OF_ADDRESS, "Unknown" },
1386 { SUBSCRIBER_NUMBER_NATURE_OF_ADDRESS, "Subscriber Number" },
1387 { RESERVED_FOR_NATIONAL_USE_NATURE_OF_ADDRESS, "Reserved For National Use" },
1388 { NATIONAL_SIGNIFICANT_NUMBER_NATURE_OF_ADDRESS, "National Significant Number" },
1389 { INTERNATION_NUMBER_NATURE_OF_ADDRESS, "International Number" },
1390 { 0, NULL } };
1392 static void
1393 dissect_global_title_parameter(tvbuff_t *parameter_tvb, proto_tree *parameter_tree, bool source)
1395 uint16_t global_title_length;
1396 uint16_t offset;
1397 bool even_length;
1398 uint8_t odd_signal, even_signal;
1399 uint8_t number_of_digits;
1400 char *gt_digits;
1402 gt_digits = (char *)wmem_alloc0(wmem_packet_scope(), GT_MAX_SIGNALS+1);
1404 global_title_length = tvb_get_ntohs(parameter_tvb, PARAMETER_LENGTH_OFFSET) -
1405 (PARAMETER_HEADER_LENGTH + RESERVED_3_LENGTH + GTI_LENGTH + NO_OF_DIGITS_LENGTH + TRANSLATION_TYPE_LENGTH + NUMBERING_PLAN_LENGTH + NATURE_OF_ADDRESS_LENGTH);
1406 proto_tree_add_item(parameter_tree, source ? hf_sua_source_gt_reserved : hf_sua_dest_gt_reserved, parameter_tvb, PARAMETER_VALUE_OFFSET, RESERVED_3_LENGTH, ENC_NA);
1407 proto_tree_add_item(parameter_tree, source ? hf_sua_source_gti : hf_sua_dest_gti, parameter_tvb, GTI_OFFSET, GTI_LENGTH, ENC_BIG_ENDIAN);
1408 proto_tree_add_item(parameter_tree, source ? hf_sua_source_number_of_digits : hf_sua_dest_number_of_digits, parameter_tvb, NO_OF_DIGITS_OFFSET, NO_OF_DIGITS_LENGTH, ENC_BIG_ENDIAN);
1409 proto_tree_add_item(parameter_tree, source ? hf_sua_source_translation_type : hf_sua_dest_translation_type, parameter_tvb, TRANSLATION_TYPE_OFFSET, TRANSLATION_TYPE_LENGTH, ENC_BIG_ENDIAN);
1410 proto_tree_add_item(parameter_tree, source ? hf_sua_source_numbering_plan : hf_sua_dest_numbering_plan, parameter_tvb, NUMBERING_PLAN_OFFSET, NUMBERING_PLAN_LENGTH, ENC_BIG_ENDIAN);
1411 proto_tree_add_item(parameter_tree, source ? hf_sua_source_nature_of_address : hf_sua_dest_nature_of_address, parameter_tvb, NATURE_OF_ADDRESS_OFFSET, NATURE_OF_ADDRESS_LENGTH, ENC_BIG_ENDIAN);
1413 number_of_digits = tvb_get_uint8(parameter_tvb, NO_OF_DIGITS_OFFSET);
1414 even_length = !(number_of_digits % 2);
1415 offset = GLOBAL_TITLE_OFFSET;
1417 while(offset < GLOBAL_TITLE_OFFSET + global_title_length) {
1418 odd_signal = tvb_get_uint8(parameter_tvb, offset) & GT_ODD_SIGNAL_MASK;
1419 even_signal = tvb_get_uint8(parameter_tvb, offset) & GT_EVEN_SIGNAL_MASK;
1420 even_signal >>= GT_EVEN_SIGNAL_SHIFT;
1422 (void) g_strlcat(gt_digits, val_to_str_const(odd_signal, sccp_address_signal_values,
1423 "Unknown"), GT_MAX_SIGNALS+1);
1425 /* If the last signal is NOT filler */
1426 if (offset != (GLOBAL_TITLE_OFFSET + global_title_length - 1) || even_length == true)
1427 (void) g_strlcat(gt_digits, val_to_str_const(even_signal, sccp_address_signal_values,
1428 "Unknown"), GT_MAX_SIGNALS+1);
1430 offset += GT_SIGNAL_LENGTH;
1433 proto_tree_add_string_format(parameter_tree, source ? hf_sua_source_global_title_digits : hf_sua_dest_global_title_digits,
1434 parameter_tvb, GLOBAL_TITLE_OFFSET,
1435 global_title_length, gt_digits,
1436 "Address information (digits): %s", gt_digits);
1438 if (sua_ri == ROUTE_ON_GT_ROUTING_INDICATOR) {
1439 if (source) {
1440 sua_source_gt = gt_digits;
1441 } else {
1442 sua_destination_gt = gt_digits;
1447 #define POINT_CODE_LENGTH 4
1448 #define POINT_CODE_OFFSET PARAMETER_VALUE_OFFSET
1450 static void
1451 dissect_point_code_parameter(tvbuff_t *parameter_tvb, proto_tree *parameter_tree, proto_item *parameter_item, bool source)
1453 uint32_t pc;
1455 pc = tvb_get_ntohl(parameter_tvb, POINT_CODE_OFFSET);
1457 if (sua_ri == ROUTE_ON_SSN_PC_ROUTING_INDICATOR) {
1458 if (source) {
1459 sua_opc->type = (Standard_Type)mtp3_standard;
1460 sua_opc->pc = pc;
1461 } else {
1462 sua_dpc->type = (Standard_Type)mtp3_standard;
1463 sua_dpc->pc = pc;
1467 proto_tree_add_item(parameter_tree, source ? hf_sua_source_point_code : hf_sua_dest_point_code, parameter_tvb, POINT_CODE_OFFSET, POINT_CODE_LENGTH, ENC_BIG_ENDIAN);
1468 proto_item_append_text(parameter_item, " (%s)", mtp3_pc_to_str(pc));
1471 #define SSN_LENGTH 1
1472 #define SSN_OFFSET (PARAMETER_VALUE_OFFSET + RESERVED_3_LENGTH)
1473 #define INVALID_SSN 0xff
1475 static void
1476 dissect_ssn_parameter(tvbuff_t *parameter_tvb, proto_tree *parameter_tree, proto_item *parameter_item, uint8_t *ssn, bool source)
1478 *ssn = tvb_get_uint8(parameter_tvb, SSN_OFFSET);
1480 if(parameter_tree) {
1481 proto_tree_add_item(parameter_tree, source ? hf_sua_source_ssn_reserved : hf_sua_dest_ssn_reserved, parameter_tvb, PARAMETER_VALUE_OFFSET, RESERVED_3_LENGTH, ENC_NA);
1482 proto_tree_add_item(parameter_tree, source ? hf_sua_source_ssn_number : hf_sua_dest_ssn_number, parameter_tvb, SSN_OFFSET, SSN_LENGTH, ENC_BIG_ENDIAN);
1483 proto_item_append_text(parameter_item, " (%u)", *ssn);
1487 #define IPV4_ADDRESS_LENGTH 4
1488 #define IPV4_ADDRESS_OFFSET PARAMETER_VALUE_OFFSET
1490 static void
1491 dissect_ipv4_parameter(tvbuff_t *parameter_tvb, proto_tree *parameter_tree, proto_item *parameter_item, bool source)
1493 proto_tree_add_item(parameter_tree, source ? hf_sua_source_ipv4 : hf_sua_dest_ipv4, parameter_tvb, IPV4_ADDRESS_OFFSET, IPV4_ADDRESS_LENGTH, ENC_BIG_ENDIAN);
1494 proto_item_append_text(parameter_item, " (%s)", tvb_ip_to_str(wmem_packet_scope(), parameter_tvb, IPV4_ADDRESS_OFFSET));
1497 #define HOSTNAME_OFFSET PARAMETER_VALUE_OFFSET
1499 static void
1500 dissect_hostname_parameter(tvbuff_t *parameter_tvb, proto_tree *parameter_tree, proto_item *parameter_item, bool source)
1502 uint16_t hostname_length;
1504 hostname_length = tvb_get_ntohs(parameter_tvb, PARAMETER_LENGTH_OFFSET) - PARAMETER_HEADER_LENGTH;
1505 proto_tree_add_item(parameter_tree, source ? hf_sua_source_hostname : hf_sua_dest_hostname, parameter_tvb, HOSTNAME_OFFSET, hostname_length, ENC_ASCII);
1506 proto_item_append_text(parameter_item, " (%s)",
1507 tvb_format_text(wmem_packet_scope(), parameter_tvb, HOSTNAME_OFFSET, hostname_length));
1510 #define IPV6_ADDRESS_LENGTH 16
1511 #define IPV6_ADDRESS_OFFSET PARAMETER_VALUE_OFFSET
1513 static void
1514 dissect_ipv6_parameter(tvbuff_t *parameter_tvb, proto_tree *parameter_tree, proto_item *parameter_item, bool source)
1516 proto_tree_add_item(parameter_tree, source ? hf_sua_source_ipv6 : hf_sua_dest_ipv6, parameter_tvb, IPV6_ADDRESS_OFFSET, IPV6_ADDRESS_LENGTH, ENC_NA);
1517 proto_item_append_text(parameter_item, " (%s)", tvb_ip6_to_str(wmem_packet_scope(), parameter_tvb, IPV6_ADDRESS_OFFSET));
1520 static void
1521 dissect_unknown_parameter(tvbuff_t *parameter_tvb, proto_tree *parameter_tree, proto_item *parameter_item)
1523 uint16_t parameter_value_length;
1525 parameter_value_length = tvb_get_ntohs(parameter_tvb, PARAMETER_LENGTH_OFFSET) - PARAMETER_HEADER_LENGTH;
1526 proto_tree_add_item(parameter_tree, hf_sua_parameter_value, parameter_tvb, PARAMETER_VALUE_OFFSET, parameter_value_length, ENC_NA);
1527 proto_item_append_text(parameter_item, "(tag %u and %u byte%s value)", tvb_get_ntohs(parameter_tvb, PARAMETER_TAG_OFFSET), parameter_value_length, plurality(parameter_value_length, "", "s"));
1530 #define V8_DATA_PARAMETER_TAG 0x0003
1531 #define V8_INFO_STRING_PARAMETER_TAG 0x0004
1532 #define V8_ROUTING_CONTEXT_PARAMETER_TAG 0x0006
1533 #define V8_DIAGNOSTIC_INFO_PARAMETER_TAG 0x0007
1534 #define V8_HEARTBEAT_DATA_PARAMETER_TAG 0x0009
1535 #define V8_TRAFFIC_MODE_TYPE_PARAMETER_TAG 0x000b
1536 #define V8_ERROR_CODE_PARAMETER_TAG 0x000c
1537 #define V8_STATUS_PARAMETER_TAG 0x000d
1538 #define V8_CONGESTION_LEVEL_PARAMETER_TAG 0x000f
1539 #define V8_ASP_IDENTIFIER_PARAMETER_TAG 0x0011
1540 #define V8_AFFECTED_POINT_CODE_PARAMETER_TAG 0x0012
1542 #define V8_SS7_HOP_COUNTER_PARAMETER_TAG 0x0101
1543 #define V8_SOURCE_ADDRESS_PARAMETER_TAG 0x0102
1544 #define V8_DESTINATION_ADDRESS_PARAMETER_TAG 0x0103
1545 #define V8_SOURCE_REFERENCE_NUMBER_PARAMETER_TAG 0x0104
1546 #define V8_DESTINATION_REFERENCE_NUMBER_PARAMETER_TAG 0x0105
1547 #define V8_SCCP_CAUSE_PARAMETER_TAG 0x0106
1548 #define V8_SEQUENCE_NUMBER_PARAMETER_TAG 0x0107
1549 #define V8_RECEIVE_SEQUENCE_NUMBER_PARAMETER_TAG 0x0108
1550 #define V8_ASP_CAPABILITIES_PARAMETER_TAG 0x0109
1551 #define V8_CREDIT_PARAMETER_TAG 0x010a
1552 #define V8_USER_CAUSE_PARAMETER_TAG 0x010c
1553 #define V8_NETWORK_APPEARANCE_PARAMETER_TAG 0x010d
1554 #define V8_ROUTING_KEY_PARAMETER_TAG 0x010e
1555 #define V8_REGISTRATION_RESULT_PARAMETER_TAG 0x010f
1556 #define V8_DEREGISTRATION_RESULT_PARAMETER_TAG 0x0110
1557 #define V8_ADDRESS_RANGE_PARAMETER_TAG 0x0111
1558 #define V8_CORRELATION_ID_PARAMETER_TAG 0x0112
1559 #define V8_IMPORTANCE_PARAMETER_TAG 0x0113
1560 #define V8_MESSAGE_PRIORITY_PARAMETER_TAG 0x0114
1561 #define V8_PROTOCOL_CLASS_PARAMETER_TAG 0x0115
1562 #define V8_SEQUENCE_CONTROL_PARAMETER_TAG 0x0116
1563 #define V8_SEGMENTATION_PARAMETER_TAG 0x0117
1564 #define V8_SMI_PARAMETER_TAG 0x0118
1565 #define V8_TID_LABEL_PARAMETER_TAG 0x0119
1566 #define V8_DRN_LABEL_PARAMETER_TAG 0x011a
1568 #define V8_GLOBAL_TITLE_PARAMETER_TAG 0x8001
1569 #define V8_POINT_CODE_PARAMETER_TAG 0x8002
1570 #define V8_SUBSYSTEM_NUMBER_PARAMETER_TAG 0x8003
1571 #define V8_IPV4_ADDRESS_PARAMETER_TAG 0x8004
1572 #define V8_HOSTNAME_PARAMETER_TAG 0x8005
1573 #define V8_IPV6_ADDRESS_PARAMETER_TAG 0x8006
1575 static const value_string v8_parameter_tag_values[] = {
1576 { V8_DATA_PARAMETER_TAG, "Data" },
1577 { V8_INFO_STRING_PARAMETER_TAG, "Info String" },
1578 { V8_ROUTING_CONTEXT_PARAMETER_TAG, "Routing context" },
1579 { V8_DIAGNOSTIC_INFO_PARAMETER_TAG, "Diagnostic info" },
1580 { V8_HEARTBEAT_DATA_PARAMETER_TAG, "Heartbeat data" },
1581 { V8_TRAFFIC_MODE_TYPE_PARAMETER_TAG, "Traffic mode type" },
1582 { V8_ERROR_CODE_PARAMETER_TAG, "Error code" },
1583 { V8_STATUS_PARAMETER_TAG, "Status" },
1584 { V8_CONGESTION_LEVEL_PARAMETER_TAG, "Congestion level" },
1585 { V8_ASP_IDENTIFIER_PARAMETER_TAG, "ASP identifier" },
1586 { V8_AFFECTED_POINT_CODE_PARAMETER_TAG, "Affected point code" },
1587 { V8_SS7_HOP_COUNTER_PARAMETER_TAG, "SS7 hop counter" },
1588 { V8_SOURCE_ADDRESS_PARAMETER_TAG, "Source address" },
1589 { V8_DESTINATION_ADDRESS_PARAMETER_TAG, "Destination address" },
1590 { V8_SOURCE_REFERENCE_NUMBER_PARAMETER_TAG, "Source reference number" },
1591 { V8_DESTINATION_REFERENCE_NUMBER_PARAMETER_TAG, "Destination reference number" },
1592 { V8_SCCP_CAUSE_PARAMETER_TAG, "SCCP cause" },
1593 { V8_SEQUENCE_NUMBER_PARAMETER_TAG, "Sequence number" },
1594 { V8_RECEIVE_SEQUENCE_NUMBER_PARAMETER_TAG, "Receive sequence number" },
1595 { V8_ASP_CAPABILITIES_PARAMETER_TAG, "ASP capabilities" },
1596 { V8_CREDIT_PARAMETER_TAG, "Credit" },
1597 { V8_USER_CAUSE_PARAMETER_TAG, "User/Cause" },
1598 { V8_NETWORK_APPEARANCE_PARAMETER_TAG, "Network appearance" },
1599 { V8_ROUTING_KEY_PARAMETER_TAG, "Routing key" },
1600 { V8_REGISTRATION_RESULT_PARAMETER_TAG, "Registration result" },
1601 { V8_DEREGISTRATION_RESULT_PARAMETER_TAG, "Deregistration result" },
1602 { V8_ADDRESS_RANGE_PARAMETER_TAG, "Address range" },
1603 { V8_CORRELATION_ID_PARAMETER_TAG, "Correlation ID" },
1604 { V8_IMPORTANCE_PARAMETER_TAG, "Importance" },
1605 { V8_MESSAGE_PRIORITY_PARAMETER_TAG, "Message priority" },
1606 { V8_PROTOCOL_CLASS_PARAMETER_TAG, "Protocol class" },
1607 { V8_SEQUENCE_CONTROL_PARAMETER_TAG, "Sequence control" },
1608 { V8_SEGMENTATION_PARAMETER_TAG, "Segmentation" },
1609 { V8_SMI_PARAMETER_TAG, "SMI" },
1610 { V8_TID_LABEL_PARAMETER_TAG, "TID label" },
1611 { V8_DRN_LABEL_PARAMETER_TAG, "DRN label" },
1612 { V8_GLOBAL_TITLE_PARAMETER_TAG, "Global title" },
1613 { V8_POINT_CODE_PARAMETER_TAG, "Point code" },
1614 { V8_SUBSYSTEM_NUMBER_PARAMETER_TAG, "Subsystem number" },
1615 { V8_IPV4_ADDRESS_PARAMETER_TAG, "IPv4 address" },
1616 { V8_HOSTNAME_PARAMETER_TAG, "Hostname" },
1617 { V8_IPV6_ADDRESS_PARAMETER_TAG, "IPv6 address" },
1618 { 0, NULL } };
1620 static void
1621 // NOLINTNEXTLINE(misc-no-recursion)
1622 dissect_v8_parameter(tvbuff_t *parameter_tvb, packet_info *pinfo, proto_tree *tree, tvbuff_t **data_tvb, uint8_t *source_ssn, uint8_t *dest_ssn)
1624 uint16_t tag, length, padding_length;
1625 proto_item *parameter_item;
1626 proto_tree *parameter_tree;
1627 uint8_t ssn = INVALID_SSN;
1629 /* extract tag and length from the parameter */
1630 tag = tvb_get_ntohs(parameter_tvb, PARAMETER_TAG_OFFSET);
1631 length = tvb_get_ntohs(parameter_tvb, PARAMETER_LENGTH_OFFSET);
1632 padding_length = tvb_reported_length(parameter_tvb) - length;
1634 /* create proto_tree stuff */
1635 parameter_tree = proto_tree_add_subtree(tree, parameter_tvb, PARAMETER_HEADER_OFFSET, -1, ett_sua_parameter, &parameter_item, val_to_str_const(tag, v8_parameter_tag_values, "Unknown parameter"));
1637 /* add tag and length to the sua tree */
1638 proto_tree_add_item(parameter_tree, hf_sua_v8_parameter_tag, parameter_tvb, PARAMETER_TAG_OFFSET, PARAMETER_TAG_LENGTH, ENC_BIG_ENDIAN);
1639 proto_tree_add_item(parameter_tree, hf_sua_parameter_length, parameter_tvb, PARAMETER_LENGTH_OFFSET, PARAMETER_LENGTH_LENGTH, ENC_BIG_ENDIAN);
1642 ** If no tree, only the data and ssn parameters in the source and destination
1643 ** address need to be dissected. This in order to make dissection of the data
1644 ** possible when there is no tree.
1646 if (!tree && tag != V8_DATA_PARAMETER_TAG
1647 && tag != V8_SOURCE_ADDRESS_PARAMETER_TAG
1648 && tag != V8_DESTINATION_ADDRESS_PARAMETER_TAG
1649 && tag != V8_DESTINATION_REFERENCE_NUMBER_PARAMETER_TAG
1650 && tag != V8_SOURCE_REFERENCE_NUMBER_PARAMETER_TAG
1651 && tag != V8_SUBSYSTEM_NUMBER_PARAMETER_TAG)
1652 return;
1654 increment_dissection_depth(pinfo);
1655 switch(tag) {
1656 case V8_DATA_PARAMETER_TAG:
1657 dissect_data_parameter(parameter_tvb, parameter_tree, parameter_item, data_tvb);
1658 break;
1659 case V8_INFO_STRING_PARAMETER_TAG:
1660 dissect_info_string_parameter(parameter_tvb, pinfo, parameter_tree, parameter_item);
1661 break;
1662 case V8_ROUTING_CONTEXT_PARAMETER_TAG:
1663 dissect_routing_context_parameter(parameter_tvb, parameter_tree, parameter_item);
1664 break;
1665 case V8_DIAGNOSTIC_INFO_PARAMETER_TAG:
1666 dissect_diagnostic_information_parameter(parameter_tvb, parameter_tree, parameter_item);
1667 break;
1668 case V8_HEARTBEAT_DATA_PARAMETER_TAG:
1669 dissect_heartbeat_data_parameter(parameter_tvb, parameter_tree, parameter_item);
1670 break;
1671 case V8_TRAFFIC_MODE_TYPE_PARAMETER_TAG:
1672 dissect_traffic_mode_type_parameter(parameter_tvb, parameter_tree, parameter_item);
1673 break;
1674 case V8_ERROR_CODE_PARAMETER_TAG:
1675 dissect_v8_error_code_parameter(parameter_tvb, parameter_tree, parameter_item);
1676 break;
1677 case V8_STATUS_PARAMETER_TAG:
1678 dissect_status_type_parameter(parameter_tvb, parameter_tree, parameter_item);
1679 break;
1680 case V8_CONGESTION_LEVEL_PARAMETER_TAG:
1681 dissect_congestion_level_parameter(parameter_tvb, parameter_tree, parameter_item);
1682 break;
1683 case V8_ASP_IDENTIFIER_PARAMETER_TAG:
1684 dissect_asp_identifier_parameter(parameter_tvb, parameter_tree, parameter_item);
1685 break;
1686 case V8_AFFECTED_POINT_CODE_PARAMETER_TAG:
1687 dissect_affected_destinations_parameter(parameter_tvb, parameter_tree, parameter_item);
1688 break;
1689 case V8_SS7_HOP_COUNTER_PARAMETER_TAG:
1690 dissect_ss7_hop_counter_parameter(parameter_tvb, parameter_tree, parameter_item);
1691 break;
1692 case V8_SOURCE_ADDRESS_PARAMETER_TAG:
1693 dissect_source_address_parameter(parameter_tvb, pinfo, parameter_tree, source_ssn);
1694 break;
1695 case V8_DESTINATION_ADDRESS_PARAMETER_TAG:
1696 dissect_destination_address_parameter(parameter_tvb, pinfo, parameter_tree, dest_ssn);
1697 break;
1698 case V8_SOURCE_REFERENCE_NUMBER_PARAMETER_TAG:
1699 dissect_source_reference_number_parameter(parameter_tvb, parameter_tree, parameter_item);
1700 break;
1701 case V8_DESTINATION_REFERENCE_NUMBER_PARAMETER_TAG:
1702 dissect_destination_reference_number_parameter(parameter_tvb, parameter_tree, parameter_item);
1703 break;
1704 case V8_SCCP_CAUSE_PARAMETER_TAG:
1705 dissect_sccp_cause_parameter(parameter_tvb, parameter_tree, parameter_item);
1706 break;
1707 case V8_SEQUENCE_NUMBER_PARAMETER_TAG:
1708 dissect_sequence_number_parameter(parameter_tvb, parameter_tree);
1709 break;
1710 case V8_RECEIVE_SEQUENCE_NUMBER_PARAMETER_TAG:
1711 dissect_receive_sequence_number_parameter(parameter_tvb, parameter_tree);
1712 break;
1713 case V8_ASP_CAPABILITIES_PARAMETER_TAG:
1714 dissect_asp_capabilities_parameter(parameter_tvb, parameter_tree);
1715 break;
1716 case V8_CREDIT_PARAMETER_TAG:
1717 dissect_credit_parameter(parameter_tvb, parameter_tree, parameter_item);
1718 break;
1719 case V8_USER_CAUSE_PARAMETER_TAG:
1720 dissect_user_cause_parameter(parameter_tvb, parameter_tree);
1721 break;
1722 case V8_NETWORK_APPEARANCE_PARAMETER_TAG:
1723 dissect_network_appearance_parameter(parameter_tvb, parameter_tree, parameter_item);
1724 break;
1725 case V8_ROUTING_KEY_PARAMETER_TAG:
1726 dissect_routing_key_parameter(parameter_tvb, pinfo, parameter_tree);
1727 break;
1728 case V8_REGISTRATION_RESULT_PARAMETER_TAG:
1729 dissect_registration_result_parameter(parameter_tvb, pinfo, parameter_tree);
1730 break;
1731 case V8_DEREGISTRATION_RESULT_PARAMETER_TAG:
1732 dissect_deregistration_result_parameter(parameter_tvb, pinfo, parameter_tree);
1733 break;
1734 case V8_ADDRESS_RANGE_PARAMETER_TAG:
1735 dissect_address_range_parameter(parameter_tvb, pinfo, parameter_tree);
1736 break;
1737 case V8_CORRELATION_ID_PARAMETER_TAG:
1738 dissect_correlation_id_parameter(parameter_tvb, parameter_tree, parameter_item);
1739 break;
1740 case V8_IMPORTANCE_PARAMETER_TAG:
1741 dissect_importance_parameter(parameter_tvb, parameter_tree, parameter_item);
1742 break;
1743 case V8_MESSAGE_PRIORITY_PARAMETER_TAG:
1744 dissect_message_priority_parameter(parameter_tvb, parameter_tree, parameter_item);
1745 break;
1746 case V8_PROTOCOL_CLASS_PARAMETER_TAG:
1747 dissect_protocol_class_parameter(parameter_tvb, parameter_tree, parameter_item);
1748 break;
1749 case V8_SEQUENCE_CONTROL_PARAMETER_TAG:
1750 dissect_sequence_control_parameter(parameter_tvb, parameter_tree, parameter_item);
1751 break;
1752 case V8_SEGMENTATION_PARAMETER_TAG:
1753 dissect_segmentation_parameter(parameter_tvb, parameter_tree);
1754 break;
1755 case V8_SMI_PARAMETER_TAG:
1756 dissect_smi_parameter(parameter_tvb, parameter_tree, parameter_item);
1757 break;
1758 case V8_TID_LABEL_PARAMETER_TAG:
1759 dissect_tid_label_parameter(parameter_tvb, parameter_tree);
1760 break;
1761 case V8_DRN_LABEL_PARAMETER_TAG:
1762 dissect_drn_label_parameter(parameter_tvb, parameter_tree);
1763 break;
1764 case V8_GLOBAL_TITLE_PARAMETER_TAG:
1765 /* Reuse whether we have source_ssn or not to determine which address we're looking at */
1766 dissect_global_title_parameter(parameter_tvb, parameter_tree, (source_ssn != NULL));
1767 break;
1768 case V8_POINT_CODE_PARAMETER_TAG:
1769 /* Reuse whether we have source_ssn or not to determine which address we're looking at */
1770 dissect_point_code_parameter(parameter_tvb, parameter_tree, parameter_item, (source_ssn != NULL));
1771 break;
1772 case V8_SUBSYSTEM_NUMBER_PARAMETER_TAG:
1773 /* Reuse whether we have source_ssn or not to determine which address we're looking at */
1774 dissect_ssn_parameter(parameter_tvb, parameter_tree, parameter_item, &ssn, (source_ssn != NULL));
1775 if(source_ssn)
1777 *source_ssn = ssn;
1779 if(dest_ssn)
1781 *dest_ssn = ssn;
1783 break;
1784 case V8_IPV4_ADDRESS_PARAMETER_TAG:
1785 /* Reuse whether we have source_ssn or not to determine which address we're looking at */
1786 dissect_ipv4_parameter(parameter_tvb, parameter_tree, parameter_item, (source_ssn != NULL));
1787 break;
1788 case V8_HOSTNAME_PARAMETER_TAG:
1789 /* Reuse whether we have source_ssn or not to determine which address we're looking at */
1790 dissect_hostname_parameter(parameter_tvb, parameter_tree, parameter_item, (source_ssn != NULL));
1791 break;
1792 case V8_IPV6_ADDRESS_PARAMETER_TAG:
1793 /* Reuse whether we have source_ssn or not to determine which address we're looking at */
1794 dissect_ipv6_parameter(parameter_tvb, parameter_tree, parameter_item, (source_ssn != NULL));
1795 break;
1796 default:
1797 dissect_unknown_parameter(parameter_tvb, parameter_tree, parameter_item);
1798 break;
1800 decrement_dissection_depth(pinfo);
1802 if (parameter_tree && (padding_length > 0))
1803 proto_tree_add_item(parameter_tree, hf_sua_parameter_padding, parameter_tvb, PARAMETER_HEADER_OFFSET + length, padding_length, ENC_NA);
1806 #define INFO_STRING_PARAMETER_TAG 0x0004
1807 #define ROUTING_CONTEXT_PARAMETER_TAG 0x0006
1808 #define DIAGNOSTIC_INFO_PARAMETER_TAG 0x0007
1809 #define HEARTBEAT_DATA_PARAMETER_TAG 0x0009
1810 #define TRAFFIC_MODE_TYPE_PARAMETER_TAG 0x000b
1811 #define ERROR_CODE_PARAMETER_TAG 0x000c
1812 #define STATUS_PARAMETER_TAG 0x000d
1813 #define ASP_IDENTIFIER_PARAMETER_TAG 0x0011
1814 #define AFFECTED_POINT_CODE_PARAMETER_TAG 0x0012
1815 #define CORRELATION_ID_PARAMETER_TAG 0x0013
1816 #define REGISTRATION_RESULT_PARAMETER_TAG 0x0014
1817 #define DEREGISTRATION_RESULT_PARAMETER_TAG 0x0015
1818 #define REGISTRATION_STATUS_PARAMETER_TAG 0x0016
1819 #define DEREGISTRATION_STATUS_PARAMETER_TAG 0x0017
1820 #define LOCAL_ROUTING_KEY_IDENTIFIER_PARAMETER_TAG 0x0018
1822 #define SS7_HOP_COUNTER_PARAMETER_TAG 0x0101
1823 #define SOURCE_ADDRESS_PARAMETER_TAG 0x0102
1824 #define DESTINATION_ADDRESS_PARAMETER_TAG 0x0103
1825 #define SOURCE_REFERENCE_NUMBER_PARAMETER_TAG 0x0104
1826 #define DESTINATION_REFERENCE_NUMBER_PARAMETER_TAG 0x0105
1827 #define SCCP_CAUSE_PARAMETER_TAG 0x0106
1828 #define SEQUENCE_NUMBER_PARAMETER_TAG 0x0107
1829 #define RECEIVE_SEQUENCE_NUMBER_PARAMETER_TAG 0x0108
1830 #define ASP_CAPABILITIES_PARAMETER_TAG 0x0109
1831 #define CREDIT_PARAMETER_TAG 0x010a
1832 #define DATA_PARAMETER_TAG 0x010b
1833 #define USER_CAUSE_PARAMETER_TAG 0x010c
1834 #define NETWORK_APPEARANCE_PARAMETER_TAG 0x010d
1835 #define ROUTING_KEY_PARAMETER_TAG 0x010e
1836 #define DRN_LABEL_PARAMETER_TAG 0x010f
1837 #define TID_LABEL_PARAMETER_TAG 0x0110
1838 #define ADDRESS_RANGE_PARAMETER_TAG 0x0111
1839 #define SMI_PARAMETER_TAG 0x0112
1840 #define IMPORTANCE_PARAMETER_TAG 0x0113
1841 #define MESSAGE_PRIORITY_PARAMETER_TAG 0x0114
1842 #define PROTOCOL_CLASS_PARAMETER_TAG 0x0115
1843 #define SEQUENCE_CONTROL_PARAMETER_TAG 0x0116
1844 #define SEGMENTATION_PARAMETER_TAG 0x0117
1845 #define CONGESTION_LEVEL_PARAMETER_TAG 0x0118
1847 #define GLOBAL_TITLE_PARAMETER_TAG 0x8001
1848 #define POINT_CODE_PARAMETER_TAG 0x8002
1849 #define SUBSYSTEM_NUMBER_PARAMETER_TAG 0x8003
1850 #define IPV4_ADDRESS_PARAMETER_TAG 0x8004
1851 #define HOSTNAME_PARAMETER_TAG 0x8005
1852 #define IPV6_ADDRESS_PARAMETER_TAG 0x8006
1854 static const value_string parameter_tag_values[] = {
1855 { INFO_STRING_PARAMETER_TAG, "Info String" },
1856 { ROUTING_CONTEXT_PARAMETER_TAG, "Routing context" },
1857 { DIAGNOSTIC_INFO_PARAMETER_TAG, "Diagnostic info" },
1858 { HEARTBEAT_DATA_PARAMETER_TAG, "Heartbeat data" },
1859 { TRAFFIC_MODE_TYPE_PARAMETER_TAG, "Traffic mode type" },
1860 { ERROR_CODE_PARAMETER_TAG, "Error code" },
1861 { STATUS_PARAMETER_TAG, "Status" },
1862 { ASP_IDENTIFIER_PARAMETER_TAG, "ASP identifier" },
1863 { AFFECTED_POINT_CODE_PARAMETER_TAG, "Affected point code" },
1864 { CORRELATION_ID_PARAMETER_TAG, "Correlation ID" },
1865 { REGISTRATION_RESULT_PARAMETER_TAG, "Registration result" },
1866 { DEREGISTRATION_RESULT_PARAMETER_TAG, "Deregistration result" },
1867 { REGISTRATION_STATUS_PARAMETER_TAG, "Registration status" },
1868 { DEREGISTRATION_STATUS_PARAMETER_TAG, "Deregistration status" },
1869 { LOCAL_ROUTING_KEY_IDENTIFIER_PARAMETER_TAG, "Local routing key identifier" },
1870 { SS7_HOP_COUNTER_PARAMETER_TAG, "SS7 hop counter" },
1871 { SOURCE_ADDRESS_PARAMETER_TAG, "Source address" },
1872 { DESTINATION_ADDRESS_PARAMETER_TAG, "Destination address" },
1873 { SOURCE_REFERENCE_NUMBER_PARAMETER_TAG, "Source reference number" },
1874 { DESTINATION_REFERENCE_NUMBER_PARAMETER_TAG, "Destination reference number" },
1875 { SCCP_CAUSE_PARAMETER_TAG, "SCCP cause" },
1876 { SEQUENCE_NUMBER_PARAMETER_TAG, "Sequence number" },
1877 { RECEIVE_SEQUENCE_NUMBER_PARAMETER_TAG, "Receive sequence number" },
1878 { ASP_CAPABILITIES_PARAMETER_TAG, "ASP capabilities" },
1879 { CREDIT_PARAMETER_TAG, "Credit" },
1880 { DATA_PARAMETER_TAG, "Data" },
1881 { USER_CAUSE_PARAMETER_TAG, "User/Cause" },
1882 { NETWORK_APPEARANCE_PARAMETER_TAG, "Network appearance" },
1883 { ROUTING_KEY_PARAMETER_TAG, "Routing key" },
1884 { DRN_LABEL_PARAMETER_TAG, "DRN label" },
1885 { TID_LABEL_PARAMETER_TAG, "TID label" },
1886 { ADDRESS_RANGE_PARAMETER_TAG, "Address range" },
1887 { SMI_PARAMETER_TAG, "SMI" },
1888 { IMPORTANCE_PARAMETER_TAG, "Importance" },
1889 { MESSAGE_PRIORITY_PARAMETER_TAG, "Message priority" },
1890 { PROTOCOL_CLASS_PARAMETER_TAG, "Protocol class" },
1891 { SEQUENCE_CONTROL_PARAMETER_TAG, "Sequence control" },
1892 { SEGMENTATION_PARAMETER_TAG, "Segmentation" },
1893 { CONGESTION_LEVEL_PARAMETER_TAG, "Congestion level" },
1894 { GLOBAL_TITLE_PARAMETER_TAG, "Global title" },
1895 { POINT_CODE_PARAMETER_TAG, "Point code" },
1896 { SUBSYSTEM_NUMBER_PARAMETER_TAG, "Subsystem number" },
1897 { IPV4_ADDRESS_PARAMETER_TAG, "IPv4 address" },
1898 { HOSTNAME_PARAMETER_TAG, "Hostname" },
1899 { IPV6_ADDRESS_PARAMETER_TAG, "IPv6 address" },
1900 { 0, NULL } };
1902 static void
1903 // NOLINTNEXTLINE(misc-no-recursion)
1904 dissect_parameter(tvbuff_t *parameter_tvb, packet_info *pinfo, proto_tree *tree, tvbuff_t **data_tvb, uint8_t *source_ssn, uint8_t *dest_ssn)
1906 uint16_t tag, length, padding_length;
1907 proto_item *parameter_item;
1908 proto_tree *parameter_tree;
1909 uint8_t ssn = INVALID_SSN;
1910 const char *param_tag_str = NULL;
1912 /* Extract tag and length from the parameter */
1913 tag = tvb_get_ntohs(parameter_tvb, PARAMETER_TAG_OFFSET);
1914 length = tvb_get_ntohs(parameter_tvb, PARAMETER_LENGTH_OFFSET);
1915 padding_length = tvb_reported_length(parameter_tvb) - length;
1917 /* Create proto_tree stuff */
1918 /* If it's a known parameter it's present in the value_string.
1919 * If param_tag_str = NULL then this is an unknown parameter
1921 param_tag_str = try_val_to_str(tag, parameter_tag_values);
1922 if(param_tag_str) {
1923 /* The parameter exists */
1924 parameter_tree = proto_tree_add_subtree(tree, parameter_tvb, PARAMETER_HEADER_OFFSET, -1, ett_sua_parameter, &parameter_item, param_tag_str);
1925 } else {
1926 if(dissector_try_uint(sua_parameter_table, tag, parameter_tvb, pinfo,tree)) {
1927 return;
1930 parameter_tree = proto_tree_add_subtree(tree, parameter_tvb, PARAMETER_HEADER_OFFSET, -1, ett_sua_parameter, &parameter_item, "Unknown parameter");
1933 /* Add tag and length to the sua tree */
1934 proto_tree_add_item(parameter_tree, hf_sua_parameter_tag, parameter_tvb, PARAMETER_TAG_OFFSET, PARAMETER_TAG_LENGTH, ENC_BIG_ENDIAN);
1935 proto_tree_add_item(parameter_tree, hf_sua_parameter_length, parameter_tvb, PARAMETER_LENGTH_OFFSET, PARAMETER_LENGTH_LENGTH, ENC_BIG_ENDIAN);
1938 ** If no tree, only the data, ssn, PC, and GT parameters in the source and destination
1939 ** addresses need to be dissected. This in order to make dissection of the data
1940 ** possible and to allow us to set the source and destination addresses when there is
1941 ** no tree.
1943 if (!tree && tag != DATA_PARAMETER_TAG
1944 && tag != SOURCE_ADDRESS_PARAMETER_TAG
1945 && tag != DESTINATION_ADDRESS_PARAMETER_TAG
1946 && tag != POINT_CODE_PARAMETER_TAG
1947 && tag != GLOBAL_TITLE_PARAMETER_TAG
1948 && tag != DESTINATION_REFERENCE_NUMBER_PARAMETER_TAG
1949 && tag != SOURCE_REFERENCE_NUMBER_PARAMETER_TAG
1950 && tag != SUBSYSTEM_NUMBER_PARAMETER_TAG)
1951 return; /* Nothing to do here */
1953 increment_dissection_depth(pinfo);
1954 switch(tag) {
1955 case DATA_PARAMETER_TAG:
1956 dissect_data_parameter(parameter_tvb, parameter_tree, parameter_item, data_tvb);
1957 break;
1958 case INFO_STRING_PARAMETER_TAG:
1959 dissect_info_string_parameter(parameter_tvb, pinfo, parameter_tree, parameter_item);
1960 break;
1961 case ROUTING_CONTEXT_PARAMETER_TAG:
1962 dissect_routing_context_parameter(parameter_tvb, parameter_tree, parameter_item);
1963 break;
1964 case DIAGNOSTIC_INFO_PARAMETER_TAG:
1965 dissect_diagnostic_information_parameter(parameter_tvb, parameter_tree, parameter_item);
1966 break;
1967 case HEARTBEAT_DATA_PARAMETER_TAG:
1968 dissect_heartbeat_data_parameter(parameter_tvb, parameter_tree, parameter_item);
1969 break;
1970 case TRAFFIC_MODE_TYPE_PARAMETER_TAG:
1971 dissect_traffic_mode_type_parameter(parameter_tvb, parameter_tree, parameter_item);
1972 break;
1973 case ERROR_CODE_PARAMETER_TAG:
1974 dissect_error_code_parameter(parameter_tvb, parameter_tree, parameter_item);
1975 break;
1976 case STATUS_PARAMETER_TAG:
1977 dissect_status_type_parameter(parameter_tvb, parameter_tree, parameter_item);
1978 break;
1979 case CONGESTION_LEVEL_PARAMETER_TAG:
1980 dissect_congestion_level_parameter(parameter_tvb, parameter_tree, parameter_item);
1981 break;
1982 case ASP_IDENTIFIER_PARAMETER_TAG:
1983 dissect_asp_identifier_parameter(parameter_tvb, parameter_tree, parameter_item);
1984 break;
1985 case AFFECTED_POINT_CODE_PARAMETER_TAG:
1986 dissect_affected_destinations_parameter(parameter_tvb, parameter_tree, parameter_item);
1987 break;
1988 case REGISTRATION_STATUS_PARAMETER_TAG:
1989 dissect_registration_status_parameter(parameter_tvb, parameter_tree, parameter_item);
1990 break;
1991 case DEREGISTRATION_STATUS_PARAMETER_TAG:
1992 dissect_deregistration_status_parameter(parameter_tvb, parameter_tree, parameter_item);
1993 break;
1994 case LOCAL_ROUTING_KEY_IDENTIFIER_PARAMETER_TAG:
1995 dissect_local_routing_key_identifier_parameter(parameter_tvb, parameter_tree, parameter_item);
1996 break;
1997 case SS7_HOP_COUNTER_PARAMETER_TAG:
1998 dissect_ss7_hop_counter_parameter(parameter_tvb, parameter_tree, parameter_item);
1999 break;
2000 case SOURCE_ADDRESS_PARAMETER_TAG:
2001 dissect_source_address_parameter(parameter_tvb, pinfo, parameter_tree, source_ssn);
2002 break;
2003 case DESTINATION_ADDRESS_PARAMETER_TAG:
2004 dissect_destination_address_parameter(parameter_tvb, pinfo, parameter_tree, dest_ssn);
2005 break;
2006 case SOURCE_REFERENCE_NUMBER_PARAMETER_TAG:
2007 dissect_source_reference_number_parameter(parameter_tvb, parameter_tree, parameter_item);
2008 break;
2009 case DESTINATION_REFERENCE_NUMBER_PARAMETER_TAG:
2010 dissect_destination_reference_number_parameter(parameter_tvb, parameter_tree, parameter_item);
2011 break;
2012 case SCCP_CAUSE_PARAMETER_TAG:
2013 dissect_sccp_cause_parameter(parameter_tvb, parameter_tree, parameter_item);
2014 break;
2015 case SEQUENCE_NUMBER_PARAMETER_TAG:
2016 dissect_sequence_number_parameter(parameter_tvb, parameter_tree);
2017 break;
2018 case RECEIVE_SEQUENCE_NUMBER_PARAMETER_TAG:
2019 dissect_receive_sequence_number_parameter(parameter_tvb, parameter_tree);
2020 break;
2021 case ASP_CAPABILITIES_PARAMETER_TAG:
2022 dissect_asp_capabilities_parameter(parameter_tvb, parameter_tree);
2023 break;
2024 case CREDIT_PARAMETER_TAG:
2025 dissect_credit_parameter(parameter_tvb, parameter_tree, parameter_item);
2026 break;
2027 case USER_CAUSE_PARAMETER_TAG:
2028 dissect_user_cause_parameter(parameter_tvb, parameter_tree);
2029 break;
2030 case NETWORK_APPEARANCE_PARAMETER_TAG:
2031 dissect_network_appearance_parameter(parameter_tvb, parameter_tree, parameter_item);
2032 break;
2033 case ROUTING_KEY_PARAMETER_TAG:
2034 dissect_routing_key_parameter(parameter_tvb, pinfo, parameter_tree);
2035 break;
2036 case REGISTRATION_RESULT_PARAMETER_TAG:
2037 dissect_registration_result_parameter(parameter_tvb, pinfo, parameter_tree);
2038 break;
2039 case DEREGISTRATION_RESULT_PARAMETER_TAG:
2040 dissect_deregistration_result_parameter(parameter_tvb, pinfo, parameter_tree);
2041 break;
2042 case ADDRESS_RANGE_PARAMETER_TAG:
2043 dissect_address_range_parameter(parameter_tvb, pinfo, parameter_tree);
2044 break;
2045 case CORRELATION_ID_PARAMETER_TAG:
2046 dissect_correlation_id_parameter(parameter_tvb, parameter_tree, parameter_item);
2047 break;
2048 case IMPORTANCE_PARAMETER_TAG:
2049 dissect_importance_parameter(parameter_tvb, parameter_tree, parameter_item);
2050 break;
2051 case MESSAGE_PRIORITY_PARAMETER_TAG:
2052 dissect_message_priority_parameter(parameter_tvb, parameter_tree, parameter_item);
2053 break;
2054 case PROTOCOL_CLASS_PARAMETER_TAG:
2055 dissect_protocol_class_parameter(parameter_tvb, parameter_tree, parameter_item);
2056 break;
2057 case SEQUENCE_CONTROL_PARAMETER_TAG:
2058 dissect_sequence_control_parameter(parameter_tvb, parameter_tree, parameter_item);
2059 break;
2060 case SEGMENTATION_PARAMETER_TAG:
2061 dissect_segmentation_parameter(parameter_tvb, parameter_tree);
2062 break;
2063 case SMI_PARAMETER_TAG:
2064 dissect_smi_parameter(parameter_tvb, parameter_tree, parameter_item);
2065 break;
2066 case TID_LABEL_PARAMETER_TAG:
2067 dissect_tid_label_parameter(parameter_tvb, parameter_tree);
2068 break;
2069 case DRN_LABEL_PARAMETER_TAG:
2070 dissect_drn_label_parameter(parameter_tvb, parameter_tree);
2071 break;
2072 case GLOBAL_TITLE_PARAMETER_TAG:
2073 /* Reuse whether we have source_ssn or not to determine which address we're looking at */
2074 dissect_global_title_parameter(parameter_tvb, parameter_tree, (source_ssn != NULL));
2075 break;
2076 case POINT_CODE_PARAMETER_TAG:
2077 /* Reuse whether we have source_ssn or not to determine which address we're looking at */
2078 dissect_point_code_parameter(parameter_tvb, parameter_tree, parameter_item, (source_ssn != NULL));
2079 break;
2080 case SUBSYSTEM_NUMBER_PARAMETER_TAG:
2081 /* Reuse whether we have source_ssn or not to determine which address we're looking at */
2082 dissect_ssn_parameter(parameter_tvb, parameter_tree, parameter_item, &ssn, (source_ssn != NULL));
2083 if(source_ssn)
2085 *source_ssn = ssn;
2087 if(dest_ssn)
2089 *dest_ssn = ssn;
2091 break;
2092 case IPV4_ADDRESS_PARAMETER_TAG:
2093 /* Reuse whether we have source_ssn or not to determine which address we're looking at */
2094 dissect_ipv4_parameter(parameter_tvb, parameter_tree, parameter_item, (source_ssn != NULL));
2095 break;
2096 case HOSTNAME_PARAMETER_TAG:
2097 /* Reuse whether we have source_ssn or not to determine which address we're looking at */
2098 dissect_hostname_parameter(parameter_tvb, parameter_tree, parameter_item, (source_ssn != NULL));
2099 break;
2100 case IPV6_ADDRESS_PARAMETER_TAG:
2101 /* Reuse whether we have source_ssn or not to determine which address we're looking at */
2102 dissect_ipv6_parameter(parameter_tvb, parameter_tree, parameter_item, (source_ssn != NULL));
2103 break;
2104 default:
2105 dissect_unknown_parameter(parameter_tvb, parameter_tree, parameter_item);
2106 break;
2108 decrement_dissection_depth(pinfo);
2110 if (parameter_tree && (padding_length > 0))
2111 proto_tree_add_item(parameter_tree, hf_sua_parameter_padding, parameter_tvb, PARAMETER_HEADER_OFFSET + length, padding_length, ENC_NA);
2114 static void
2115 // NOLINTNEXTLINE(misc-no-recursion)
2116 dissect_parameters(tvbuff_t *parameters_tvb, packet_info *pinfo, proto_tree *tree, tvbuff_t **data_tvb, uint8_t *source_ssn, uint8_t *dest_ssn)
2118 int offset, length, total_length, remaining_length;
2119 tvbuff_t *parameter_tvb;
2121 offset = 0;
2122 while((remaining_length = tvb_reported_length_remaining(parameters_tvb, offset))) {
2123 length = tvb_get_ntohs(parameters_tvb, offset + PARAMETER_LENGTH_OFFSET);
2124 total_length = WS_ROUNDUP_4(length);
2125 if (remaining_length >= length)
2126 total_length = MIN(total_length, remaining_length);
2127 /* create a tvb for the parameter including the padding bytes */
2128 parameter_tvb = tvb_new_subset_length(parameters_tvb, offset, total_length);
2129 switch(version) {
2130 case SUA_V08:
2131 dissect_v8_parameter(parameter_tvb, pinfo, tree, data_tvb, source_ssn, dest_ssn);
2132 break;
2133 case SUA_RFC:
2134 dissect_parameter(parameter_tvb, pinfo, tree, data_tvb, source_ssn, dest_ssn);
2135 break;
2137 /* get rid of the handled parameter */
2138 offset += total_length;
2142 static void
2143 dissect_sua_message(tvbuff_t *message_tvb, packet_info *pinfo, proto_tree *sua_tree, proto_tree *tree)
2145 tvbuff_t *common_header_tvb;
2146 tvbuff_t *parameters_tvb;
2147 tvbuff_t *data_tvb = NULL;
2149 heur_dtbl_entry_t *hdtbl_entry;
2150 #if 0
2151 proto_tree *assoc_tree;
2152 #endif
2153 uint8_t source_ssn = INVALID_SSN;
2154 uint8_t dest_ssn = INVALID_SSN;
2155 proto_item *assoc_item;
2156 struct _sccp_msg_info_t* sccp_info = NULL;
2158 message_class = 0;
2159 message_type = 0;
2160 drn = 0;
2161 srn = 0;
2163 assoc = NULL;
2164 no_sua_assoc.calling_dpc = 0;
2165 no_sua_assoc.called_dpc = 0;
2166 no_sua_assoc.calling_ssn = INVALID_SSN;
2167 no_sua_assoc.called_ssn = INVALID_SSN;
2168 no_sua_assoc.has_bw_key = false;
2169 no_sua_assoc.has_fw_key = false;
2171 sua_opc = wmem_new0(pinfo->pool, mtp3_addr_pc_t);
2172 sua_dpc = wmem_new0(pinfo->pool, mtp3_addr_pc_t);
2173 sua_source_gt = NULL;
2174 sua_destination_gt = NULL;
2176 common_header_tvb = tvb_new_subset_length(message_tvb, COMMON_HEADER_OFFSET, COMMON_HEADER_LENGTH);
2177 dissect_common_header(common_header_tvb, pinfo, sua_tree);
2179 parameters_tvb = tvb_new_subset_remaining(message_tvb, COMMON_HEADER_LENGTH);
2180 dissect_parameters(parameters_tvb, pinfo, sua_tree, &data_tvb, &source_ssn, &dest_ssn);
2184 if (message_class == MESSAGE_CLASS_CO_MESSAGE) {
2185 /* XXX: this might fail with multihomed SCTP (on a path failure during a call)
2186 * or with "load sharing"?
2188 sccp_assoc_info_t* sccp_assoc;
2189 sccp_decode_context_t sccp_decode;
2190 /* sua assoc */
2192 switch (message_type) {
2193 case MESSAGE_TYPE_CORE:
2194 assoc = sua_assoc(pinfo,&(pinfo->src),&(pinfo->dst), srn , drn);
2195 if(assoc) {
2196 assoc->calling_routing_ind = sua_ri;
2197 assoc->calling_ssn = source_ssn;
2198 assoc->called_ssn = dest_ssn;
2200 break;
2201 case MESSAGE_TYPE_COAK:
2202 assoc = sua_assoc(pinfo,&(pinfo->src),&(pinfo->dst), srn , drn);
2203 if(assoc) {
2204 assoc->called_routing_ind = sua_ri;
2205 if( (assoc->called_ssn != INVALID_SSN)&& (dest_ssn != INVALID_SSN)) {
2206 assoc->called_ssn = dest_ssn;
2209 break;
2210 default :
2211 assoc = sua_assoc(pinfo,&(pinfo->src),&(pinfo->dst), srn , drn);
2214 switch (message_type) {
2215 case MESSAGE_TYPE_CORE:
2216 case MESSAGE_TYPE_COAK:
2217 break;
2218 default:
2219 if((assoc && assoc->called_ssn != INVALID_SSN)&& (dest_ssn != INVALID_SSN)) {
2220 dest_ssn = assoc->called_ssn;
2222 if((assoc && assoc->calling_ssn != INVALID_SSN)&& (source_ssn != INVALID_SSN)) {
2223 source_ssn = assoc->calling_ssn;
2227 if (assoc && assoc->assoc_id !=0) {
2228 assoc_item = proto_tree_add_uint(tree, hf_sua_assoc_id, message_tvb, 0, 0, assoc->assoc_id);
2229 proto_item_set_generated(assoc_item);
2230 #if 0
2231 assoc_tree = proto_item_add_subtree(assoc_item, ett_sua_assoc);
2232 proto_tree_add_debug_text(assoc_tree, message_tvb, 0, 0, "routing_ind %u", assoc->calling_routing_ind);
2233 proto_tree_add_debug_text(assoc_tree, message_tvb, 0, 0, "routing_ind %u", assoc->called_routing_ind);
2234 proto_tree_add_debug_text(assoc_tree, message_tvb, 0, 0, "calling_ssn %u", assoc->calling_ssn);
2235 proto_tree_add_debug_text(assoc_tree, message_tvb, 0, 0, "called_ssn %u", assoc->called_ssn);
2236 #endif /* 0 */
2239 sccp_decode.message_type = message_type;
2240 sccp_decode.dlr = drn;
2241 sccp_decode.slr = srn;
2242 sccp_decode.assoc = NULL;
2243 sccp_decode.sccp_msg = NULL; /* Unused, but initialized */
2245 sccp_assoc = get_sccp_assoc(pinfo, tvb_offset_from_real_beginning(message_tvb), &sccp_decode);
2246 if (sccp_assoc && sccp_assoc->curr_msg) {
2247 sccp_info = sccp_assoc->curr_msg;
2248 tap_queue_packet(sua_tap,pinfo,sccp_assoc->curr_msg);
2252 if (set_addresses) {
2253 if (sua_opc->type)
2254 set_address(&pinfo->src, ss7pc_address_type, sizeof(mtp3_addr_pc_t), (uint8_t *) sua_opc);
2255 if (sua_dpc->type)
2256 set_address(&pinfo->dst, ss7pc_address_type, sizeof(mtp3_addr_pc_t), (uint8_t *) sua_dpc);
2258 if (sua_source_gt)
2259 set_address(&pinfo->src, AT_STRINGZ, 1+(int)strlen(sua_source_gt), wmem_strdup(pinfo->pool, sua_source_gt));
2260 if (sua_destination_gt)
2261 set_address(&pinfo->dst, AT_STRINGZ, 1+(int)strlen(sua_destination_gt), wmem_strdup(pinfo->pool, sua_destination_gt));
2264 /* If there was SUA data it could be dissected */
2265 if(data_tvb)
2267 /* Try subdissectors (if we found a valid SSN on the current message) */
2268 if ((dest_ssn == INVALID_SSN ||
2269 !dissector_try_uint_with_data(sccp_ssn_dissector_table, dest_ssn, data_tvb, pinfo, tree, true, sccp_info))
2270 && (source_ssn == INVALID_SSN ||
2271 !dissector_try_uint_with_data(sccp_ssn_dissector_table, source_ssn, data_tvb, pinfo, tree, true, sccp_info)))
2273 /* try heuristic subdissector list to see if there are any takers */
2274 if (dissector_try_heuristic(heur_subdissector_list, data_tvb, pinfo, tree, &hdtbl_entry, sccp_info)) {
2275 return;
2277 /* No sub-dissection occurred, treat it as raw data */
2278 call_data_dissector(data_tvb, pinfo, tree);
2283 static int
2284 dissect_sua(tvbuff_t *message_tvb, packet_info *pinfo, proto_tree *tree, void* data _U_)
2286 proto_item *sua_item;
2287 proto_tree *sua_tree;
2289 /* make entry in the Protocol column on summary display */
2291 switch (version) {
2292 case SUA_V08:
2293 col_set_str(pinfo->cinfo, COL_PROTOCOL, "SUA (ID 08)");
2294 break;
2295 case SUA_RFC:
2296 col_set_str(pinfo->cinfo, COL_PROTOCOL, "SUA (RFC 3868)");
2297 break;
2300 /* Clear entries in Info column on summary display */
2301 col_clear(pinfo->cinfo, COL_INFO);
2303 /* create the sua protocol tree */
2304 sua_item = proto_tree_add_item(tree, proto_sua, message_tvb, 0, -1, ENC_NA);
2305 sua_tree = proto_item_add_subtree(sua_item, ett_sua);
2307 /* dissect the message */
2308 dissect_sua_message(message_tvb, pinfo, sua_tree, tree);
2309 return tvb_captured_length(message_tvb);
2312 /* Register the protocol with Wireshark */
2313 void
2314 proto_register_sua(void)
2317 /* Setup list of header fields */
2318 static hf_register_info hf[] = {
2319 { &hf_sua_version, { "Version", "sua.version", FT_UINT8, BASE_DEC, VALS(protocol_version_values), 0x0, NULL, HFILL } },
2320 { &hf_sua_reserved, { "Reserved", "sua.reserved", FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL } },
2321 { &hf_sua_message_class, { "Message Class", "sua.message_class", FT_UINT8, BASE_DEC, VALS(message_class_values), 0x0, NULL, HFILL } },
2322 { &hf_sua_message_type, { "Message Type", "sua.message_type", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL } },
2323 { &hf_sua_message_length, { "Message Length", "sua.message_length", FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL } },
2324 { &hf_sua_parameter_tag, { "Parameter Tag", "sua.parameter_tag", FT_UINT16, BASE_HEX, VALS(parameter_tag_values), 0x0, NULL, HFILL } },
2325 { &hf_sua_v8_parameter_tag, { "Parameter Tag", "sua.parameter_tag", FT_UINT16, BASE_HEX, VALS(v8_parameter_tag_values), 0x0, NULL, HFILL } },
2326 { &hf_sua_parameter_length, { "Parameter Length", "sua.parameter_length", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL } },
2327 { &hf_sua_parameter_value, { "Parameter Value", "sua.parameter_value", FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL } },
2328 { &hf_sua_parameter_padding, { "Padding", "sua.parameter_padding", FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL } },
2329 { &hf_sua_info_string, { "Info string", "sua.info_string", FT_STRING, BASE_NONE, NULL, 0x0, NULL, HFILL } },
2330 { &hf_sua_routing_context, { "Routing context", "sua.routing_context", FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL } },
2331 { &hf_sua_diagnostic_information_info, { "Diagnostic Information", "sua.diagnostic_information", FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL } },
2332 { &hf_sua_heartbeat_data, { "Heartbeat Data", "sua.heartbeat_data", FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL } },
2333 { &hf_sua_traffic_mode_type, { "Traffic mode Type", "sua.traffic_mode_type", FT_UINT32, BASE_DEC, VALS(traffic_mode_type_values), 0x0, NULL, HFILL } },
2334 { &hf_sua_error_code, { "Error code", "sua.error_code", FT_UINT32, BASE_DEC, VALS(error_code_values), 0x0, NULL, HFILL } },
2335 { &hf_sua_v8_error_code, { "Error code", "sua.error_code", FT_UINT32, BASE_DEC, VALS(v8_error_code_values), 0x0, NULL, HFILL } },
2336 { &hf_sua_status_type, { "Status type", "sua.status_type", FT_UINT16, BASE_DEC, VALS(status_type_values), 0x0, NULL, HFILL } },
2337 { &hf_sua_status_info, { "Status info", "sua.status_info", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL } },
2338 { &hf_sua_congestion_level, { "Congestion Level", "sua.congestion_level", FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL } },
2339 { &hf_sua_asp_identifier, { "ASP Identifier", "sua.asp_identifier", FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL } },
2340 { &hf_sua_mask, { "Mask", "sua.affected_point_code_mask", FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL } },
2341 { &hf_sua_dpc, { "Affected DPC", "sua.affected_pointcode_dpc", FT_UINT24, BASE_DEC, NULL, 0x0, NULL, HFILL } },
2342 { &hf_sua_registration_status, { "Registration status", "sua.registration_status", FT_UINT32, BASE_DEC, VALS(registration_status_values), 0x0, NULL, HFILL } },
2343 { &hf_sua_deregistration_status, { "Deregistration status", "sua.deregistration_status", FT_UINT32, BASE_DEC, VALS(deregistration_status_values), 0x0, NULL, HFILL } },
2344 { &hf_sua_local_routing_key_identifier, { "Local routing key identifier", "sua.local_routing_key_identifier", FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL } },
2346 { &hf_sua_source_address_routing_indicator, { "Source Routing Indicator", "sua.source.routing_indicator", FT_UINT16, BASE_DEC, VALS(routing_indicator_values), 0x0, NULL, HFILL } },
2347 { &hf_sua_source_address_reserved_bits, { "Source Reserved Bits", "sua.source.reserved_bits", FT_UINT16, BASE_DEC, NULL, ADDRESS_RESERVED_BITMASK, NULL, HFILL } },
2348 { &hf_sua_source_address_gt_bit, { "Source Include GT", "sua.source.gt_bit", FT_BOOLEAN, 16, NULL, ADDRESS_GT_BITMASK, NULL, HFILL } },
2349 { &hf_sua_source_address_pc_bit, { "Source Include PC", "sua.source.pc_bit", FT_BOOLEAN, 16, NULL, ADDRESS_PC_BITMASK, NULL, HFILL } },
2350 { &hf_sua_source_address_ssn_bit, { "Source Include SSN", "sua.source.ssn_bit", FT_BOOLEAN, 16, NULL, ADDRESS_SSN_BITMASK, NULL, HFILL } },
2351 { &hf_sua_source_gt_reserved, { "Source Reserved", "sua.source.gt_reserved", FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL } },
2352 { &hf_sua_source_gti, { "Source GTI", "sua.source.gti", FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL } },
2353 { &hf_sua_source_number_of_digits, { "Source Number of Digits", "sua.source.global_title_number_of_digits", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL } },
2354 { &hf_sua_source_translation_type, { "Source Translation Type", "sua.source.global_title_translation_type", FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL } },
2355 { &hf_sua_source_numbering_plan, { "Source Numbering Plan", "sua.source.global_title_numbering_plan", FT_UINT8, BASE_HEX, VALS(numbering_plan_values), 0x0, NULL, HFILL } },
2356 { &hf_sua_source_nature_of_address, { "Source Nature of Address", "sua.source.global_title_nature_of_address", FT_UINT8, BASE_HEX, VALS(nature_of_address_values), 0x0, NULL, HFILL } },
2357 { &hf_sua_source_global_title_digits, { "Source Global Title Digits", "sua.source.global_title_digits", FT_STRING, BASE_NONE, NULL, 0x0, NULL, HFILL } },
2358 { &hf_sua_source_point_code, { "Source Point Code", "sua.source.point_code", FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL } },
2359 { &hf_sua_source_ssn_reserved, { "Source Reserved", "sua.source.ssn_reserved", FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL } },
2360 { &hf_sua_source_ssn_number, { "Source Subsystem Number", "sua.source.ssn", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL } },
2361 { &hf_sua_source_ipv4, { "Source IP Version 4 address", "sua.source.ipv4_address", FT_IPv4, BASE_NONE, NULL, 0x0, NULL, HFILL } },
2362 { &hf_sua_source_hostname, { "Source Hostname", "sua.source.hostname.name", FT_STRING, BASE_NONE, NULL, 0x0, NULL, HFILL } },
2363 { &hf_sua_source_ipv6, { "Source IP Version 6 address", "sua.source.ipv6_address", FT_IPv6, BASE_NONE, NULL, 0x0, NULL, HFILL } },
2365 { &hf_sua_destination_address_routing_indicator, { "Destination Routing Indicator","sua.destination.routing_indicator", FT_UINT16, BASE_DEC, VALS(routing_indicator_values), 0x0, NULL, HFILL } },
2366 { &hf_sua_destination_address_reserved_bits, { "Destination Reserved Bits", "sua.destination.reserved_bits", FT_UINT16, BASE_DEC, NULL, ADDRESS_RESERVED_BITMASK, NULL, HFILL } },
2367 { &hf_sua_destination_address_gt_bit, { "Destination Include GT", "sua.destination.gt_bit", FT_BOOLEAN, 16, NULL, ADDRESS_GT_BITMASK, NULL, HFILL } },
2368 { &hf_sua_destination_address_pc_bit, { "Destination Include PC", "sua.destination.pc_bit", FT_BOOLEAN, 16, NULL, ADDRESS_PC_BITMASK, NULL, HFILL } },
2369 { &hf_sua_destination_address_ssn_bit, { "Destination Include SSN", "sua.destination.ssn_bit", FT_BOOLEAN, 16, NULL, ADDRESS_SSN_BITMASK, NULL, HFILL } },
2370 { &hf_sua_dest_gt_reserved, { "Destination Reserved", "sua.destination.gt_reserved", FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL } },
2371 { &hf_sua_dest_gti, { "Destination GTI", "sua.destination.gti", FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL } },
2372 { &hf_sua_dest_number_of_digits, { "Destination Number of Digits", "sua.destination.global_title_number_of_digits", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL } },
2373 { &hf_sua_dest_translation_type, { "Destination Translation Type", "sua.destination.global_title_translation_type", FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL } },
2374 { &hf_sua_dest_numbering_plan, { "Destination Numbering Plan", "sua.destination.global_title_numbering_plan", FT_UINT8, BASE_HEX, VALS(numbering_plan_values), 0x0, NULL, HFILL } },
2375 { &hf_sua_dest_nature_of_address, { "Destination Nature of Address","sua.destination.global_title_nature_of_address",FT_UINT8, BASE_HEX, VALS(nature_of_address_values), 0x0, NULL, HFILL } },
2376 { &hf_sua_dest_global_title_digits, { "Destination Global Title Digits","sua.destination.global_title_digits", FT_STRING, BASE_NONE, NULL, 0x0, NULL, HFILL } },
2377 { &hf_sua_dest_point_code, { "Destination Point Code", "sua.destination.point_code", FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL } },
2378 { &hf_sua_dest_ssn_reserved, { "Destination Reserved", "sua.destination.ssn_reserved", FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL } },
2379 { &hf_sua_dest_ssn_number, { "Destination Subsystem Number", "sua.destination.ssn", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL } },
2380 { &hf_sua_dest_ipv4, { "Destination IPv4 address", "sua.destination.ipv4_address", FT_IPv4, BASE_NONE, NULL, 0x0, NULL, HFILL } },
2381 { &hf_sua_dest_hostname, { "Destination Hostname", "sua.destination.hostname.name", FT_STRING, BASE_NONE, NULL, 0x0, NULL, HFILL } },
2382 { &hf_sua_dest_ipv6, { "Destination IPv6 address", "sua.destination.ipv6_address", FT_IPv6, BASE_NONE, NULL, 0x0, NULL, HFILL } },
2384 { &hf_sua_ss7_hop_counter_counter, { "SS7 Hop Counter", "sua.ss7_hop_counter_counter", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL } },
2385 { &hf_sua_ss7_hop_counter_reserved, { "Reserved", "sua.ss7_hop_counter_reserved", FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL } },
2386 { &hf_sua_destination_reference_number, { "Destination Reference Number", "sua.destination_reference_number", FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL } },
2387 { &hf_sua_source_reference_number, { "Source Reference Number", "sua.source_reference_number", FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL } },
2388 { &hf_sua_cause_reserved, { "Reserved", "sua.sccp_cause_reserved", FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL } },
2389 { &hf_sua_cause_type, { "Cause Type", "sua.sccp_cause_type", FT_UINT8, BASE_HEX, VALS(cause_type_values), 0x0, NULL, HFILL } },
2390 { &hf_sua_cause_value, { "Cause Value", "sua.sccp_cause_value", FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL } },
2391 { &hf_sua_sequence_number_reserved, { "Reserved", "sua.sequence_number_reserved", FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL } },
2392 { &hf_sua_sequence_number_rec_number, { "Receive Sequence Number P(R)", "sua.sequence_number_receive_sequence_number", FT_UINT8, BASE_DEC, NULL, SEQ_NUM_MASK, NULL, HFILL } },
2393 { &hf_sua_sequence_number_more_data_bit, { "More Data Bit", "sua.sequence_number_more_data_bit", FT_BOOLEAN, 8, TFS(&more_data_bit_value), MORE_DATA_BIT_MASK, NULL, HFILL } },
2394 { &hf_sua_sequence_number_sent_number, { "Sent Sequence Number P(S)", "sua.sequence_number_sent_sequence_number", FT_UINT8, BASE_DEC, NULL, SEQ_NUM_MASK, NULL, HFILL } },
2395 { &hf_sua_sequence_number_spare_bit, { "Spare Bit", "sua.sequence_number_spare_bit", FT_UINT8, BASE_DEC, NULL, SPARE_BIT_MASK, NULL, HFILL } },
2396 { &hf_sua_receive_sequence_number_reserved, { "Reserved", "sua.receive_sequence_number_reserved", FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL } },
2397 { &hf_sua_receive_sequence_number_number, { "Receive Sequence Number P(R)", "sua.receive_sequence_number_number", FT_UINT8, BASE_DEC, NULL, SEQ_NUM_MASK, NULL, HFILL } },
2398 { &hf_sua_receive_sequence_number_spare_bit, { "Spare Bit", "sua.receive_sequence_number_spare_bit", FT_UINT8, BASE_DEC, NULL, SPARE_BIT_MASK, NULL, HFILL } },
2399 { &hf_sua_asp_capabilities_reserved, { "Reserved", "sua.asp_capabilities_reserved", FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL } },
2400 { &hf_sua_protocol_classes, { "Protocol classes", "sua.protocol_classes", FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL } },
2401 { &hf_sua_protocol_class_flags, { "Protocol class", "sua.protocol_class_flags", FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL } },
2402 { &hf_sua_asp_capabilities_reserved_bits, { "Reserved Bits", "sua.asp_capabilities_reserved_bits", FT_UINT8, BASE_HEX, NULL, RESERVED_BITS_MASK, NULL, HFILL } },
2403 { &hf_sua_asp_capabilities_a_bit, { "Protocol Class 3", "sua.asp_capabilities_a_bit", FT_BOOLEAN, 8, TFS(&tfs_supported_not_supported), A_BIT_MASK, NULL, HFILL } },
2404 { &hf_sua_asp_capabilities_b_bit, { "Protocol Class 2", "sua.asp_capabilities_b_bit", FT_BOOLEAN, 8, TFS(&tfs_supported_not_supported), B_BIT_MASK, NULL, HFILL } },
2405 { &hf_sua_asp_capabilities_c_bit, { "Protocol Class 1", "sua.asp_capabilities_c_bit", FT_BOOLEAN, 8, TFS(&tfs_supported_not_supported), C_BIT_MASK, NULL, HFILL } },
2406 { &hf_sua_asp_capabilities_d_bit, { "Protocol Class 0", "sua.asp_capabilities_d_bit", FT_BOOLEAN, 8, TFS(&tfs_supported_not_supported), D_BIT_MASK, NULL, HFILL } },
2407 { &hf_sua_asp_capabilities_interworking, { "Interworking", "sua.asp_capabilities_interworking", FT_UINT8, BASE_HEX, VALS(interworking_values), 0x0, NULL, HFILL } },
2408 { &hf_sua_credit, { "Credit", "sua.credit", FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL } },
2409 { &hf_sua_cause, { "Cause", "sua.cause_user_cause", FT_UINT16, BASE_DEC, VALS(cause_values), 0x0, NULL, HFILL } },
2410 { &hf_sua_user, { "User", "sua.cause_user_user", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL } },
2411 { &hf_sua_data, { "Data", "sua.data", FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL } },
2412 { &hf_sua_network_appearance, { "Network Appearance", "sua.network_appearance", FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL } },
2413 { &hf_sua_correlation_id, { "Correlation ID", "sua.correlation_id", FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL } },
2414 { &hf_sua_importance_reserved, { "Reserved", "sua.importance_reserved", FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL } },
2415 { &hf_sua_importance, { "Importance", "sua.importance_importance", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL } },
2416 { &hf_sua_message_priority_reserved, { "Reserved", "sua.message_priority_reserved", FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL } },
2417 { &hf_sua_message_priority, { "Message Priority", "sua.message_priority_priority", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL } },
2418 { &hf_sua_protocol_class_reserved, { "Reserved", "sua.protocol_class_reserved", FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL } },
2419 { &hf_sua_return_on_error_bit, { "Return On Error Bit", "sua.protocol_class_return_on_error_bit", FT_BOOLEAN, 8, TFS(&return_on_error_bit_value), RETURN_ON_ERROR_BIT_MASK, NULL, HFILL } },
2420 { &hf_sua_protocol_class, { "Protocol Class", "sua.protocol_class_class", FT_UINT8, BASE_DEC, NULL, PROTOCOL_CLASS_MASK, NULL, HFILL } },
2421 { &hf_sua_sequence_control, { "Sequence Control", "sua.sequence_control_sequence_control", FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL } },
2422 { &hf_sua_first_remaining, { "First / Remaining", "sua.first_remaining", FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL } },
2423 { &hf_sua_first_bit, { "First Segment Bit", "sua.segmentation_first_bit", FT_BOOLEAN, 8, TFS(&first_bit_value), FIRST_BIT_MASK, NULL, HFILL } },
2424 { &hf_sua_number_of_remaining_segments, { "Number of Remaining Segments", "sua.segmentation_number_of_remaining_segments", FT_UINT8, BASE_DEC, NULL, NUMBER_OF_SEGMENTS_MASK, NULL, HFILL } },
2425 { &hf_sua_segmentation_reference, { "Segmentation Reference", "sua.segmentation_reference", FT_UINT24, BASE_DEC, NULL, 0x0, NULL, HFILL } },
2426 { &hf_sua_smi_reserved, { "Reserved", "sua.smi_reserved", FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL } },
2427 { &hf_sua_smi, { "SMI", "sua.smi_smi", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL } },
2428 { &hf_sua_tid_label_start, { "Start", "sua.tid_label_start", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL } },
2429 { &hf_sua_tid_label_end, { "End", "sua.tid_label_end", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL } },
2430 { &hf_sua_tid_label_value, { "Label Value", "sua.tid_label_value", FT_UINT16, BASE_HEX, NULL, 0x0, NULL, HFILL } },
2431 { &hf_sua_drn_label_start, { "Start", "sua.drn_label_start", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL } },
2432 { &hf_sua_drn_label_end, { "End", "sua.drn_label_end", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL } },
2433 { &hf_sua_drn_label_value, { "Label Value", "sua.drn_label_value", FT_UINT16, BASE_HEX, NULL, 0x0, NULL, HFILL } },
2435 { &hf_sua_assoc_id, { "Association ID", "sua.assoc.id", FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL}},
2438 /* Setup protocol subtree array */
2439 static int *ett[] = {
2440 &ett_sua,
2441 &ett_sua_parameter,
2442 &ett_sua_source_address_indicator,
2443 &ett_sua_destination_address_indicator,
2444 &ett_sua_affected_destination,
2445 &ett_sua_sequence_number_rec_number,
2446 &ett_sua_sequence_number_sent_number,
2447 &ett_sua_receive_sequence_number_number,
2448 &ett_sua_protocol_classes,
2449 &ett_sua_first_remaining,
2450 &ett_sua_return_on_error_bit_and_protocol_class,
2451 &ett_sua_assoc
2455 module_t *sua_module;
2457 static const enum_val_t options[] = {
2458 { "draft-08", "Internet Draft version 08", SUA_V08 },
2459 { "rfc3868", "RFC 3868", SUA_RFC },
2460 { NULL, NULL, 0 }
2463 /* Register the protocol name and description */
2464 proto_sua = proto_register_protocol("SS7 SCCP-User Adaptation Layer", "SUA", "sua");
2465 sua_handle = register_dissector("sua", dissect_sua, proto_sua);
2467 /* Required function calls to register the header fields and subtrees used */
2468 proto_register_field_array(proto_sua, hf, array_length(hf));
2469 proto_register_subtree_array(ett, array_length(ett));
2471 sua_module = prefs_register_protocol(proto_sua, NULL);
2472 prefs_register_obsolete_preference(sua_module, "sua_version");
2473 prefs_register_enum_preference(sua_module, "version", "SUA Version", "Version used by Wireshark", &version, options, false);
2474 prefs_register_bool_preference(sua_module, "set_addresses", "Set source and destination addresses",
2475 "Set the source and destination addresses to the PC or GT digits, depending on the routing indicator."
2476 " This may affect TCAP's ability to recognize which messages belong to which TCAP session.", &set_addresses);
2478 heur_subdissector_list = register_heur_dissector_list_with_description("sua", "SUA Data fallback", proto_sua);
2479 sua_parameter_table = register_dissector_table("sua.prop.tags", "SUA Proprietary Tags", proto_sua, FT_UINT16, BASE_DEC);
2480 sua_tap = register_tap("sua");
2482 assocs = wmem_tree_new_autoreset(wmem_epan_scope(), wmem_file_scope());
2485 void
2486 proto_reg_handoff_sua(void)
2488 /* Do we have an info string dissector ? */
2489 sua_info_str_handle = find_dissector("sua.infostring");
2490 dissector_add_uint("sctp.ppi", SUA_PAYLOAD_PROTOCOL_ID, sua_handle);
2491 dissector_add_uint("sctp.port", SCTP_PORT_SUA, sua_handle);
2493 sccp_ssn_dissector_table = find_dissector_table("sccp.ssn");
2495 ss7pc_address_type = address_type_get_by_name("AT_SS7PC");
2499 * Editor modelines - https://www.wireshark.org/tools/modelines.html
2501 * Local Variables:
2502 * c-basic-offset: 2
2503 * tab-width: 8
2504 * indent-tabs-mode: nil
2505 * End:
2507 * ex: set shiftwidth=2 tabstop=8 expandtab:
2508 * :indentSize=2:tabSize=8:noTabs=true: