Coverage Report

Created: 2026-06-30 07:22

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