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