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