Coverage Report

Created: 2025-08-04 07:15

/src/wireshark/epan/dissectors/packet-sccp.c
Line
Count
Source (jump to first uncovered line)
1
/* packet-sccp.c
2
 * Routines for Signalling Connection Control Part (SCCP) dissection
3
 *
4
 * It is hopefully compliant to:
5
 *   ANSI T1.112.3-2001
6
 *   ITU-T Q.713 7/1996
7
 *   YDN 038-1997 (Chinese ITU variant)
8
 *   JT-Q713 and NTT-Q713 (Japan)
9
 *
10
 *   Note that Japan-specific GTT is incomplete; in particular, the specific
11
 *   TTs that are defined in TTC and NTT are not decoded in detail.
12
 *
13
 * Copyright 2002, Jeff Morriss <jeff.morriss.ws [AT] gmail.com>
14
 *
15
 * Wireshark - Network traffic analyzer
16
 * By Gerald Combs <gerald@wireshark.org>
17
 * Copyright 1998 Gerald Combs
18
 *
19
 * Copied from packet-m2pa.c
20
 *
21
 * SPDX-License-Identifier: GPL-2.0-or-later
22
 */
23
24
25
#include "config.h"
26
27
28
#include <epan/packet.h>
29
#include <epan/prefs.h>
30
#include <epan/reassemble.h>
31
#include <epan/address_types.h>
32
#include <epan/asn1.h>
33
#include <epan/uat.h>
34
#include <epan/expert.h>
35
#include <epan/tap.h>
36
#include <epan/to_str.h>
37
#include <epan/decode_as.h>
38
#include <epan/proto_data.h>
39
#include <wiretap/wtap.h>
40
#include <wsutil/str_util.h>
41
#include "packet-mtp3.h"
42
#include "packet-tcap.h"
43
#include "packet-sccp.h"
44
#include "packet-e164.h"
45
#include "packet-e212.h"
46
47
/* function prototypes */
48
void proto_register_sccp(void);
49
void proto_reg_handoff_sccp(void);
50
51
static Standard_Type decode_mtp3_standard;
52
53
562
#define SCCP_MSG_TYPE_OFFSET 0
54
562
#define SCCP_MSG_TYPE_LENGTH 1
55
1.32k
#define POINTER_LENGTH       1
56
1.18k
#define POINTER_LENGTH_LONG  2
57
58
/* Same as below but with names typed out */
59
static const value_string sccp_message_type_values[] = {
60
  { SCCP_MSG_TYPE_CR,           "Connection Request" },
61
  { SCCP_MSG_TYPE_CC,           "Connection Confirm" },
62
  { SCCP_MSG_TYPE_CREF,         "Connection Refused" },
63
  { SCCP_MSG_TYPE_RLSD,         "Released" },
64
  { SCCP_MSG_TYPE_RLC,          "Release Complete" },
65
  { SCCP_MSG_TYPE_DT1,          "Data Form 1" },
66
  { SCCP_MSG_TYPE_DT2,          "Data Form 2" },
67
  { SCCP_MSG_TYPE_AK,           "Data Acknowledgement" },
68
  { SCCP_MSG_TYPE_UDT,          "Unitdata" },
69
  { SCCP_MSG_TYPE_UDTS,         "Unitdata Service" },
70
  { SCCP_MSG_TYPE_ED,           "Expedited Data" },
71
  { SCCP_MSG_TYPE_EA,           "Expedited Data Acknowledgement" },
72
  { SCCP_MSG_TYPE_RSR,          "Reset Request" },
73
  { SCCP_MSG_TYPE_RSC,          "Reset Confirmation" },
74
  { SCCP_MSG_TYPE_ERR,          "Error" },
75
  { SCCP_MSG_TYPE_IT,           "Inactivity Timer" },
76
  { SCCP_MSG_TYPE_XUDT,         "Extended Unitdata" },
77
  { SCCP_MSG_TYPE_XUDTS,        "Extended Unitdata Service" },
78
  { SCCP_MSG_TYPE_LUDT,         "Long Unitdata" },
79
  { SCCP_MSG_TYPE_LUDTS,        "Long Unitdata Service" },
80
  { 0,                          NULL } };
81
82
/* Same as above but in acronym form (for the Info column) */
83
const value_string sccp_message_type_acro_values[] = {
84
  { SCCP_MSG_TYPE_CR,           "CR" },
85
  { SCCP_MSG_TYPE_CC,           "CC" },
86
  { SCCP_MSG_TYPE_CREF,         "CREF" },
87
  { SCCP_MSG_TYPE_RLSD,         "RLSD" },
88
  { SCCP_MSG_TYPE_RLC,          "RLC" },
89
  { SCCP_MSG_TYPE_DT1,          "DT1" },
90
  { SCCP_MSG_TYPE_DT2,          "DT2" },
91
  { SCCP_MSG_TYPE_AK,           "AK" },
92
  { SCCP_MSG_TYPE_UDT,          "UDT" },
93
  { SCCP_MSG_TYPE_UDTS,         "UDTS" },
94
  { SCCP_MSG_TYPE_ED,           "ED" },
95
  { SCCP_MSG_TYPE_EA,           "EA" },
96
  { SCCP_MSG_TYPE_RSR,          "RSR" },
97
  { SCCP_MSG_TYPE_RSC,          "RSC" },
98
  { SCCP_MSG_TYPE_ERR,          "ERR" },
99
  { SCCP_MSG_TYPE_IT,           "IT" },
100
  { SCCP_MSG_TYPE_XUDT,         "XUDT" },
101
  { SCCP_MSG_TYPE_XUDTS,        "XUDTS" },
102
  { SCCP_MSG_TYPE_LUDT,         "LUDT" },
103
  { SCCP_MSG_TYPE_LUDTS,        "LUDTS" },
104
  { 0,                          NULL } };
105
106
2.32k
#define PARAMETER_LENGTH_LENGTH                 1
107
3
#define PARAMETER_LONG_DATA_LENGTH_LENGTH       2
108
2.02k
#define PARAMETER_TYPE_LENGTH                   1
109
110
2.37k
#define PARAMETER_END_OF_OPTIONAL_PARAMETERS    0x00
111
1.98k
#define PARAMETER_DESTINATION_LOCAL_REFERENCE   0x01
112
1.43k
#define PARAMETER_SOURCE_LOCAL_REFERENCE        0x02
113
630
#define PARAMETER_CALLED_PARTY_ADDRESS          0x03
114
764
#define PARAMETER_CALLING_PARTY_ADDRESS         0x04
115
480
#define PARAMETER_CLASS                         0x05
116
77
#define PARAMETER_SEGMENTING_REASSEMBLING       0x06
117
36
#define PARAMETER_RECEIVE_SEQUENCE_NUMBER       0x07
118
66
#define PARAMETER_SEQUENCING_SEGMENTING         0x08
119
55
#define PARAMETER_CREDIT                        0x09
120
1.49k
#define PARAMETER_RELEASE_CAUSE                 0x0a
121
1.72k
#define PARAMETER_RETURN_CAUSE                  0x0b
122
1.60k
#define PARAMETER_RESET_CAUSE                   0x0c
123
1.64k
#define PARAMETER_ERROR_CAUSE                   0x0d
124
1.74k
#define PARAMETER_REFUSAL_CAUSE                 0x0e
125
5.03k
#define PARAMETER_DATA                          0x0f
126
406
#define PARAMETER_SEGMENTATION                  0x10
127
144
#define PARAMETER_HOP_COUNTER                   0x11
128
/* Importance is ITU only */
129
68
#define PARAMETER_IMPORTANCE                    0x12
130
2.80k
#define PARAMETER_LONG_DATA                     0x13
131
/* ISNI is ANSI only */
132
7
#define PARAMETER_ISNI                          0xfa
133
134
static const value_string sccp_parameter_values[] = {
135
  { PARAMETER_END_OF_OPTIONAL_PARAMETERS,       "End of Optional Parameters" },
136
  { PARAMETER_DESTINATION_LOCAL_REFERENCE,      "Destination Local Reference" },
137
  { PARAMETER_SOURCE_LOCAL_REFERENCE,           "Source Local Reference" },
138
  { PARAMETER_CALLED_PARTY_ADDRESS,             "Called Party Address" },
139
  { PARAMETER_CALLING_PARTY_ADDRESS,            "Calling Party Address" },
140
  { PARAMETER_CLASS,                            "Protocol Class" },
141
  { PARAMETER_SEGMENTING_REASSEMBLING,          "Segmenting/Reassembling" },
142
  { PARAMETER_RECEIVE_SEQUENCE_NUMBER,          "Receive Sequence Number" },
143
  { PARAMETER_SEQUENCING_SEGMENTING,            "Sequencing/Segmenting" },
144
  { PARAMETER_CREDIT,                           "Credit" },
145
  { PARAMETER_RELEASE_CAUSE,                    "Release Cause" },
146
  { PARAMETER_RETURN_CAUSE,                     "Return Cause" },
147
  { PARAMETER_RESET_CAUSE,                      "Reset Cause" },
148
  { PARAMETER_ERROR_CAUSE,                      "Error Cause" },
149
  { PARAMETER_REFUSAL_CAUSE,                    "Refusal Cause" },
150
  { PARAMETER_DATA,                             "Data" },
151
  { PARAMETER_SEGMENTATION,                     "Segmentation" },
152
  { PARAMETER_HOP_COUNTER,                      "Hop Counter" },
153
  { PARAMETER_IMPORTANCE,                       "Importance (ITU)" },
154
  { PARAMETER_LONG_DATA,                        "Long Data" },
155
  { PARAMETER_ISNI,                             "Intermediate Signaling Network Identification (ANSI)" },
156
  { 0,                                           NULL } };
157
158
159
206
#define END_OF_OPTIONAL_PARAMETERS_LENGTH       1
160
89
#define DESTINATION_LOCAL_REFERENCE_LENGTH      3
161
171
#define SOURCE_LOCAL_REFERENCE_LENGTH           3
162
209
#define PROTOCOL_CLASS_LENGTH                   1
163
#define RECEIVE_SEQUENCE_NUMBER_LENGTH          1
164
#define CREDIT_LENGTH                           1
165
#define RELEASE_CAUSE_LENGTH                    1
166
#define RETURN_CAUSE_LENGTH                     1
167
#define RESET_CAUSE_LENGTH                      1
168
#define ERROR_CAUSE_LENGTH                      1
169
#define REFUSAL_CAUSE_LENGTH                    1
170
#define HOP_COUNTER_LENGTH                      1
171
#define IMPORTANCE_LENGTH                       1
172
173
174
/* Parts of the Called and Calling Address parameters */
175
/* Address Indicator */
176
3.15k
#define ADDRESS_INDICATOR_LENGTH        1
177
481
#define ITU_RESERVED_MASK               0x80
178
28
#define ANSI_NATIONAL_MASK              0x80
179
481
#define ROUTING_INDICATOR_MASK          0x40
180
509
#define GTI_MASK                        0x3C
181
379
#define GTI_SHIFT                       2
182
478
#define ITU_SSN_INDICATOR_MASK          0x02
183
478
#define ITU_PC_INDICATOR_MASK           0x01
184
28
#define ANSI_PC_INDICATOR_MASK          0x02
185
28
#define ANSI_SSN_INDICATOR_MASK         0x01
186
187
static const value_string sccp_ansi_national_indicator_values[] = {
188
  { 0x0,  "Address coded to International standard" },
189
  { 0x1,  "Address coded to National standard" },
190
  { 0,    NULL } };
191
192
0
#define ROUTE_ON_GT             0x0
193
666
#define ROUTE_ON_SSN            0x1
194
453
#define ROUTING_INDICATOR_SHIFT 6
195
static const value_string sccp_routing_indicator_values[] = {
196
  { ROUTE_ON_GT,  "Route on GT" },
197
  { ROUTE_ON_SSN, "Route on SSN" },
198
  { 0,            NULL } };
199
200
436
#define AI_GTI_NO_GT                    0x0
201
551
#define ITU_AI_GTI_NAI                  0x1
202
758
#define AI_GTI_TT                       0x2
203
742
#define ITU_AI_GTI_TT_NP_ES             0x3
204
866
#define ITU_AI_GTI_TT_NP_ES_NAI 0x4
205
static const value_string sccp_itu_global_title_indicator_values[] = {
206
  { AI_GTI_NO_GT,               "No Global Title" },
207
  { ITU_AI_GTI_NAI,             "Nature of Address Indicator only" },
208
  { AI_GTI_TT,                  "Translation Type only" },
209
  { ITU_AI_GTI_TT_NP_ES,        "Translation Type, Numbering Plan, and Encoding Scheme included" },
210
  { ITU_AI_GTI_TT_NP_ES_NAI,    "Translation Type, Numbering Plan, Encoding Scheme, and Nature of Address Indicator included" },
211
  { 0,                          NULL } };
212
213
/* #define AI_GTI_NO_GT         0x0 */
214
0
#define ANSI_AI_GTI_TT_NP_ES    0x1
215
/* #define AI_GTI_TT            0x2 */
216
static const value_string sccp_ansi_global_title_indicator_values[] = {
217
  { AI_GTI_NO_GT,               "No Global Title" },
218
  { ANSI_AI_GTI_TT_NP_ES,       "Translation Type, Numbering Plan, and Encoding Scheme included" },
219
  { AI_GTI_TT,                  "Translation Type only" },
220
  { 0,                          NULL } };
221
222
static const value_string sccp_ai_pci_values[] = {
223
  { 0x1,  "Point Code present" },
224
  { 0x0,  "Point Code not present" },
225
  { 0,    NULL } };
226
227
static const value_string sccp_ai_ssni_values[] = {
228
  { 0x1,  "SSN present" },
229
  { 0x0,  "SSN not present" },
230
  { 0,    NULL } };
231
232
733
#define ADDRESS_SSN_LENGTH      1
233
1.35k
#define INVALID_SSN             0xff
234
/* Some values from 3GPP TS 23.003 */
235
/*  Japan TTC and NTT define a lot of SSNs, some of which conflict with
236
 *  these.  They are not added for now.
237
 */
238
static const value_string sccp_ssn_values[] = {
239
  { 0x00,  "SSN not known/not used" },
240
  { 0x01,  "SCCP management" },
241
  { 0x02,  "Reserved for ITU-T allocation" },
242
  { 0x03,  "ISDN User Part" },
243
  { 0x04,  "OMAP (Operation, Maintenance, and Administration Part)" },
244
  { 0x05,  "MAP (Mobile Application Part)" },
245
  { 0x06,  "HLR (Home Location Register)" },
246
  { 0x07,  "VLR (Visitor Location Register)" },
247
  { 0x08,  "MSC (Mobile Switching Center)" },
248
  { 0x09,  "EIC/EIR (Equipment Identifier Center/Equipment Identification Register)" },
249
  { 0x0a,  "AUC/AC (Authentication Center)" },
250
  { 0x0b,  "ISDN supplementary services (ITU only)" },
251
  { 0x0c,  "Reserved for international use (ITU only)" },
252
  { 0x0d,  "Broadband ISDN edge-to-edge applications (ITU only)" },
253
  { 0x0e,  "TC test responder (ITU only)" },
254
  /* The following national network subsystem numbers have been allocated for use within and
255
   * between GSM/UMTS networks:
256
   */
257
  { 0x8e,  "RANAP" },
258
  { 0x8f,  "RNSAP" },
259
  { 0x91,  "GMLC(MAP)" },
260
  { 0x92,  "CAP" },
261
  { 0x93,  "gsmSCF (MAP) or IM-SSF (MAP) or Presence Network Agent" },
262
  { 0x94,  "SIWF (MAP)" },
263
  { 0x95,  "SGSN (MAP)" },
264
  { 0x96,  "GGSN (MAP)" },
265
  /* The following national network subsystem numbers have been allocated for use within GSM/UMTS networks:*/
266
  { 0xf8,  "CSS (MAP)" },
267
  { 0xf9,  "PCAP" },
268
  { 0xfa,  "BSC (BSSAP-LE)" },
269
  { 0xfb,  "MSC (BSSAP-LE)" },
270
  { 0xfc,  "IOS or SMLC (BSSAP-LE)" },
271
  { 0xfd,  "BSS O&M (A interface)" },
272
  { 0xfe,  "BSSAP/BSAP" },
273
  { 0,     NULL } };
274
275
276
/* * * * * * * * * * * * * * * * *
277
 * Global Title: ITU GTI == 0001 *
278
 * * * * * * * * * * * * * * * * */
279
200
#define GT_NAI_MASK 0x7F
280
487
#define GT_NAI_LENGTH 1
281
#define GT_NAI_UNKNOWN                  0x00
282
#define GT_NAI_SUBSCRIBER_NUMBER        0x01
283
#define GT_NAI_RESERVED_NATIONAL        0x02
284
#define GT_NAI_NATIONAL_SIG_NUM         0x03
285
17
#define GT_NAI_INTERNATIONAL_NUM        0x04
286
static const value_string sccp_nai_values[] = {
287
  { GT_NAI_UNKNOWN,             "NAI unknown" },
288
  { GT_NAI_SUBSCRIBER_NUMBER,   "Subscriber Number" },
289
  { GT_NAI_RESERVED_NATIONAL,   "Reserved for national use" },
290
  { GT_NAI_NATIONAL_SIG_NUM,    "National significant number" },
291
  { GT_NAI_INTERNATIONAL_NUM,   "International number" },
292
  { 0,                          NULL } };
293
294
295
171
#define GT_OE_MASK 0x80
296
143
#define GT_OE_EVEN 0
297
#define GT_OE_ODD  1
298
static const value_string sccp_oe_values[] = {
299
  { GT_OE_EVEN, "Even number of address signals" },
300
  { GT_OE_ODD,  "Odd number of address signals" },
301
  { 0,          NULL } };
302
303
const value_string sccp_address_signal_values[] = {
304
  { 0,  "0" },
305
  { 1,  "1" },
306
  { 2,  "2" },
307
  { 3,  "3" },
308
  { 4,  "4" },
309
  { 5,  "5" },
310
  { 6,  "6" },
311
  { 7,  "7" },
312
  { 8,  "8" },
313
  { 9,  "9" },
314
  { 10, "(spare)" },
315
  { 11, "11" },
316
  { 12, "12" },
317
  { 13, "(spare)" },
318
  { 14, "(spare)" },
319
  { 15, "ST" },
320
  { 0,  NULL } };
321
322
323
/* * * * * * * * * * * * * * * * * * * * *
324
 * Global Title: ITU and ANSI GTI == 0010 *
325
 * * * * * * * * * * * * * * * * * * * * */
326
202
#define GT_TT_LENGTH 1
327
328
329
/* * * * * * * * * * * * * * * * * * * * * * * * * *
330
 * Global Title: ITU GTI == 0011, ANSI GTI == 0001 *
331
 * * * * * * * * * * * * * * * * * * * * * * * * * */
332
113
#define GT_NP_MASK              0xf0
333
376
#define GT_NP_SHIFT             4
334
255
#define GT_NP_ES_LENGTH         1
335
#define GT_NP_UNKNOWN           0x00
336
13
#define GT_NP_ISDN              0x01
337
#define GT_NP_GENERIC_RESERVED  0x02
338
#define GT_NP_DATA              0x03
339
#define GT_NP_TELEX             0x04
340
#define GT_NP_MARITIME_MOBILE   0x05
341
4
#define GT_NP_LAND_MOBILE       0x06
342
17
#define GT_NP_ISDN_MOBILE       0x07
343
#define GT_NP_PRIVATE_NETWORK   0x0e
344
#define GT_NP_RESERVED          0x0f
345
static const value_string sccp_np_values[] = {
346
  { GT_NP_UNKNOWN,              "Unknown" },
347
  { GT_NP_ISDN,                 "ISDN/telephony" },
348
  { GT_NP_GENERIC_RESERVED,     "Generic (ITU)/Reserved (ANSI)" },
349
  { GT_NP_DATA,                 "Data" },
350
  { GT_NP_TELEX,                "Telex" },
351
  { GT_NP_MARITIME_MOBILE,      "Maritime mobile" },
352
  { GT_NP_LAND_MOBILE,          "Land mobile" },
353
  { GT_NP_ISDN_MOBILE,          "ISDN/mobile" },
354
  { GT_NP_PRIVATE_NETWORK,      "Private network or network-specific" },
355
  { GT_NP_RESERVED,             "Reserved" },
356
  { 0,                          NULL } };
357
358
113
#define GT_ES_MASK     0x0f
359
#define GT_ES_UNKNOWN  0x0
360
#define GT_ES_BCD_ODD  0x1
361
85
#define GT_ES_BCD_EVEN 0x2
362
#define GT_ES_NATIONAL 0x3
363
#define GT_ES_RESERVED 0xf
364
static const value_string sccp_es_values[] = {
365
  { GT_ES_UNKNOWN,      "Unknown" },
366
  { GT_ES_BCD_ODD,      "BCD, odd number of digits" },
367
  { GT_ES_BCD_EVEN,     "BCD, even number of digits" },
368
  { GT_ES_NATIONAL,     "National specific" },
369
  { GT_ES_RESERVED,     "Reserved (ITU)/Spare (ANSI)" },
370
  { 0,                  NULL } };
371
372
/* Address signals above */
373
374
375
/* * * * * * * * * * * * * * * * *
376
 * Global Title: ITU GTI == 0100 *
377
 * * * * * * * * * * * * * * * * */
378
/* NP above */
379
/* ES above */
380
/* NAI above */
381
/* Address signals above */
382
383
384
225
#define CLASS_CLASS_MASK                0xf
385
106
#define CLASS_SPARE_HANDLING_MASK       0xf0
386
92
#define CLASS_SPARE_HANDLING_SHIFT      4
387
static const value_string sccp_class_handling_values [] = {
388
  { 0x0,  "No special options" },
389
  { 0x8,  "Return message on error" },
390
  { 0,    NULL } };
391
392
393
5
#define SEGMENTING_REASSEMBLING_LENGTH 1
394
19
#define SEGMENTING_REASSEMBLING_MASK   0x01
395
#define NO_MORE_DATA 0
396
#define MORE_DATA    1
397
/* This is also used by sequencing-segmenting parameter */
398
static const value_string sccp_segmenting_reassembling_values [] = {
399
  { NO_MORE_DATA,       "No more data" },
400
  { MORE_DATA,          "More data" },
401
  { 0,                  NULL } };
402
403
404
1
#define RECEIVE_SEQUENCE_NUMBER_LENGTH          1
405
14
#define RSN_MASK                                0xfe
406
407
8
#define SEQUENCING_SEGMENTING_LENGTH            2
408
87
#define SEQUENCING_SEGMENTING_SSN_LENGTH        1
409
58
#define SEQUENCING_SEGMENTING_RSN_LENGTH        1
410
14
#define SEND_SEQUENCE_NUMBER_MASK               0xfe
411
14
#define RECEIVE_SEQUENCE_NUMBER_MASK            0xfe
412
14
#define SEQUENCING_SEGMENTING_MORE_MASK         0x01
413
414
415
8
#define CREDIT_LENGTH 1
416
417
8
#define RELEASE_CAUSE_LENGTH 1
418
const value_string sccp_release_cause_values [] = {
419
  { 0x00,  "End user originated" },
420
  { 0x01,  "End user congestion" },
421
  { 0x02,  "End user failure" },
422
  { 0x03,  "SCCP user originated" },
423
  { 0x04,  "Remote procedure error" },
424
  { 0x05,  "Inconsistent connection data" },
425
  { 0x06,  "Access failure" },
426
  { 0x07,  "Access congestion" },
427
  { 0x08,  "Subsystem failure" },
428
  { 0x09,  "Subsystem congestion" },
429
  { 0x0a,  "MTP failure" },
430
  { 0x0b,  "Network congestion" },
431
  { 0x0c,  "Expiration of reset timer" },
432
  { 0x0d,  "Expiration of receive inactivity timer" },
433
  { 0x0e,  "Reserved" },
434
  { 0x0f,  "Unqualified" },
435
  { 0x10,  "SCCP failure (ITU only)" },
436
  { 0,     NULL } };
437
438
439
34
#define RETURN_CAUSE_LENGTH 1
440
const value_string sccp_return_cause_values [] = {
441
  { 0x00,  "No translation for an address of such nature" },
442
  { 0x01,  "No translation for this specific address" },
443
  { 0x02,  "Subsystem congestion" },
444
  { 0x03,  "Subsystem failure" },
445
  { 0x04,  "Unequipped failure" },
446
  { 0x05,  "MTP failure" },
447
  { 0x06,  "Network congestion" },
448
  { 0x07,  "Unqualified" },
449
  { 0x08,  "Error in message transport" },
450
  { 0x09,  "Error in local processing" },
451
  { 0x0a,  "Destination cannot perform reassembly" },
452
  { 0x0b,  "SCCP failure" },
453
  { 0x0c,  "Hop counter violation" },
454
  { 0x0d,  "Segmentation not supported" },
455
  { 0x0e,  "Segmentation failure" },
456
  { 0xf7,  "Message change failure (ANSI only)" },
457
  { 0xf8,  "Invalid INS routing request (ANSI only)" },
458
  { 0xf9,  "Invalid ISNI routing request (ANSI only)"},
459
  { 0xfa,  "Unauthorized message (ANSI only)" },
460
  { 0xfb,  "Message incompatibility (ANSI only)" },
461
  { 0xfc,  "Cannot perform ISNI constrained routing (ANSI only)" },
462
  { 0xfd,  "Redundant ISNI constrained routing (ANSI only)" },
463
  { 0xfe,  "Unable to perform ISNI identification (ANSI only)" },
464
  { 0,     NULL } };
465
466
467
0
#define RESET_CAUSE_LENGTH 1
468
const value_string sccp_reset_cause_values [] = {
469
  { 0x00,  "End user originated" },
470
  { 0x01,  "SCCP user originated" },
471
  { 0x02,  "Message out of order - incorrect send sequence number" },
472
  { 0x03,  "Message out of order - incorrect receive sequence number" },
473
  { 0x04,  "Remote procedure error - message out of window" },
474
  { 0x05,  "Remote procedure error - incorrect send sequence number after (re)initialization" },
475
  { 0x06,  "Remote procedure error - general" },
476
  { 0x07,  "Remote end user operational" },
477
  { 0x08,  "Network operational" },
478
  { 0x09,  "Access operational" },
479
  { 0x0a,  "Network congestion" },
480
  { 0x0b,  "Reserved (ITU)/Not obtainable (ANSI)" },
481
  { 0x0c,  "Unqualified" },
482
  { 0,     NULL } };
483
484
485
2
#define ERROR_CAUSE_LENGTH 1
486
const value_string sccp_error_cause_values [] = {
487
  { 0x00,  "Local Reference Number (LRN) mismatch - unassigned destination LRN" },
488
  { 0x01,  "Local Reference Number (LRN) mismatch - inconsistent source LRN" },
489
  { 0x02,  "Point code mismatch" },
490
  { 0x03,  "Service class mismatch" },
491
  { 0x04,  "Unqualified" },
492
  { 0,     NULL } };
493
494
495
8
#define REFUSAL_CAUSE_LENGTH 1
496
const value_string sccp_refusal_cause_values [] = {
497
  { 0x00,  "End user originated" },
498
  { 0x01,  "End user congestion" },
499
  { 0x02,  "End user failure" },
500
  { 0x03,  "SCCP user originated" },
501
  { 0x04,  "Destination address unknown" },
502
  { 0x05,  "Destination inaccessible" },
503
  { 0x06,  "Network resource - QOS not available/non-transient" },
504
  { 0x07,  "Network resource - QOS not available/transient" },
505
  { 0x08,  "Access failure" },
506
  { 0x09,  "Access congestion" },
507
  { 0x0a,  "Subsystem failure" },
508
  { 0x0b,  "Subsystem congestion" },
509
  { 0x0c,  "Expiration of connection establishment timer" },
510
  { 0x0d,  "Incompatible user data" },
511
  { 0x0e,  "Reserved" },
512
  { 0x0f,  "Unqualified" },
513
  { 0x10,  "Hop counter violation" },
514
  { 0x11,  "SCCP failure (ITU only)" },
515
  { 0x12,  "No translation for an address of such nature" },
516
  { 0x13,  "Unequipped user" },
517
  { 0,     NULL } };
518
519
520
#define SEGMENTATION_LENGTH             4
521
14
#define SEGMENTATION_FIRST_SEGMENT_MASK 0x80
522
14
#define SEGMENTATION_CLASS_MASK         0x40
523
#define SEGMENTATION_SPARE_MASK         0x30
524
14
#define SEGMENTATION_REMAINING_MASK     0x0f
525
static const value_string sccp_segmentation_first_segment_values [] = {
526
  { 1,  "First segment" },
527
  { 0,  "Not first segment" },
528
  { 0,  NULL } };
529
static const value_string sccp_segmentation_class_values [] = {
530
  { 0,  "Class 0 selected" },
531
  { 1,  "Class 1 selected" },
532
  { 0,  NULL } };
533
534
535
70
#define HOP_COUNTER_LENGTH 1
536
537
#define IMPORTANCE_LENGTH               1
538
14
#define IMPORTANCE_IMPORTANCE_MASK      0x7
539
540
541
0
#define ANSI_ISNI_ROUTING_CONTROL_LENGTH 1
542
14
#define ANSI_ISNI_MI_MASK                0x01
543
14
#define ANSI_ISNI_IRI_MASK               0x06
544
#define ANSI_ISNI_RES_MASK               0x08
545
14
#define ANSI_ISNI_TI_MASK                0x10
546
0
#define ANSI_ISNI_TI_SHIFT               4
547
14
#define ANSI_ISNI_COUNTER_MASK           0xe0
548
14
#define ANSI_ISNI_NETSPEC_MASK           0x03
549
550
static const value_string sccp_isni_mark_for_id_values [] = {
551
  { 0x0,  "Do not identify networks" },
552
  { 0x1,  "Identify networks" },
553
  { 0,    NULL } };
554
555
static const value_string sccp_isni_iri_values [] = {
556
  { 0x0,  "Neither constrained nor suggested ISNI routing" },
557
  { 0x1,  "Constrained ISNI routing" },
558
  { 0x2,  "Reserved for suggested ISNI routing" },
559
  { 0x3,  "Spare" },
560
  { 0,    NULL } };
561
562
#define ANSI_ISNI_TYPE_0 0x0
563
0
#define ANSI_ISNI_TYPE_1 0x1
564
static const value_string sccp_isni_ti_values [] = {
565
  { ANSI_ISNI_TYPE_0,   "Type zero ISNI parameter format" },
566
  { ANSI_ISNI_TYPE_1,   "Type one ISNI parameter format" },
567
  { 0,                  NULL } };
568
569
/* Laded from e212 hf*/
570
static int hf_assoc_imsi;
571
572
/* Initialize the protocol and registered fields */
573
static int proto_sccp;
574
static int hf_sccp_message_type;
575
static int hf_sccp_variable_pointer1;
576
static int hf_sccp_variable_pointer2;
577
static int hf_sccp_variable_pointer3;
578
static int hf_sccp_optional_pointer;
579
static int hf_sccp_param_length;
580
static int hf_sccp_ssn;
581
static int hf_sccp_gt_digits;
582
583
/* Called Party address */
584
static int hf_sccp_called_ansi_national_indicator;
585
static int hf_sccp_called_itu_natl_use_bit;
586
static int hf_sccp_called_routing_indicator;
587
static int hf_sccp_called_itu_global_title_indicator;
588
static int hf_sccp_called_ansi_global_title_indicator;
589
static int hf_sccp_called_itu_ssn_indicator;
590
static int hf_sccp_called_itu_point_code_indicator;
591
static int hf_sccp_called_ansi_ssn_indicator;
592
static int hf_sccp_called_ansi_point_code_indicator;
593
static int hf_sccp_called_ssn;
594
static int hf_sccp_called_pc_member;
595
static int hf_sccp_called_pc_cluster;
596
static int hf_sccp_called_pc_network;
597
static int hf_sccp_called_ansi_pc;
598
static int hf_sccp_called_chinese_pc;
599
static int hf_sccp_called_itu_pc;
600
static int hf_sccp_called_japan_pc;
601
static int hf_sccp_called_gt_nai;
602
static int hf_sccp_called_gt_oe;
603
static int hf_sccp_called_gt_tt;
604
static int hf_sccp_called_gt_np;
605
static int hf_sccp_called_gt_es;
606
static int hf_sccp_called_gt_digits;
607
static int hf_sccp_called_gt_digits_length;
608
609
/* Calling party address */
610
static int hf_sccp_calling_ansi_national_indicator;
611
static int hf_sccp_calling_itu_natl_use_bit;
612
static int hf_sccp_calling_routing_indicator;
613
static int hf_sccp_calling_itu_global_title_indicator;
614
static int hf_sccp_calling_ansi_global_title_indicator;
615
static int hf_sccp_calling_itu_ssn_indicator;
616
static int hf_sccp_calling_itu_point_code_indicator;
617
static int hf_sccp_calling_ansi_ssn_indicator;
618
static int hf_sccp_calling_ansi_point_code_indicator;
619
static int hf_sccp_calling_ssn;
620
static int hf_sccp_calling_pc_member;
621
static int hf_sccp_calling_pc_cluster;
622
static int hf_sccp_calling_pc_network;
623
static int hf_sccp_calling_ansi_pc;
624
static int hf_sccp_calling_chinese_pc;
625
static int hf_sccp_calling_itu_pc;
626
static int hf_sccp_calling_japan_pc;
627
static int hf_sccp_calling_gt_nai;
628
static int hf_sccp_calling_gt_oe;
629
static int hf_sccp_calling_gt_tt;
630
static int hf_sccp_calling_gt_np;
631
static int hf_sccp_calling_gt_es;
632
static int hf_sccp_calling_gt_digits;
633
static int hf_sccp_calling_gt_digits_length;
634
635
/* Other parameter values */
636
static int hf_sccp_dlr;
637
static int hf_sccp_slr;
638
static int hf_sccp_lr;
639
static int hf_sccp_class;
640
static int hf_sccp_handling;
641
static int hf_sccp_more;
642
static int hf_sccp_rsn;
643
static int hf_sccp_sequencing_segmenting_ssn;
644
static int hf_sccp_sequencing_segmenting_rsn;
645
static int hf_sccp_sequencing_segmenting_more;
646
static int hf_sccp_credit;
647
static int hf_sccp_release_cause;
648
static int hf_sccp_return_cause;
649
static int hf_sccp_reset_cause;
650
static int hf_sccp_error_cause;
651
static int hf_sccp_refusal_cause;
652
static int hf_sccp_segmentation_first;
653
static int hf_sccp_segmentation_class;
654
static int hf_sccp_segmentation_remaining;
655
static int hf_sccp_segmentation_slr;
656
static int hf_sccp_hop_counter;
657
static int hf_sccp_importance;
658
static int hf_sccp_ansi_isni_mi;
659
static int hf_sccp_ansi_isni_iri;
660
static int hf_sccp_ansi_isni_ti;
661
static int hf_sccp_ansi_isni_netspec;
662
static int hf_sccp_ansi_isni_counter;
663
static int hf_sccp_ansi_isni_network;
664
static int hf_sccp_ansi_isni_cluster;
665
static int hf_sccp_xudt_msg_fragments;
666
static int hf_sccp_xudt_msg_fragment;
667
static int hf_sccp_xudt_msg_fragment_overlap;
668
static int hf_sccp_xudt_msg_fragment_overlap_conflicts;
669
static int hf_sccp_xudt_msg_fragment_multiple_tails;
670
static int hf_sccp_xudt_msg_fragment_too_long_fragment;
671
static int hf_sccp_xudt_msg_fragment_error;
672
static int hf_sccp_xudt_msg_fragment_count;
673
static int hf_sccp_xudt_msg_reassembled_in;
674
static int hf_sccp_xudt_msg_reassembled_length;
675
static int hf_sccp_assoc_msg;
676
static int hf_sccp_assoc_id;
677
static int hf_sccp_segmented_data;
678
static int hf_sccp_linked_dissector;
679
static int hf_sccp_end_optional_param;
680
static int hf_sccp_unknown_message;
681
static int hf_sccp_unknown_parameter;
682
683
/* Initialize the subtree pointers */
684
static int ett_sccp;
685
static int ett_sccp_called;
686
static int ett_sccp_called_ai;
687
static int ett_sccp_called_pc;
688
static int ett_sccp_called_gt;
689
static int ett_sccp_called_gt_digits;
690
static int ett_sccp_calling;
691
static int ett_sccp_calling_ai;
692
static int ett_sccp_calling_pc;
693
static int ett_sccp_calling_gt;
694
static int ett_sccp_calling_gt_digits;
695
static int ett_sccp_sequencing_segmenting;
696
static int ett_sccp_segmentation;
697
static int ett_sccp_ansi_isni_routing_control;
698
static int ett_sccp_xudt_msg_fragment;
699
static int ett_sccp_xudt_msg_fragments;
700
static int ett_sccp_assoc;
701
702
static expert_field ei_sccp_wrong_length;
703
static expert_field ei_sccp_international_standard_address;
704
static expert_field ei_sccp_no_ssn_present;
705
static expert_field ei_sccp_ssn_zero;
706
static expert_field ei_sccp_class_unexpected;
707
static expert_field ei_sccp_handling_invalid;
708
static expert_field ei_sccp_gt_digits_missing;
709
static expert_field ei_sccp_externally_reassembled;
710
711
712
static bool sccp_reassemble = true;
713
static bool show_key_params;
714
static bool set_addresses;
715
static bool dt1_ignore_length;
716
717
static int ss7pc_address_type = -1;
718
719
static int sccp_tap;
720
721
722
static const fragment_items sccp_xudt_msg_frag_items = {
723
  /* Fragment subtrees */
724
  &ett_sccp_xudt_msg_fragment,
725
  &ett_sccp_xudt_msg_fragments,
726
  /* Fragment fields */
727
  &hf_sccp_xudt_msg_fragments,
728
  &hf_sccp_xudt_msg_fragment,
729
  &hf_sccp_xudt_msg_fragment_overlap,
730
  &hf_sccp_xudt_msg_fragment_overlap_conflicts,
731
  &hf_sccp_xudt_msg_fragment_multiple_tails,
732
  &hf_sccp_xudt_msg_fragment_too_long_fragment,
733
  &hf_sccp_xudt_msg_fragment_error,
734
  &hf_sccp_xudt_msg_fragment_count,
735
  /* Reassembled in field */
736
  &hf_sccp_xudt_msg_reassembled_in,
737
  /* Reassembled length field */
738
  &hf_sccp_xudt_msg_reassembled_length,
739
  /* Reassembled data field */
740
  NULL,
741
  /* Tag */
742
  "SCCP XUDT Message fragments"
743
};
744
745
static reassembly_table sccp_xudt_msg_reassembly_table;
746
747
748
#define SCCP_USER_DATA       0
749
#define SCCP_USER_TCAP       1
750
#define SCCP_USER_RANAP      2
751
#define SCCP_USER_BSSAP      3
752
#define SCCP_USER_GSMMAP     4
753
#define SCCP_USER_CAMEL      5
754
#define SCCP_USER_INAP       6
755
#define SCCP_USER_BSAP       7
756
#define SCCP_USER_BSSAP_LE   8
757
#define SCCP_USER_BSSAP_PLUS 9
758
759
typedef struct _sccp_user_t {
760
  unsigned            ni;
761
  range_t            *called_pc;
762
  range_t            *called_ssn;
763
  unsigned            user;
764
  bool                uses_tcap;
765
  dissector_handle_t *handlep;
766
} sccp_user_t;
767
768
static sccp_user_t *sccp_users;
769
static unsigned     num_sccp_users;
770
771
static dissector_handle_t sccp_handle;
772
static dissector_handle_t data_handle;
773
static dissector_handle_t tcap_handle;
774
static dissector_handle_t ranap_handle;
775
static dissector_handle_t bssap_handle;
776
static dissector_handle_t gsmmap_handle;
777
static dissector_handle_t camel_handle;
778
static dissector_handle_t inap_handle;
779
static dissector_handle_t bsap_handle;
780
static dissector_handle_t bssap_le_handle;
781
static dissector_handle_t bssap_plus_handle;
782
static dissector_handle_t default_handle;
783
784
static const char *default_payload;
785
786
static const value_string sccp_users_vals[] = {
787
  { SCCP_USER_DATA,       "Data"},
788
  { SCCP_USER_TCAP,       "TCAP"},
789
  { SCCP_USER_RANAP,      "RANAP"},
790
  { SCCP_USER_BSSAP,      "BSSAP"},
791
  { SCCP_USER_GSMMAP,     "GSM MAP"},
792
  { SCCP_USER_CAMEL,      "CAMEL"},
793
  { SCCP_USER_INAP,       "INAP"},
794
  { SCCP_USER_BSAP,       "BSAP"},
795
  { SCCP_USER_BSSAP_LE,   "BSSAP-LE"},
796
  { SCCP_USER_BSSAP_PLUS, "BSSAP+"},
797
  { 0, NULL }
798
};
799
800
/*
801
 * Here are the global variables associated with
802
 * the various user definable characteristics of the dissection
803
 */
804
static uint32_t sccp_source_pc_global;
805
static bool sccp_show_length;
806
static bool trace_sccp;
807
808
static heur_dissector_list_t heur_subdissector_list;
809
810
static dissector_table_t sccp_ssn_dissector_table;
811
812
static wmem_tree_t       *assocs;
813
static sccp_assoc_info_t  no_assoc = { 0,0,0,INVALID_SSN,INVALID_SSN,false,false,NULL,NULL,SCCP_PLOAD_NONE,NULL,NULL,NULL, NULL, 0 };
814
static uint32_t           next_assoc_id;
815
816
static const value_string assoc_protos[] = {
817
  { SCCP_PLOAD_BSSAP,   "BSSAP" },
818
  { SCCP_PLOAD_RANAP,   "RANAP" },
819
  { 0,                  NULL }
820
};
821
822
/*
823
 * Fragment reassembly helpers.
824
 *
825
 * SCCP data can span multiple messages. As the same local reference number is
826
 * used throughout a connection, this identifier is not sufficient for
827
 * identifying reassembled PDUs with multiple fragments in the same frame. For
828
 * that reason, create a new identifier for each group of fragments based on the
829
 * more-data indicator (M-bit) and use that in place of the local reference
830
 * number.
831
 *
832
 * As an optimization, if fragments do not need reassembly (a single message
833
 * with the M-bit set), then no surrogate ID is needed nor stored since
834
 * reassembly is skipped.
835
 */
836
static uint32_t sccp_reassembly_id_next;
837
838
/* Maps a key to the current identifier as used in the reassembly API (first pass only). */
839
static wmem_tree_t *sccp_reassembly_ids;
840
841
/* Maps (frame number, offset) to a reassembly API identifier. */
842
static wmem_map_t *sccp_reassembly_id_map;
843
844
static uint32_t
845
sccp_reassembly_get_id_pass1(uint32_t frame, uint32_t offset, uint32_t key, bool more_frags)
846
13
{
847
13
  uint32_t id = GPOINTER_TO_UINT(wmem_tree_lookup32(sccp_reassembly_ids, key));
848
13
  if (!id) {
849
13
    if (!more_frags) {
850
      /* This is the last and only fragment, no need to reassembly anything. */
851
9
      return 0;
852
9
    }
853
854
    /* This is a new fragment and "local reference", so create a new one. */
855
4
    id = sccp_reassembly_id_next++;
856
4
    wmem_tree_insert32(sccp_reassembly_ids, key, GUINT_TO_POINTER(id));
857
4
  }
858
  /* Save ID for second pass. */
859
4
  uint64_t *frame_offset = wmem_new(wmem_file_scope(), uint64_t);
860
4
  *frame_offset = ((uint64_t)offset << 32) | frame;
861
4
  wmem_map_insert(sccp_reassembly_id_map, frame_offset, GUINT_TO_POINTER(id));
862
4
  return id;
863
13
}
864
865
static uint32_t
866
sccp_reassembly_get_id_pass2(uint32_t frame, uint32_t offset)
867
0
{
868
0
  uint64_t frame_offset = ((uint64_t)offset << 32) | frame;
869
0
  return GPOINTER_TO_UINT(wmem_map_lookup(sccp_reassembly_id_map, &frame_offset));
870
0
}
871
872
/**
873
 * Returns the reassembly ID for the given frame at the given position or 0 if
874
 * reassembly is not necessary.
875
 */
876
static uint32_t
877
sccp_reassembly_get_id(packet_info *pinfo, uint32_t offset, uint32_t key, bool more_frags)
878
13
{
879
13
  if (!PINFO_FD_VISITED(pinfo)) {
880
13
    return sccp_reassembly_get_id_pass1(pinfo->num, offset, key, more_frags);
881
13
  } else {
882
0
    return sccp_reassembly_get_id_pass2(pinfo->num, offset);
883
0
  }
884
13
}
885
886
static tvbuff_t *
887
sccp_reassemble_fragments(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
888
                          uint16_t length_offset, uint32_t source_local_ref, bool more_frags,
889
                          uint8_t pointer_length)
890
13
{
891
13
  bool      save_fragmented;
892
13
  tvbuff_t *new_tvb;
893
13
  fragment_head *frag_msg = NULL;
894
13
  unsigned  fragment_len;
895
13
  uint32_t  abs_offset, frags_id;
896
897
13
  switch (pointer_length) {
898
13
  case POINTER_LENGTH:
899
13
    fragment_len = tvb_get_uint8(tvb, length_offset);
900
13
    break;
901
0
  case POINTER_LENGTH_LONG:
902
0
    fragment_len = tvb_get_uint16(tvb, length_offset, ENC_LITTLE_ENDIAN);
903
0
    break;
904
0
  default:
905
0
    ws_assert_not_reached();
906
13
  }
907
  /* Assume that the absolute offset within the tvb uniquely identifies the
908
   * message in this frame. */
909
13
  abs_offset = tvb_raw_offset(tvb) + length_offset;
910
13
  frags_id = sccp_reassembly_get_id(pinfo, abs_offset, source_local_ref, more_frags);
911
13
  if (frags_id) {
912
    /*
913
     * This fragment is part of multiple fragments, reassembly is required.
914
     */
915
4
    save_fragmented = pinfo->fragmented;
916
4
    pinfo->fragmented = true;
917
4
    frag_msg = fragment_add_seq_next(&sccp_xudt_msg_reassembly_table,
918
4
                                     tvb, length_offset + pointer_length,
919
4
                                     pinfo,
920
4
                                     frags_id,        /* ID for fragments belonging together */
921
4
                                     NULL,
922
4
                                     fragment_len,    /* fragment length - to the end */
923
4
                                     more_frags);     /* More fragments? */
924
925
4
    if (!PINFO_FD_VISITED(pinfo) && frag_msg) {
926
      /* Reassembly has finished, ensure that the next fragment gets a new ID. */
927
0
      wmem_tree_remove32(sccp_reassembly_ids, source_local_ref);
928
0
    }
929
930
4
    new_tvb = process_reassembled_data(tvb, length_offset + pointer_length, pinfo,
931
4
                                       "Reassembled SCCP", frag_msg,
932
4
                                       &sccp_xudt_msg_frag_items,
933
4
                                       NULL, tree);
934
4
    if (frag_msg) { /* Reassembled */
935
0
      col_append_str(pinfo->cinfo, COL_INFO, "(Message reassembled) ");
936
4
    } else { /* Not last packet of reassembled message */
937
4
      col_append_str(pinfo->cinfo, COL_INFO, "(Message fragment) ");
938
4
    }
939
4
    pinfo->fragmented = save_fragmented;
940
9
  } else {
941
    /*
942
     * There is only a single fragment, reassembly is not required.
943
     */
944
9
    new_tvb = tvb_new_subset_length(tvb, length_offset + pointer_length, fragment_len);
945
9
  }
946
13
  return new_tvb;
947
13
}
948
949
950
#define is_connectionless(m) \
951
1.18k
  ( m == SCCP_MSG_TYPE_UDT || m == SCCP_MSG_TYPE_UDTS      \
952
591
    || m == SCCP_MSG_TYPE_XUDT|| m == SCCP_MSG_TYPE_XUDTS  \
953
591
    || m == SCCP_MSG_TYPE_LUDT|| m == SCCP_MSG_TYPE_LUDTS)
954
955
#define RETURN_FALSE \
956
0
  do { \
957
0
    /*ws_warning("Frame %d not protocol %d @ line %d", frame_num, my_mtp3_standard, __LINE__);*/ \
958
0
    return false; \
959
0
  } while (0)
960
961
962
static void sccp_prompt(packet_info *pinfo _U_, char* result)
963
0
{
964
0
  snprintf(result, MAX_DECODE_AS_PROMPT_LEN, "Dissect SSN %d as",
965
0
     GPOINTER_TO_UINT(p_get_proto_data(pinfo->pool, pinfo, proto_sccp, 0)));
966
0
}
967
968
static void *sccp_value(packet_info *pinfo)
969
0
{
970
0
  return p_get_proto_data(pinfo->pool, pinfo, proto_sccp, 0);
971
0
}
972
973
static bool
974
sccp_called_calling_looks_valid(uint32_t frame_num _U_, tvbuff_t *tvb, uint8_t my_mtp3_standard, bool is_co)
975
0
{
976
0
  uint8_t ai, ri, gti, ssni, pci;
977
0
  uint8_t len_needed = 1;      /* need at least the Address Indicator */
978
0
  unsigned  len        = tvb_reported_length(tvb);
979
980
0
  ai = tvb_get_uint8(tvb, 0);
981
0
  if ((my_mtp3_standard == ANSI_STANDARD) && ((ai & ANSI_NATIONAL_MASK) == 0))
982
0
    RETURN_FALSE;
983
984
0
  gti = (ai & GTI_MASK) >> GTI_SHIFT;
985
0
  if (my_mtp3_standard == ANSI_STANDARD) {
986
0
    if (gti > 2)
987
0
      RETURN_FALSE;
988
0
  } else {
989
0
    if (gti > 4)
990
0
      RETURN_FALSE;
991
0
  }
992
993
0
  ri = (ai & ROUTING_INDICATOR_MASK) >> ROUTING_INDICATOR_SHIFT;
994
0
  if (my_mtp3_standard == ANSI_STANDARD) {
995
0
    pci  = ai & ANSI_PC_INDICATOR_MASK;
996
0
    ssni = ai & ANSI_SSN_INDICATOR_MASK;
997
0
  } else {
998
0
    ssni = ai & ITU_SSN_INDICATOR_MASK;
999
0
    pci  = ai & ITU_PC_INDICATOR_MASK;
1000
0
  }
1001
1002
  /* Route on SSN with no SSN? */
1003
0
  if ((ri == ROUTE_ON_SSN) && (ssni == 0))
1004
0
    RETURN_FALSE;
1005
1006
  /* Route on GT with no GT? */
1007
0
  if ((ri == ROUTE_ON_GT) && (gti == AI_GTI_NO_GT))
1008
0
    RETURN_FALSE;
1009
1010
  /* GT routed and connection-oriented (Class-2)?
1011
   * Yes, that's theoretically possible, but it's not used.
1012
   */
1013
0
  if ((ri == ROUTE_ON_GT) && is_co)
1014
0
    RETURN_FALSE;
1015
1016
0
  if (ssni)
1017
0
    len_needed += ADDRESS_SSN_LENGTH;
1018
0
  if (pci) {
1019
0
    if (my_mtp3_standard == ANSI_STANDARD ||
1020
0
        my_mtp3_standard == CHINESE_ITU_STANDARD)
1021
0
      len_needed += ANSI_PC_LENGTH;
1022
0
    else
1023
0
      len_needed += ITU_PC_LENGTH;
1024
0
  }
1025
0
  if (gti)
1026
0
    len_needed += 2;
1027
1028
0
  if (len_needed > len)
1029
0
    RETURN_FALSE;
1030
1031
0
  return true;
1032
0
}
1033
1034
bool
1035
looks_like_valid_sccp(uint32_t frame_num _U_, tvbuff_t *tvb, uint8_t my_mtp3_standard)
1036
0
{
1037
0
  unsigned  offset;
1038
0
  uint8_t msgtype, msg_class, cause;
1039
0
  unsigned  called_ptr     = 0;
1040
0
  unsigned  calling_ptr    = 0;
1041
0
  unsigned  data_ptr       = 0;
1042
0
  unsigned  opt_ptr        = 0;
1043
0
  uint8_t pointer_length = POINTER_LENGTH;
1044
0
  unsigned  len            = tvb_captured_length(tvb);
1045
1046
  /* Ensure we can do some basic checks without throwing an exception.
1047
   * Accesses beyond this length need to check the length first because
1048
   * we don't want to throw an exception in here...
1049
   */
1050
0
  if (len < 5)
1051
0
    RETURN_FALSE;
1052
1053
0
  msgtype = tvb_get_uint8(tvb, SCCP_MSG_TYPE_OFFSET);
1054
0
  if (!try_val_to_str(msgtype, sccp_message_type_acro_values)) {
1055
0
    RETURN_FALSE;
1056
0
  }
1057
0
  offset = SCCP_MSG_TYPE_LENGTH;
1058
1059
0
  switch (msgtype) {
1060
0
  case SCCP_MSG_TYPE_UDT:
1061
0
  case SCCP_MSG_TYPE_XUDT:
1062
0
  case SCCP_MSG_TYPE_LUDT:
1063
0
  case SCCP_MSG_TYPE_UDTS:
1064
0
  case SCCP_MSG_TYPE_XUDTS:
1065
0
  case SCCP_MSG_TYPE_LUDTS:
1066
0
  {
1067
0
    if (msgtype == SCCP_MSG_TYPE_XUDT || msgtype == SCCP_MSG_TYPE_XUDTS) {
1068
0
      if (SCCP_MSG_TYPE_LENGTH +
1069
0
          PROTOCOL_CLASS_LENGTH + /* or Cause for XUDTS */
1070
0
          HOP_COUNTER_LENGTH +
1071
0
          POINTER_LENGTH +
1072
0
          POINTER_LENGTH +
1073
0
          POINTER_LENGTH +
1074
0
          POINTER_LENGTH > len)
1075
0
        RETURN_FALSE;
1076
0
    }
1077
1078
0
    if (msgtype == SCCP_MSG_TYPE_LUDT || msgtype == SCCP_MSG_TYPE_LUDTS) {
1079
0
      if (SCCP_MSG_TYPE_LENGTH +
1080
0
          PROTOCOL_CLASS_LENGTH + /* or Cause for LUDTS */
1081
0
          HOP_COUNTER_LENGTH +
1082
0
          POINTER_LENGTH_LONG +
1083
0
          POINTER_LENGTH_LONG +
1084
0
          POINTER_LENGTH_LONG +
1085
0
          POINTER_LENGTH_LONG > len)
1086
0
        RETURN_FALSE;
1087
1088
0
      pointer_length = POINTER_LENGTH_LONG;
1089
0
    }
1090
1091
0
    if (msgtype == SCCP_MSG_TYPE_UDT || msgtype == SCCP_MSG_TYPE_XUDT ||
1092
0
        msgtype == SCCP_MSG_TYPE_LUDT) {
1093
1094
0
      msg_class = tvb_get_uint8(tvb, offset) & CLASS_CLASS_MASK;
1095
0
      if (msg_class > 1)
1096
0
        RETURN_FALSE;
1097
0
      offset += PROTOCOL_CLASS_LENGTH;
1098
0
    }
1099
1100
0
    if (msgtype == SCCP_MSG_TYPE_XUDT || msgtype == SCCP_MSG_TYPE_LUDT)
1101
0
      offset += HOP_COUNTER_LENGTH;
1102
1103
0
    if (msgtype == SCCP_MSG_TYPE_UDTS ||
1104
0
        msgtype == SCCP_MSG_TYPE_XUDTS ||
1105
0
        msgtype == SCCP_MSG_TYPE_LUDTS) {
1106
1107
0
      cause = tvb_get_uint8(tvb, offset);
1108
0
      if (!try_val_to_str(cause, sccp_return_cause_values))
1109
0
        RETURN_FALSE;
1110
0
      offset += RETURN_CAUSE_LENGTH;
1111
0
    }
1112
1113
0
    if (msgtype == SCCP_MSG_TYPE_XUDTS || msgtype == SCCP_MSG_TYPE_LUDTS)
1114
0
      offset += HOP_COUNTER_LENGTH;
1115
1116
0
    if (msgtype == SCCP_MSG_TYPE_LUDT || msgtype == SCCP_MSG_TYPE_LUDTS)
1117
0
      called_ptr = tvb_get_letohs(tvb, offset);
1118
0
    else
1119
0
      called_ptr = tvb_get_uint8(tvb, offset);
1120
0
    if (called_ptr == 0) /* Mandatory variable parameters must be present */
1121
0
      RETURN_FALSE;
1122
0
    called_ptr += offset;
1123
0
    offset += pointer_length;
1124
1125
0
    if (msgtype == SCCP_MSG_TYPE_LUDT || msgtype == SCCP_MSG_TYPE_LUDTS)
1126
0
      calling_ptr = tvb_get_letohs(tvb, offset);
1127
0
    else
1128
0
      calling_ptr = tvb_get_uint8(tvb, offset);
1129
0
    if (calling_ptr == 0) /* Mandatory variable parameters must be present */
1130
0
      RETURN_FALSE;
1131
0
    calling_ptr += offset;
1132
0
    offset += pointer_length;
1133
1134
0
    if (msgtype == SCCP_MSG_TYPE_LUDT || msgtype == SCCP_MSG_TYPE_LUDTS)
1135
0
      data_ptr = tvb_get_letohs(tvb, offset);
1136
0
    else
1137
0
      data_ptr = tvb_get_uint8(tvb, offset);
1138
0
    if (data_ptr == 0) /* Mandatory variable parameters must be present */
1139
0
      RETURN_FALSE;
1140
0
    data_ptr += offset;
1141
0
    offset += pointer_length;
1142
1143
0
    if (msgtype == SCCP_MSG_TYPE_XUDT || msgtype == SCCP_MSG_TYPE_XUDTS) {
1144
0
      opt_ptr = tvb_get_uint8(tvb, offset);
1145
0
      offset += POINTER_LENGTH;
1146
0
    } else if (msgtype == SCCP_MSG_TYPE_LUDT || msgtype == SCCP_MSG_TYPE_LUDTS) {
1147
0
      opt_ptr = tvb_get_letohs(tvb, offset);
1148
0
      offset += POINTER_LENGTH_LONG;
1149
0
    }
1150
1151
0
    if (msgtype == SCCP_MSG_TYPE_LUDT || msgtype == SCCP_MSG_TYPE_LUDTS) {
1152
      /* Long pointers count from the 2nd (MSB) octet of the pointer */
1153
0
      called_ptr += 1;
1154
0
      calling_ptr += 1;
1155
0
      data_ptr += 1;
1156
0
      if (opt_ptr)
1157
0
        opt_ptr += 1;
1158
0
    }
1159
1160
    /* Check that the variable pointers are within bounds */
1161
0
    if (called_ptr > len || calling_ptr > len || data_ptr > len)
1162
0
      RETURN_FALSE;
1163
1164
    /* Check that the lengths of the variable parameters are within bounds */
1165
0
    if (tvb_get_uint8(tvb, called_ptr)+called_ptr > len ||
1166
0
        tvb_get_uint8(tvb, calling_ptr)+calling_ptr > len)
1167
0
      RETURN_FALSE;
1168
0
    if (msgtype == SCCP_MSG_TYPE_LUDT || msgtype == SCCP_MSG_TYPE_LUDTS) {
1169
0
      if (tvb_get_letohs(tvb, data_ptr)+data_ptr > len)
1170
0
        RETURN_FALSE;
1171
0
    } else {
1172
0
      if (tvb_get_uint8(tvb, data_ptr)+data_ptr > len)
1173
0
        RETURN_FALSE;
1174
0
    }
1175
0
  }
1176
0
  break;
1177
0
  case SCCP_MSG_TYPE_CR:
1178
0
  {
1179
0
    if (len < SCCP_MSG_TYPE_LENGTH
1180
0
        + DESTINATION_LOCAL_REFERENCE_LENGTH
1181
0
        + PROTOCOL_CLASS_LENGTH
1182
0
        + POINTER_LENGTH
1183
0
        + POINTER_LENGTH)
1184
0
      RETURN_FALSE;
1185
1186
0
    offset += DESTINATION_LOCAL_REFERENCE_LENGTH;
1187
1188
    /* Class is only the lower 4 bits, but the upper 4 bits are spare
1189
     * in Class-2.  Don't mask them off so the below comparison also
1190
     * fails if any of those spare bits are set.
1191
     */
1192
0
    msg_class = tvb_get_uint8(tvb, offset);
1193
0
    if (msg_class != 2)
1194
0
      RETURN_FALSE;
1195
1196
0
    offset += PROTOCOL_CLASS_LENGTH;
1197
0
    data_ptr = tvb_get_uint8(tvb, offset);
1198
0
    if (data_ptr == 0)
1199
0
      RETURN_FALSE;
1200
1201
0
    offset += POINTER_LENGTH;
1202
0
    opt_ptr = tvb_get_uint8(tvb, offset);
1203
0
    if (opt_ptr == 0)
1204
0
      RETURN_FALSE;
1205
1206
0
    offset += POINTER_LENGTH;
1207
0
  }
1208
0
  break;
1209
0
  case SCCP_MSG_TYPE_CC:
1210
0
  {
1211
0
    if (len < SCCP_MSG_TYPE_LENGTH
1212
0
        + DESTINATION_LOCAL_REFERENCE_LENGTH
1213
0
        + SOURCE_LOCAL_REFERENCE_LENGTH
1214
0
        + PROTOCOL_CLASS_LENGTH
1215
0
        + POINTER_LENGTH)
1216
0
      RETURN_FALSE;
1217
1218
0
    offset += DESTINATION_LOCAL_REFERENCE_LENGTH;
1219
0
    offset += SOURCE_LOCAL_REFERENCE_LENGTH;
1220
1221
    /* Class is only the lower 4 bits, but the upper 4 bits are spare
1222
     * in Class-2.  Don't mask them off so the below comparison also
1223
     * fails if any of those spare bits are set.
1224
     */
1225
0
    msg_class = tvb_get_uint8(tvb, offset);
1226
0
    if (msg_class != 2)
1227
0
      RETURN_FALSE;
1228
0
    offset += PROTOCOL_CLASS_LENGTH;
1229
1230
0
    opt_ptr = tvb_get_uint8(tvb, offset);
1231
0
    offset += POINTER_LENGTH;
1232
1233
    /* If the pointer isn't 0 (no optional parameters) or 1 (optional
1234
     * parameter starts immediately after the pointer) then what would
1235
     * be between the pointer and the parameter?
1236
     */
1237
0
    if (opt_ptr > 1)
1238
0
      RETURN_FALSE;
1239
1240
    /* If there are no optional parameters, are we at the end of the
1241
     * message?
1242
     */
1243
0
    if ((opt_ptr == 0) && (offset != len))
1244
0
      RETURN_FALSE;
1245
0
  }
1246
0
  break;
1247
0
  case SCCP_MSG_TYPE_CREF:
1248
0
  {
1249
0
    if (len < SCCP_MSG_TYPE_LENGTH
1250
0
        + DESTINATION_LOCAL_REFERENCE_LENGTH
1251
0
        + REFUSAL_CAUSE_LENGTH
1252
0
        + POINTER_LENGTH)
1253
0
      RETURN_FALSE;
1254
1255
0
    offset += DESTINATION_LOCAL_REFERENCE_LENGTH;
1256
1257
0
    cause = tvb_get_uint8(tvb, offset);
1258
0
    if (!try_val_to_str(cause, sccp_refusal_cause_values))
1259
0
      RETURN_FALSE;
1260
0
    offset += REFUSAL_CAUSE_LENGTH;
1261
1262
0
    opt_ptr = tvb_get_uint8(tvb, offset);
1263
0
    offset += POINTER_LENGTH;
1264
1265
    /* If the pointer isn't 0 (no optional parameters) or 1 (optional
1266
     * parameter starts immediately after the pointer) then what would
1267
     * be between the pointer and the parameter?
1268
     */
1269
0
    if (opt_ptr > 1)
1270
0
      RETURN_FALSE;
1271
1272
    /* If there are no optional parameters, are we at the end of the
1273
     * message?
1274
     */
1275
0
    if ((opt_ptr == 0) && (offset != len))
1276
0
      RETURN_FALSE;
1277
0
  }
1278
0
  break;
1279
0
  case SCCP_MSG_TYPE_RLSD:
1280
0
  {
1281
0
    if (len < SCCP_MSG_TYPE_LENGTH
1282
0
        + DESTINATION_LOCAL_REFERENCE_LENGTH
1283
0
        + SOURCE_LOCAL_REFERENCE_LENGTH
1284
0
        + RELEASE_CAUSE_LENGTH
1285
0
        + POINTER_LENGTH)
1286
0
      RETURN_FALSE;
1287
1288
0
    offset += DESTINATION_LOCAL_REFERENCE_LENGTH;
1289
0
    offset += SOURCE_LOCAL_REFERENCE_LENGTH;
1290
1291
0
    cause = tvb_get_uint8(tvb, offset);
1292
0
    if (!try_val_to_str(cause, sccp_release_cause_values))
1293
0
      RETURN_FALSE;
1294
0
    offset += RELEASE_CAUSE_LENGTH;
1295
1296
0
    opt_ptr = tvb_get_uint8(tvb, offset);
1297
0
    offset += POINTER_LENGTH;
1298
1299
    /* If the pointer isn't 0 (no optional parameters) or 1 (optional
1300
     * parameter starts immediately after the pointer) then what would
1301
     * be between the pointer and the parameter?
1302
     */
1303
0
    if (opt_ptr > 1)
1304
0
      RETURN_FALSE;
1305
1306
    /* If there are no optional parameters, are we at the end of the
1307
     * message?
1308
     */
1309
0
    if ((opt_ptr == 0) && (offset != len))
1310
0
      RETURN_FALSE;
1311
0
  }
1312
0
  break;
1313
0
  case SCCP_MSG_TYPE_RLC:
1314
0
  {
1315
0
    if (len != SCCP_MSG_TYPE_LENGTH
1316
0
        + DESTINATION_LOCAL_REFERENCE_LENGTH
1317
0
        + SOURCE_LOCAL_REFERENCE_LENGTH)
1318
0
      RETURN_FALSE;
1319
0
  }
1320
0
  break;
1321
0
  case SCCP_MSG_TYPE_ERR:
1322
0
  {
1323
0
    if (len != SCCP_MSG_TYPE_LENGTH
1324
0
        + DESTINATION_LOCAL_REFERENCE_LENGTH
1325
0
        + ERROR_CAUSE_LENGTH)
1326
0
      RETURN_FALSE;
1327
1328
0
    offset += DESTINATION_LOCAL_REFERENCE_LENGTH;
1329
1330
0
    cause = tvb_get_uint8(tvb, offset);
1331
0
    if (!try_val_to_str(cause, sccp_error_cause_values))
1332
0
      RETURN_FALSE;
1333
0
  }
1334
0
  break;
1335
0
  case SCCP_MSG_TYPE_DT1:
1336
0
  {
1337
0
    if (len < SCCP_MSG_TYPE_LENGTH
1338
0
        + DESTINATION_LOCAL_REFERENCE_LENGTH
1339
0
        + SEGMENTING_REASSEMBLING_LENGTH
1340
0
        + POINTER_LENGTH
1341
0
        + PARAMETER_LENGTH_LENGTH
1342
0
        + 1) /* At least 1 byte of payload */
1343
0
      RETURN_FALSE;
1344
0
    offset += DESTINATION_LOCAL_REFERENCE_LENGTH;
1345
1346
    /* Are any of the spare bits in set? */
1347
0
    if (tvb_get_uint8(tvb, offset) & ~SEGMENTING_REASSEMBLING_MASK)
1348
0
      RETURN_FALSE;
1349
0
    offset += SEGMENTING_REASSEMBLING_LENGTH;
1350
1351
0
    data_ptr = tvb_get_uint8(tvb, offset) + offset;
1352
    /* Verify the data pointer is within bounds */
1353
0
    if (data_ptr > len)
1354
0
      RETURN_FALSE;
1355
0
    offset += POINTER_LENGTH;
1356
1357
    /* Verify the data length uses the rest of the message */
1358
0
    if (tvb_get_uint8(tvb, data_ptr) + offset + 1U != len)
1359
0
      RETURN_FALSE;
1360
0
  }
1361
0
  break;
1362
0
  case SCCP_MSG_TYPE_IT:
1363
0
  {
1364
0
    if (len < SCCP_MSG_TYPE_LENGTH
1365
0
        + DESTINATION_LOCAL_REFERENCE_LENGTH
1366
0
        + SOURCE_LOCAL_REFERENCE_LENGTH
1367
0
        + PROTOCOL_CLASS_LENGTH
1368
0
        + SEQUENCING_SEGMENTING_LENGTH
1369
0
        + CREDIT_LENGTH)
1370
0
      RETURN_FALSE;
1371
1372
0
    offset += DESTINATION_LOCAL_REFERENCE_LENGTH;
1373
0
    offset += SOURCE_LOCAL_REFERENCE_LENGTH;
1374
1375
    /* Class is only the lower 4 bits, but the upper 4 bits are spare
1376
     * in Class-2.  Don't mask them off so the below comparison also
1377
     * fails if any of those spare bits are set.
1378
     */
1379
0
    msg_class = tvb_get_uint8(tvb, offset);
1380
0
    if (msg_class != 2)
1381
0
      RETURN_FALSE;
1382
0
    offset += PROTOCOL_CLASS_LENGTH;
1383
0
  }
1384
0
  break;
1385
0
  case SCCP_MSG_TYPE_AK:
1386
0
  case SCCP_MSG_TYPE_DT2:
1387
0
  case SCCP_MSG_TYPE_EA:
1388
0
  case SCCP_MSG_TYPE_ED:
1389
0
  case SCCP_MSG_TYPE_RSC:
1390
0
  case SCCP_MSG_TYPE_RSR:
1391
    /* Class-3 is never actually used in the real world */
1392
0
    RETURN_FALSE;
1393
0
    break;
1394
1395
0
  default:
1396
0
    DISSECTOR_ASSERT_NOT_REACHED();
1397
0
  }
1398
1399
0
  if (called_ptr) {
1400
0
    uint8_t param_len = tvb_get_uint8(tvb, called_ptr);
1401
0
    tvbuff_t *param_tvb;
1402
1403
0
    if (param_len == 0)
1404
0
      RETURN_FALSE;
1405
0
    param_tvb = tvb_new_subset_length(tvb, called_ptr+1, param_len);
1406
1407
0
    if (!sccp_called_calling_looks_valid(frame_num, param_tvb, my_mtp3_standard, !is_connectionless(msgtype)))
1408
0
      RETURN_FALSE;
1409
0
  }
1410
1411
0
  if (calling_ptr) {
1412
0
    uint8_t param_len = tvb_get_uint8(tvb, calling_ptr);
1413
0
    tvbuff_t *param_tvb;
1414
1415
0
    if (param_len == 0)
1416
0
      RETURN_FALSE;
1417
0
    param_tvb = tvb_new_subset_length(tvb, calling_ptr+1, param_len);
1418
1419
0
    if (!sccp_called_calling_looks_valid(frame_num, param_tvb, my_mtp3_standard, !is_connectionless(msgtype)))
1420
0
      RETURN_FALSE;
1421
0
  }
1422
1423
0
  if (opt_ptr) {
1424
0
    uint8_t opt_param;
1425
1426
0
    opt_ptr += offset-pointer_length; /* (offset was already incremented) */
1427
1428
    /* Check that the optional pointer is within bounds */
1429
0
    if (opt_ptr > len)
1430
0
      RETURN_FALSE;
1431
1432
0
    opt_param = tvb_get_uint8(tvb, opt_ptr);
1433
    /* Check if the (1st) optional parameter tag is valid */
1434
0
    if (!try_val_to_str(opt_param, sccp_parameter_values))
1435
0
      RETURN_FALSE;
1436
1437
    /* Check that the (1st) parameter length is within bounds */
1438
0
    if ((opt_param != PARAMETER_END_OF_OPTIONAL_PARAMETERS)  &&
1439
0
        ((opt_ptr+1U) <= len) &&
1440
0
        ((tvb_get_uint8(tvb, opt_ptr+1U)+offset) > len))
1441
0
      RETURN_FALSE;
1442
1443
    /* If we're at the end of the parameters, are we also at the end of the
1444
     * message?
1445
     */
1446
0
    if ((opt_param == PARAMETER_END_OF_OPTIONAL_PARAMETERS) && ((opt_ptr+1U) != len))
1447
0
      RETURN_FALSE;
1448
0
  }
1449
1450
0
  return true;
1451
0
}
1452
1453
static sccp_assoc_info_t *
1454
new_assoc(uint32_t calling, uint32_t called)
1455
57
{
1456
57
  sccp_assoc_info_t *a = wmem_new0(wmem_file_scope(), sccp_assoc_info_t);
1457
1458
57
  a->id            = next_assoc_id++;
1459
57
  a->calling_dpc   = calling;
1460
57
  a->called_dpc    = called;
1461
57
  a->calling_ssn   = INVALID_SSN;
1462
57
  a->called_ssn    = INVALID_SSN;
1463
57
  a->msgs          = NULL;
1464
57
  a->curr_msg      = NULL;
1465
57
  a->payload       = SCCP_PLOAD_NONE;
1466
57
  a->calling_party = NULL;
1467
57
  a->called_party  = NULL;
1468
57
  a->extra_info    = NULL;
1469
57
  a->imsi = NULL;
1470
1471
57
  return a;
1472
57
}
1473
1474
sccp_assoc_info_t *
1475
get_sccp_assoc(packet_info *pinfo, unsigned offset, sccp_decode_context_t* value)
1476
270
{
1477
270
  uint32_t opck, dpck;
1478
270
  address *opc = &(pinfo->src);
1479
270
  address *dpc = &(pinfo->dst);
1480
270
  unsigned framenum = pinfo->num;
1481
1482
270
  if (value->assoc)
1483
0
    return value->assoc;
1484
1485
270
  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));
1486
270
  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));
1487
1488
1489
270
  switch (value->message_type) {
1490
100
  case SCCP_MSG_TYPE_CR:
1491
100
  {
1492
    /* CR contains the opc,dpc,dlr key of backward messages swapped as dpc,opc,slr  */
1493
100
    wmem_tree_key_t bw_key[4];
1494
1495
100
    bw_key[0].length = 1;
1496
100
    bw_key[0].key = &dpck;
1497
1498
100
    bw_key[1].length = 1;
1499
100
    bw_key[1].key = &opck;
1500
1501
100
    bw_key[2].length = 1;
1502
100
    bw_key[2].key = &value->slr;
1503
1504
100
    bw_key[3].length = 0;
1505
100
    bw_key[3].key = NULL;
1506
1507
100
    if (! (value->assoc = (sccp_assoc_info_t *)wmem_tree_lookup32_array(assocs, bw_key) ) && ! PINFO_FD_VISITED(pinfo) ) {
1508
32
      value->assoc = new_assoc(opck, dpck);
1509
32
      wmem_tree_insert32_array(assocs, bw_key, value->assoc);
1510
32
      value->assoc->has_bw_key = true;
1511
32
    }
1512
1513
100
    pinfo->p2p_dir = P2P_DIR_SENT;
1514
1515
100
    break;
1516
0
  }
1517
54
  case SCCP_MSG_TYPE_CC:
1518
54
  {
1519
54
    wmem_tree_key_t fw_key[4];
1520
54
    wmem_tree_key_t bw_key[4];
1521
1522
54
    fw_key[0].length = 1;
1523
54
    fw_key[0].key = &dpck;
1524
1525
54
    fw_key[1].length = 1;
1526
54
    fw_key[1].key = &opck;
1527
1528
54
    fw_key[2].length = 1;
1529
54
    fw_key[2].key = &value->slr;
1530
1531
54
    fw_key[3].length = 0;
1532
54
    fw_key[3].key = NULL;
1533
1534
54
    bw_key[0].length = 1;
1535
54
    bw_key[0].key = &opck;
1536
1537
54
    bw_key[1].length = 1;
1538
54
    bw_key[1].key = &dpck;
1539
1540
54
    bw_key[2].length = 1;
1541
54
    bw_key[2].key = &value->dlr;
1542
1543
54
    bw_key[3].length = 0;
1544
54
    bw_key[3].key = NULL;
1545
1546
1547
54
    if ( (value->assoc = (sccp_assoc_info_t *)wmem_tree_lookup32_array(assocs, bw_key) ) ) {
1548
32
      goto got_assoc;
1549
32
    }
1550
1551
22
    if ( (value->assoc = (sccp_assoc_info_t *)wmem_tree_lookup32_array(assocs, fw_key) ) ) {
1552
0
      goto got_assoc;
1553
0
    }
1554
1555
22
    value->assoc = new_assoc(dpck, opck);
1556
1557
54
  got_assoc:
1558
1559
54
    pinfo->p2p_dir = P2P_DIR_RECV;
1560
1561
54
    if ( ! PINFO_FD_VISITED(pinfo) && ! value->assoc->has_bw_key ) {
1562
22
      wmem_tree_insert32_array(assocs, bw_key, value->assoc);
1563
22
      value->assoc->has_bw_key = true;
1564
22
    }
1565
1566
54
    if ( ! PINFO_FD_VISITED(pinfo) && ! value->assoc->has_fw_key ) {
1567
22
      wmem_tree_insert32_array(assocs, fw_key, value->assoc);
1568
22
      value->assoc->has_fw_key = true;
1569
22
    }
1570
1571
54
    break;
1572
22
  }
1573
6
  case SCCP_MSG_TYPE_IT:
1574
    /* fall-through */
1575
7
  case SCCP_MSG_TYPE_RLC:
1576
7
  {
1577
7
    wmem_tree_key_t fw_key[4];
1578
7
    wmem_tree_key_t bw_key[4];
1579
1580
7
    fw_key[0].length = 1;
1581
7
    fw_key[0].key = &dpck;
1582
1583
7
    fw_key[1].length = 1;
1584
7
    fw_key[1].key = &opck;
1585
1586
7
    fw_key[2].length = 1;
1587
7
    fw_key[2].key = &value->slr;
1588
1589
7
    fw_key[3].length = 0;
1590
7
    fw_key[3].key = NULL;
1591
1592
7
    bw_key[0].length = 1;
1593
7
    bw_key[0].key = &opck;
1594
1595
7
    bw_key[1].length = 1;
1596
7
    bw_key[1].key = &dpck;
1597
1598
7
    bw_key[2].length = 1;
1599
7
    bw_key[2].key = &value->dlr;
1600
1601
7
    bw_key[3].length = 0;
1602
7
    bw_key[3].key = NULL;
1603
1604
7
    if ( (value->assoc = (sccp_assoc_info_t *)wmem_tree_lookup32_array(assocs, bw_key) ) ) {
1605
2
      goto got_assoc_rlc;
1606
2
    }
1607
1608
5
    if ( (value->assoc = (sccp_assoc_info_t *)wmem_tree_lookup32_array(assocs, fw_key) ) ) {
1609
2
      goto got_assoc_rlc;
1610
2
    }
1611
1612
3
    value->assoc = new_assoc(dpck, opck);
1613
1614
7
  got_assoc_rlc:
1615
1616
7
    pinfo->p2p_dir = P2P_DIR_SENT;
1617
1618
7
    if ( ! PINFO_FD_VISITED(pinfo) && ! value->assoc->has_bw_key ) {
1619
3
      wmem_tree_insert32_array(assocs, bw_key, value->assoc);
1620
3
      value->assoc->has_bw_key = true;
1621
3
    }
1622
1623
7
    if ( ! PINFO_FD_VISITED(pinfo) && ! value->assoc->has_fw_key ) {
1624
3
      wmem_tree_insert32_array(assocs, fw_key, value->assoc);
1625
3
      value->assoc->has_fw_key = true;
1626
3
    }
1627
7
    break;
1628
3
  }
1629
109
  default:
1630
109
  {
1631
109
    wmem_tree_key_t key[4];
1632
1633
109
    key[0].length = 1;
1634
109
    key[0].key = &opck;
1635
1636
109
    key[1].length = 1;
1637
109
    key[1].key = &dpck;
1638
1639
109
    key[2].length = 1;
1640
109
    key[2].key = &value->dlr;
1641
1642
109
    key[3].length = 0;
1643
109
    key[3].key = NULL;
1644
1645
1646
109
    value->assoc = (sccp_assoc_info_t *)wmem_tree_lookup32_array(assocs, key);
1647
1648
109
    if (value->assoc) {
1649
1
      if (value->assoc->calling_dpc == dpck) {
1650
1
        pinfo->p2p_dir = P2P_DIR_RECV;
1651
1
      } else {
1652
0
        pinfo->p2p_dir = P2P_DIR_SENT;
1653
0
      }
1654
1
    }
1655
1656
109
    break;
1657
3
  }
1658
270
  }
1659
1660
270
  if (value->assoc && trace_sccp) {
1661
0
    if ( ! PINFO_FD_VISITED(pinfo)) {
1662
0
      sccp_msg_info_t *msg = wmem_new0(wmem_file_scope(), sccp_msg_info_t);
1663
0
      msg->framenum = framenum;
1664
0
      msg->offset = offset;
1665
0
      msg->data.co.next = NULL;
1666
0
      msg->data.co.assoc = value->assoc;
1667
0
      msg->data.co.label = NULL;
1668
0
      msg->data.co.comment = NULL;
1669
0
      msg->data.co.imsi = NULL;
1670
0
      msg->type = value->message_type;
1671
1672
0
      if (value->assoc->msgs) {
1673
0
        sccp_msg_info_t *m;
1674
0
        for (m = value->assoc->msgs; m->data.co.next; m = m->data.co.next) ;
1675
0
        m->data.co.next = msg;
1676
0
      } else {
1677
0
        value->assoc->msgs = msg;
1678
0
      }
1679
1680
0
      value->assoc->curr_msg = msg;
1681
1682
0
    } else {
1683
1684
0
      sccp_msg_info_t *m;
1685
1686
0
      for (m = value->assoc->msgs; m; m = m->data.co.next) {
1687
0
        if (m->data.co.imsi != NULL && value->assoc->imsi == NULL) {
1688
0
          value->assoc->imsi = wmem_strdup(wmem_epan_scope(), m->data.co.imsi);
1689
0
        }
1690
0
        if ((m->framenum == framenum) && (m->offset == offset)) {
1691
0
          value->assoc->curr_msg = m;
1692
0
          break;
1693
0
        }
1694
0
      }
1695
0
    }
1696
0
  }
1697
1698
270
  return value->assoc ? value->assoc : &no_assoc;
1699
270
}
1700
1701
1702
static void
1703
dissect_sccp_unknown_message(tvbuff_t *message_tvb, proto_tree *sccp_tree)
1704
10
{
1705
10
  uint32_t message_length;
1706
1707
10
  message_length = tvb_captured_length(message_tvb);
1708
1709
10
  proto_tree_add_bytes_format(sccp_tree, hf_sccp_unknown_message, message_tvb, 0, message_length,
1710
10
                      NULL, "Unknown message (%u byte%s)",
1711
10
                      message_length, plurality(message_length, "", "s"));
1712
10
}
1713
1714
static void
1715
dissect_sccp_unknown_param(tvbuff_t *tvb, proto_tree *tree, uint8_t type, unsigned length)
1716
372
{
1717
372
  proto_tree_add_bytes_format(tree, hf_sccp_unknown_parameter, tvb, 0, length, NULL,
1718
372
                        "Unknown parameter 0x%x (%u byte%s)", type, length, plurality(length, "", "s"));
1719
372
}
1720
1721
static void
1722
dissect_sccp_dlr_param(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned length, sccp_decode_context_t* sccp_info)
1723
476
{
1724
476
  proto_item *lr_item;
1725
1726
476
  if (length != 3) {
1727
383
    proto_tree_add_expert_format(tree, pinfo, &ei_sccp_wrong_length, tvb, 0, length,
1728
383
                                 "Wrong length indicated. Expected 3, got %u", length);
1729
383
    return;
1730
383
  }
1731
1732
93
  sccp_info->dlr = tvb_get_letoh24(tvb, 0);
1733
93
  proto_tree_add_uint(tree, hf_sccp_dlr, tvb, 0, length, sccp_info->dlr);
1734
93
  lr_item = proto_tree_add_uint(tree, hf_sccp_lr, tvb, 0, length, sccp_info->dlr);
1735
93
  proto_item_set_generated(lr_item);
1736
1737
93
  if (show_key_params)
1738
0
    col_append_fstr(pinfo->cinfo, COL_INFO, "DLR=%d ", sccp_info->dlr);
1739
93
}
1740
1741
static void
1742
dissect_sccp_slr_param(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned length, sccp_decode_context_t* sccp_info)
1743
320
{
1744
320
  proto_item *lr_item;
1745
1746
320
  if (length != 3) {
1747
146
    proto_tree_add_expert_format(tree, pinfo, &ei_sccp_wrong_length, tvb, 0, length,
1748
146
                                 "Wrong length indicated. Expected 3, got %u", length);
1749
146
    return;
1750
146
  }
1751
1752
174
  sccp_info->slr = tvb_get_letoh24(tvb, 0);
1753
174
  proto_tree_add_uint(tree, hf_sccp_slr, tvb, 0, length, sccp_info->slr);
1754
174
  lr_item = proto_tree_add_uint(tree, hf_sccp_lr, tvb, 0, length, sccp_info->slr);
1755
174
  proto_item_set_generated(lr_item);
1756
1757
174
  if (show_key_params)
1758
0
    col_append_fstr(pinfo->cinfo, COL_INFO, "SLR=%d ", sccp_info->slr);
1759
174
}
1760
1761
static proto_tree *
1762
dissect_sccp_gt_address_information(tvbuff_t *tvb, packet_info *pinfo,
1763
                                    proto_tree *tree, unsigned length,
1764
                                    bool even_length, bool called,
1765
                                    sccp_decode_context_t* sccp_info)
1766
375
{
1767
375
  unsigned offset = 0;
1768
375
  uint8_t odd_signal, even_signal;
1769
375
  proto_item *digits_item;
1770
375
  proto_tree *digits_tree;
1771
375
  char *gt_digits;
1772
1773
375
  gt_digits = (char *)wmem_alloc0(pinfo->pool, GT_MAX_SIGNALS+1);
1774
1775
19.1k
  while (offset < length) {
1776
18.7k
    odd_signal = tvb_get_uint8(tvb, offset) & GT_ODD_SIGNAL_MASK;
1777
18.7k
    even_signal = tvb_get_uint8(tvb, offset) & GT_EVEN_SIGNAL_MASK;
1778
18.7k
    even_signal >>= GT_EVEN_SIGNAL_SHIFT;
1779
1780
18.7k
    (void) g_strlcat(gt_digits, val_to_str(odd_signal, sccp_address_signal_values,
1781
18.7k
                                    "Unknown: %d"), GT_MAX_SIGNALS+1);
1782
1783
    /* If the last signal is NOT filler */
1784
18.7k
    if (offset != (length - 1) || even_length == true)
1785
18.6k
      (void) g_strlcat(gt_digits, val_to_str(even_signal, sccp_address_signal_values,
1786
18.6k
                                      "Unknown: %d"), GT_MAX_SIGNALS+1);
1787
1788
18.7k
    offset += GT_SIGNAL_LENGTH;
1789
18.7k
  }
1790
1791
375
  if (is_connectionless(sccp_info->message_type) && sccp_info->sccp_msg) {
1792
138
    uint8_t **gt_ptr = called ? &(sccp_info->sccp_msg->data.ud.called_gt) : &(sccp_info->sccp_msg->data.ud.calling_gt);
1793
1794
138
    *gt_ptr  = (uint8_t *)wmem_strdup(pinfo->pool, gt_digits);
1795
138
  }
1796
1797
375
  digits_item = proto_tree_add_string(tree, called ? hf_sccp_called_gt_digits
1798
375
                                      : hf_sccp_calling_gt_digits,
1799
375
                                      tvb, 0, length, gt_digits);
1800
375
  digits_tree = proto_item_add_subtree(digits_item, called ? ett_sccp_called_gt_digits
1801
375
                                       : ett_sccp_calling_gt_digits);
1802
1803
375
  if (set_addresses) {
1804
0
    if (called) {
1805
0
      set_address(&pinfo->dst, AT_STRINGZ, 1+(int)strlen(gt_digits), gt_digits);
1806
0
    } else {
1807
0
      set_address(&pinfo->src, AT_STRINGZ, 1+(int)strlen(gt_digits), gt_digits);
1808
0
    }
1809
0
  }
1810
1811
375
  proto_tree_add_string(digits_tree, hf_sccp_gt_digits, tvb, 0, length, gt_digits);
1812
375
  proto_tree_add_uint(digits_tree, called ? hf_sccp_called_gt_digits_length
1813
375
                      : hf_sccp_calling_gt_digits_length,
1814
375
                      tvb, 0, length, (uint32_t)strlen(gt_digits));
1815
1816
375
  return digits_tree;
1817
375
}
1818
1819
static void
1820
dissect_sccp_global_title(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned length,
1821
                          uint8_t gti, bool called, sccp_decode_context_t* sccp_info)
1822
379
{
1823
379
  proto_item *gt_item;
1824
379
  proto_tree *gt_tree;
1825
379
  proto_tree *digits_tree;
1826
379
  tvbuff_t   *signals_tvb;
1827
379
  unsigned    offset        = 0;
1828
379
  uint8_t     odd_even, nai = 0, np = 0, es;
1829
379
  bool        even          = true;
1830
1831
  /* Shift GTI to where we can work with it */
1832
379
  gti >>= GTI_SHIFT;
1833
1834
379
  gt_tree = proto_tree_add_subtree_format(tree, tvb, offset, length,
1835
379
                                called ? ett_sccp_called_gt : ett_sccp_calling_gt, &gt_item,
1836
379
                                "Global Title 0x%x (%u byte%s)",
1837
379
                                gti, length, plurality(length,"", "s"));
1838
1839
  /* Decode Transaction Type (if present) */
1840
379
  if ((gti == AI_GTI_TT) ||
1841
379
      ((decode_mtp3_standard != ANSI_STANDARD) &&
1842
363
       ((gti == ITU_AI_GTI_TT_NP_ES) || (gti == ITU_AI_GTI_TT_NP_ES_NAI))) ||
1843
379
      ((decode_mtp3_standard == ANSI_STANDARD) && (gti == ANSI_AI_GTI_TT_NP_ES))) {
1844
1845
101
    proto_tree_add_item(gt_tree, called ? hf_sccp_called_gt_tt
1846
101
                        : hf_sccp_calling_gt_tt,
1847
101
                        tvb, offset, GT_TT_LENGTH, ENC_NA);
1848
101
    offset += GT_TT_LENGTH;
1849
101
  }
1850
1851
379
  if (gti == AI_GTI_TT) {
1852
    /* Protocol doesn't tell us, so we ASSUME even... */
1853
16
    even = true;
1854
16
  }
1855
1856
  /* Decode Numbering Plan and Encoding Scheme (if present) */
1857
379
  if (((decode_mtp3_standard != ANSI_STANDARD) &&
1858
379
       ((gti == ITU_AI_GTI_TT_NP_ES) || (gti == ITU_AI_GTI_TT_NP_ES_NAI))) ||
1859
379
      ((decode_mtp3_standard == ANSI_STANDARD) && (gti == ANSI_AI_GTI_TT_NP_ES))) {
1860
1861
85
    np = tvb_get_uint8(tvb, offset) & GT_NP_MASK;
1862
85
    proto_tree_add_uint(gt_tree, called ? hf_sccp_called_gt_np
1863
85
                        : hf_sccp_calling_gt_np,
1864
85
                        tvb, offset, GT_NP_ES_LENGTH, np);
1865
1866
85
    es = tvb_get_uint8(tvb, offset) & GT_ES_MASK;
1867
85
    proto_tree_add_uint(gt_tree, called ? hf_sccp_called_gt_es
1868
85
                        : hf_sccp_calling_gt_es,
1869
85
                        tvb, offset, GT_NP_ES_LENGTH, es);
1870
1871
85
    even = (es == GT_ES_BCD_EVEN) ? true : false;
1872
1873
85
    offset += GT_NP_ES_LENGTH;
1874
85
  }
1875
1876
  /* Decode Nature of Address Indicator (if present) */
1877
379
  if ((decode_mtp3_standard != ANSI_STANDARD) &&
1878
379
      ((gti == ITU_AI_GTI_NAI) || (gti == ITU_AI_GTI_TT_NP_ES_NAI))) {
1879
1880
    /* Decode Odd/Even Indicator (if present) */
1881
172
    if (gti == ITU_AI_GTI_NAI) {
1882
143
      odd_even = tvb_get_uint8(tvb, offset) & GT_OE_MASK;
1883
143
      proto_tree_add_uint(gt_tree, called ? hf_sccp_called_gt_oe
1884
143
                          : hf_sccp_calling_gt_oe,
1885
143
                          tvb, offset, GT_NAI_LENGTH, odd_even);
1886
143
      even = (odd_even == GT_OE_EVEN) ? true : false;
1887
143
    }
1888
1889
172
    nai = tvb_get_uint8(tvb, offset) & GT_NAI_MASK;
1890
172
    proto_tree_add_uint(gt_tree, called ? hf_sccp_called_gt_nai
1891
172
                        : hf_sccp_calling_gt_nai,
1892
172
                        tvb, offset, GT_NAI_LENGTH, nai);
1893
1894
172
    offset += GT_NAI_LENGTH;
1895
172
  }
1896
1897
379
  if(length == 0){
1898
3
      expert_add_info(pinfo, gt_item, &ei_sccp_gt_digits_missing);
1899
3
      return;
1900
3
  }
1901
1902
  /* Decode address signal(s) */
1903
376
  if (length < offset)
1904
0
    return;
1905
1906
376
  signals_tvb = tvb_new_subset_length(tvb, offset, (length - offset));
1907
1908
376
  digits_tree = dissect_sccp_gt_address_information(signals_tvb, pinfo, gt_tree,
1909
376
                                                    (length - offset),
1910
376
                                                    even, called, sccp_info);
1911
1912
  /* Display the country code (if we can) */
1913
376
  switch (np >> GT_NP_SHIFT) {
1914
13
  case GT_NP_ISDN:
1915
17
  case GT_NP_ISDN_MOBILE:
1916
17
    if (nai == GT_NAI_INTERNATIONAL_NUM) {
1917
0
      dissect_e164_cc(signals_tvb, pinfo, digits_tree, 0, E164_ENC_BCD);
1918
0
    }
1919
17
    break;
1920
4
  case GT_NP_LAND_MOBILE:
1921
4
    dissect_e212_mcc_mnc_in_address(signals_tvb, pinfo, digits_tree, 0);
1922
4
    break;
1923
327
  default:
1924
327
    break;
1925
376
  }
1926
376
}
1927
1928
static int
1929
dissect_sccp_3byte_pc(tvbuff_t *tvb, packet_info* pinfo, proto_tree *call_tree, unsigned offset,
1930
                      bool called)
1931
0
{
1932
0
  int hf_pc;
1933
1934
0
  if (decode_mtp3_standard == ANSI_STANDARD)
1935
0
  {
1936
0
    if (called)
1937
0
      hf_pc = hf_sccp_called_ansi_pc;
1938
0
    else
1939
0
      hf_pc = hf_sccp_calling_ansi_pc;
1940
0
  } else /* CHINESE_ITU_STANDARD */ {
1941
0
    if (called)
1942
0
      hf_pc = hf_sccp_called_chinese_pc;
1943
0
    else
1944
0
      hf_pc = hf_sccp_calling_chinese_pc;
1945
0
  }
1946
1947
  /* create and fill the PC tree */
1948
0
  dissect_mtp3_3byte_pc(tvb, pinfo, offset, call_tree,
1949
0
                        called ? ett_sccp_called_pc : ett_sccp_calling_pc,
1950
0
                        hf_pc,
1951
0
                        called ? hf_sccp_called_pc_network : hf_sccp_calling_pc_network,
1952
0
                        called ? hf_sccp_called_pc_cluster : hf_sccp_calling_pc_cluster,
1953
0
                        called ? hf_sccp_called_pc_member  : hf_sccp_calling_pc_member,
1954
0
                        0, 0);
1955
1956
0
  return offset + ANSI_PC_LENGTH;
1957
0
}
1958
1959
/*  FUNCTION dissect_sccp_called_calling_param():
1960
 *  Dissect the Calling or Called Party Address parameters.
1961
 *
1962
 *  The boolean 'called' describes whether this function is decoding a
1963
 *  called (true) or calling (false) party address.  There is simply too
1964
 *  much code in this function to have 2 copies of it (one for called, one
1965
 *  for calling).
1966
 *
1967
 *  NOTE:  this function is called even when (!tree) so that we can get
1968
 *  the SSN and subsequently call subdissectors (if and when there's a data
1969
 *  parameter).  Realistically we should put if (!tree)'s around a lot of the
1970
 *  code, but I think that would make it unreadable--and the expense of not
1971
 *  doing so does not appear to be very high.
1972
 */
1973
static void
1974
dissect_sccp_called_calling_param(tvbuff_t *tvb, proto_tree *tree, packet_info *pinfo,
1975
                                  unsigned length, bool called, sccp_decode_context_t* sccp_info)
1976
453
{
1977
453
  proto_item *call_ai_item, *item, *hidden_item, *expert_item;
1978
453
  proto_tree *call_tree, *call_ai_tree;
1979
453
  unsigned offset;
1980
453
  uint8_t national = 0xFFU, routing_ind, gti, pci, ssni, ssn;
1981
453
  tvbuff_t *gt_tvb;
1982
453
  dissector_handle_t ssn_dissector = NULL, tcap_ssn_dissector = NULL;
1983
453
  const char *ssn_dissector_description = NULL;
1984
453
  const char *tcap_ssn_dissector_description = NULL;
1985
1986
453
  call_tree = proto_tree_add_subtree_format(tree, tvb, 0, length,
1987
453
                                  called ? ett_sccp_called : ett_sccp_calling, NULL,
1988
453
                                  "%s Party address (%u byte%s)",
1989
453
                                  called ? "Called" : "Calling", length,
1990
453
                                  plurality(length, "", "s"));
1991
1992
453
  call_ai_tree = proto_tree_add_subtree(call_tree, tvb, 0,
1993
453
                                     ADDRESS_INDICATOR_LENGTH,
1994
453
                                     called ? ett_sccp_called_ai : ett_sccp_calling_ai, &call_ai_item, "Address Indicator");
1995
1996
453
  if (decode_mtp3_standard == ANSI_STANDARD) {
1997
0
    national = tvb_get_uint8(tvb, 0) & ANSI_NATIONAL_MASK;
1998
0
    expert_item = proto_tree_add_uint(call_ai_tree, called ? hf_sccp_called_ansi_national_indicator
1999
0
                                      : hf_sccp_calling_ansi_national_indicator,
2000
0
                                      tvb, 0, ADDRESS_INDICATOR_LENGTH, national);
2001
0
    if (national == 0)
2002
0
      expert_add_info(pinfo, expert_item, &ei_sccp_international_standard_address);
2003
453
  } else {
2004
453
    uint8_t natl_use_bit = tvb_get_uint8(tvb, 0) & ITU_RESERVED_MASK;
2005
2006
453
    proto_tree_add_uint(call_ai_tree, called ? hf_sccp_called_itu_natl_use_bit
2007
453
                        : hf_sccp_calling_itu_natl_use_bit,
2008
453
                        tvb, 0, ADDRESS_INDICATOR_LENGTH, natl_use_bit);
2009
453
  }
2010
2011
453
  routing_ind = tvb_get_uint8(tvb, 0) & ROUTING_INDICATOR_MASK;
2012
453
  proto_tree_add_uint(call_ai_tree, called ? hf_sccp_called_routing_indicator : hf_sccp_calling_routing_indicator,
2013
453
                      tvb, 0, ADDRESS_INDICATOR_LENGTH, routing_ind);
2014
  /* Only shift off the other bits after adding the item */
2015
453
  routing_ind >>= ROUTING_INDICATOR_SHIFT;
2016
2017
453
  gti = tvb_get_uint8(tvb, 0) & GTI_MASK;
2018
2019
453
  if (decode_mtp3_standard == ITU_STANDARD ||
2020
453
      decode_mtp3_standard == CHINESE_ITU_STANDARD ||
2021
453
      decode_mtp3_standard == JAPAN_STANDARD ||
2022
453
      national == 0) {
2023
2024
450
    proto_tree_add_uint(call_ai_tree,
2025
450
                        called ? hf_sccp_called_itu_global_title_indicator : hf_sccp_calling_itu_global_title_indicator,
2026
450
                        tvb, 0, ADDRESS_INDICATOR_LENGTH, gti);
2027
2028
450
    ssni = tvb_get_uint8(tvb, 0) & ITU_SSN_INDICATOR_MASK;
2029
450
    expert_item = proto_tree_add_uint(call_ai_tree,
2030
450
                                      called ? hf_sccp_called_itu_ssn_indicator : hf_sccp_calling_itu_ssn_indicator,
2031
450
                                      tvb, 0, ADDRESS_INDICATOR_LENGTH, ssni);
2032
450
    if ((routing_ind == ROUTE_ON_SSN) && (ssni == 0)) {
2033
40
      expert_add_info(pinfo, expert_item, &ei_sccp_no_ssn_present);
2034
40
    }
2035
2036
450
    pci = tvb_get_uint8(tvb, 0) & ITU_PC_INDICATOR_MASK;
2037
450
    proto_tree_add_uint(call_ai_tree, called ? hf_sccp_called_itu_point_code_indicator : hf_sccp_calling_itu_point_code_indicator,
2038
450
                        tvb, 0, ADDRESS_INDICATOR_LENGTH, pci);
2039
2040
450
    offset = ADDRESS_INDICATOR_LENGTH;
2041
2042
    /* Dissect PC (if present) */
2043
450
    if (pci) {
2044
191
      if (decode_mtp3_standard == ITU_STANDARD || national == 0) {
2045
191
        if (length < offset + ITU_PC_LENGTH) {
2046
14
          proto_tree_add_expert_format(call_tree, pinfo, &ei_sccp_wrong_length, tvb, 0, -1,
2047
14
                                            "Wrong length indicated (%u) should be at least %u, PC is %u octets",
2048
14
                                            length, offset + ITU_PC_LENGTH, ITU_PC_LENGTH);
2049
14
          return;
2050
14
        }
2051
177
        proto_tree_add_item(call_tree, called ? hf_sccp_called_itu_pc : hf_sccp_calling_itu_pc,
2052
177
                            tvb, offset, ITU_PC_LENGTH, ENC_LITTLE_ENDIAN);
2053
177
        offset += ITU_PC_LENGTH;
2054
2055
177
      } else if (decode_mtp3_standard == JAPAN_STANDARD) {
2056
2057
0
        if (length < offset + JAPAN_PC_LENGTH) {
2058
0
          proto_tree_add_expert_format(call_tree, pinfo, &ei_sccp_wrong_length, tvb, 0, -1,
2059
0
                                            "Wrong length indicated (%u) should be at least %u, PC is %u octets",
2060
0
                                            length, offset + JAPAN_PC_LENGTH, JAPAN_PC_LENGTH);
2061
0
          return;
2062
0
        }
2063
0
        proto_tree_add_item(call_tree, called ? hf_sccp_called_japan_pc : hf_sccp_calling_japan_pc,
2064
0
                            tvb, offset, JAPAN_PC_LENGTH, ENC_LITTLE_ENDIAN);
2065
2066
0
        offset += JAPAN_PC_LENGTH;
2067
2068
0
      } else /* CHINESE_ITU_STANDARD */ {
2069
2070
0
        if (length < offset + ANSI_PC_LENGTH) {
2071
0
          proto_tree_add_expert_format(call_tree, pinfo, &ei_sccp_wrong_length, tvb, 0, -1,
2072
0
                                            "Wrong length indicated (%u) should be at least %u, PC is %u octets",
2073
0
                                            length, offset + ANSI_PC_LENGTH, ANSI_PC_LENGTH);
2074
0
          return;
2075
0
        }
2076
0
        offset = dissect_sccp_3byte_pc(tvb, pinfo, call_tree, offset, called);
2077
2078
0
      }
2079
191
    }
2080
2081
    /* Dissect SSN (if present) */
2082
436
    if (ssni) {
2083
216
      ssn = tvb_get_uint8(tvb, offset);
2084
2085
216
      if ((routing_ind == ROUTE_ON_SSN) && (ssn == 0)) {
2086
5
        expert_add_info(pinfo, expert_item, &ei_sccp_ssn_zero);
2087
5
      }
2088
2089
216
      if (called && sccp_info->assoc)
2090
128
        sccp_info->assoc->called_ssn = ssn;
2091
88
      else if (sccp_info->assoc)
2092
87
        sccp_info->assoc->calling_ssn = ssn;
2093
2094
216
      if (is_connectionless(sccp_info->message_type) && sccp_info->sccp_msg) {
2095
103
        unsigned *ssn_ptr = called ? &(sccp_info->sccp_msg->data.ud.called_ssn) : &(sccp_info->sccp_msg->data.ud.calling_ssn);
2096
2097
103
        *ssn_ptr  = ssn;
2098
103
      }
2099
2100
216
      proto_tree_add_uint(call_tree, called ? hf_sccp_called_ssn
2101
216
                          : hf_sccp_calling_ssn,
2102
216
                          tvb, offset, ADDRESS_SSN_LENGTH, ssn);
2103
216
      hidden_item = proto_tree_add_uint(call_tree, hf_sccp_ssn, tvb, offset,
2104
216
                                        ADDRESS_SSN_LENGTH, ssn);
2105
216
      proto_item_set_hidden(hidden_item);
2106
2107
216
      offset += ADDRESS_SSN_LENGTH;
2108
2109
      /* Get the dissector handle of the dissector registered for this ssn
2110
       * And print its name.
2111
       */
2112
216
      ssn_dissector = dissector_get_uint_handle(sccp_ssn_dissector_table, ssn);
2113
2114
216
      if (ssn_dissector) {
2115
85
        ssn_dissector_description = dissector_handle_get_description(ssn_dissector);
2116
2117
85
        if (ssn_dissector_description) {
2118
85
          item = proto_tree_add_string_format(call_tree, hf_sccp_linked_dissector, tvb, offset - 1, ADDRESS_SSN_LENGTH,
2119
85
                                     ssn_dissector_description, "Linked to %s", ssn_dissector_description);
2120
85
          proto_item_set_generated(item);
2121
2122
85
          if (g_ascii_strncasecmp("TCAP", ssn_dissector_description, 4)== 0) {
2123
64
            tcap_ssn_dissector = get_itu_tcap_subdissector(ssn);
2124
2125
64
            if (tcap_ssn_dissector) {
2126
35
              tcap_ssn_dissector_description = dissector_handle_get_description(tcap_ssn_dissector);
2127
35
              proto_item_append_text(item,", TCAP SSN linked to %s", tcap_ssn_dissector_description);
2128
35
            }
2129
64
          }
2130
85
        } /* short name */
2131
85
      } /* ssn_dissector */
2132
216
    } /* ssni */
2133
2134
    /* Dissect GT (if present) */
2135
436
    if (gti != AI_GTI_NO_GT) {
2136
379
      if (length < offset)
2137
0
        return;
2138
2139
379
      gt_tvb = tvb_new_subset_length(tvb, offset, (length - offset));
2140
379
      dissect_sccp_global_title(gt_tvb, pinfo, call_tree, (length - offset), gti,
2141
379
                                called, sccp_info);
2142
379
    }
2143
2144
436
  } else if (decode_mtp3_standard == ANSI_STANDARD) {
2145
2146
0
    proto_tree_add_uint(call_ai_tree, called ? hf_sccp_called_ansi_global_title_indicator
2147
0
                        : hf_sccp_calling_ansi_global_title_indicator,
2148
0
                        tvb, 0, ADDRESS_INDICATOR_LENGTH, gti);
2149
2150
0
    pci = tvb_get_uint8(tvb, 0) & ANSI_PC_INDICATOR_MASK;
2151
0
    proto_tree_add_uint(call_ai_tree, called ? hf_sccp_called_ansi_point_code_indicator
2152
0
                        : hf_sccp_calling_ansi_point_code_indicator,
2153
0
                        tvb, 0, ADDRESS_INDICATOR_LENGTH, pci);
2154
2155
0
    ssni = tvb_get_uint8(tvb, 0) & ANSI_SSN_INDICATOR_MASK;
2156
0
    expert_item = proto_tree_add_uint(call_ai_tree, called ? hf_sccp_called_ansi_ssn_indicator
2157
0
                                      : hf_sccp_calling_ansi_ssn_indicator,
2158
0
                                      tvb, 0, ADDRESS_INDICATOR_LENGTH, ssni);
2159
0
    if ((routing_ind == ROUTE_ON_SSN) && (ssni == 0)) {
2160
0
      expert_add_info(pinfo, expert_item, &ei_sccp_no_ssn_present);
2161
0
    }
2162
2163
0
    offset = ADDRESS_INDICATOR_LENGTH;
2164
2165
    /* Dissect SSN (if present) */
2166
0
    if (ssni) {
2167
0
      ssn = tvb_get_uint8(tvb, offset);
2168
2169
0
      if ((routing_ind == ROUTE_ON_SSN) && (ssn == 0)) {
2170
0
        expert_add_info(pinfo, expert_item, &ei_sccp_ssn_zero);
2171
0
      }
2172
2173
0
      if (called && sccp_info->assoc) {
2174
0
        sccp_info->assoc->called_ssn = ssn;
2175
0
      } else if (sccp_info->assoc) {
2176
0
        sccp_info->assoc->calling_ssn = ssn;
2177
0
      }
2178
2179
0
      if (is_connectionless(sccp_info->message_type) && sccp_info->sccp_msg) {
2180
0
        unsigned *ssn_ptr = called ? &(sccp_info->sccp_msg->data.ud.called_ssn) : &(sccp_info->sccp_msg->data.ud.calling_ssn);
2181
2182
0
        *ssn_ptr  = ssn;
2183
0
      }
2184
2185
0
      proto_tree_add_uint(call_tree, called ? hf_sccp_called_ssn
2186
0
                          : hf_sccp_calling_ssn,
2187
0
                          tvb, offset, ADDRESS_SSN_LENGTH, ssn);
2188
0
      hidden_item = proto_tree_add_uint(call_tree, hf_sccp_ssn, tvb, offset,
2189
0
                                        ADDRESS_SSN_LENGTH, ssn);
2190
0
      proto_item_set_hidden(hidden_item);
2191
2192
0
      offset += ADDRESS_SSN_LENGTH;
2193
0
    }
2194
2195
    /* Dissect PC (if present) */
2196
0
    if (pci) {
2197
0
      offset = dissect_sccp_3byte_pc(tvb, pinfo, call_tree, offset, called);
2198
0
    }
2199
2200
    /* Dissect GT (if present) */
2201
0
    if (gti != AI_GTI_NO_GT) {
2202
0
      if (length < offset)
2203
0
        return;
2204
0
      gt_tvb = tvb_new_subset_length(tvb, offset, (length - offset));
2205
0
      dissect_sccp_global_title(gt_tvb, pinfo, call_tree, (length - offset), gti,
2206
0
                                called, sccp_info);
2207
0
    }
2208
2209
0
  }
2210
2211
453
}
2212
2213
static void
2214
dissect_sccp_called_param(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned length, sccp_decode_context_t* sccp_info)
2215
224
{
2216
224
  dissect_sccp_called_calling_param(tvb, tree, pinfo, length, true, sccp_info);
2217
224
}
2218
2219
static void
2220
dissect_sccp_calling_param(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned length, sccp_decode_context_t* sccp_info)
2221
229
{
2222
229
  dissect_sccp_called_calling_param(tvb, tree, pinfo, length, false, sccp_info);
2223
229
}
2224
2225
static void
2226
dissect_sccp_class_param(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned length, sccp_decode_context_t* sccp_info)
2227
271
{
2228
271
  uint8_t     msg_class;
2229
271
  proto_item *pi;
2230
271
  bool        invalid_class = false;
2231
2232
271
  if (length != 1) {
2233
60
    proto_tree_add_expert_format(tree, pinfo, &ei_sccp_wrong_length, tvb, 0, length,
2234
60
                                 "Wrong length indicated. Expected 1, got %u", length);
2235
60
    return;
2236
60
  }
2237
2238
211
  msg_class = tvb_get_uint8(tvb, 0) & CLASS_CLASS_MASK;
2239
211
  pi = proto_tree_add_uint(tree, hf_sccp_class, tvb, 0, length, msg_class);
2240
2241
211
  switch (sccp_info->message_type) {
2242
0
  case SCCP_MSG_TYPE_DT1:
2243
0
    if (msg_class != 2)
2244
0
      invalid_class = true;
2245
0
    break;
2246
0
  case SCCP_MSG_TYPE_DT2:
2247
0
  case SCCP_MSG_TYPE_AK:
2248
0
  case SCCP_MSG_TYPE_ED:
2249
0
  case SCCP_MSG_TYPE_EA:
2250
0
  case SCCP_MSG_TYPE_RSR:
2251
0
  case SCCP_MSG_TYPE_RSC:
2252
0
    if (msg_class != 3)
2253
0
      invalid_class = true;
2254
0
    break;
2255
102
  case SCCP_MSG_TYPE_CR:
2256
156
  case SCCP_MSG_TYPE_CC:
2257
156
  case SCCP_MSG_TYPE_CREF:
2258
157
  case SCCP_MSG_TYPE_RLSD:
2259
157
  case SCCP_MSG_TYPE_RLC:
2260
157
  case SCCP_MSG_TYPE_ERR:
2261
163
  case SCCP_MSG_TYPE_IT:
2262
163
    if ((msg_class != 2) && (msg_class != 3))
2263
139
      invalid_class = true;
2264
163
    break;
2265
6
  case SCCP_MSG_TYPE_UDT:
2266
6
  case SCCP_MSG_TYPE_UDTS:
2267
47
  case SCCP_MSG_TYPE_XUDT:
2268
47
  case SCCP_MSG_TYPE_XUDTS:
2269
48
  case SCCP_MSG_TYPE_LUDT:
2270
48
  case SCCP_MSG_TYPE_LUDTS:
2271
48
    if ((msg_class != 0) && (msg_class != 1))
2272
9
      invalid_class = true;
2273
48
    break;
2274
211
  }
2275
2276
211
  if (invalid_class)
2277
148
    expert_add_info(pinfo, pi, &ei_sccp_class_unexpected);
2278
2279
211
  if (msg_class == 0 || msg_class == 1) {
2280
92
    uint8_t handling = tvb_get_uint8(tvb, 0) & CLASS_SPARE_HANDLING_MASK;
2281
2282
92
    pi = proto_tree_add_item(tree, hf_sccp_handling, tvb, 0, length, ENC_NA);
2283
92
    handling >>= CLASS_SPARE_HANDLING_SHIFT;
2284
2285
92
    if (try_val_to_str(handling, sccp_class_handling_values) == NULL) {
2286
50
      expert_add_info(pinfo, pi, &ei_sccp_handling_invalid);
2287
50
    }
2288
92
  }
2289
211
}
2290
2291
static void
2292
dissect_sccp_segmenting_reassembling_param(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned length)
2293
72
{
2294
72
  if (length != 1) {
2295
66
    proto_tree_add_expert_format(tree, pinfo, &ei_sccp_wrong_length, tvb, 0, length,
2296
66
                                 "Wrong length indicated. Expected 1, got %u", length);
2297
66
    return;
2298
66
  }
2299
2300
6
  proto_tree_add_item(tree, hf_sccp_more, tvb, 0, length, ENC_BIG_ENDIAN);
2301
6
}
2302
2303
static void
2304
dissect_sccp_receive_sequence_number_param(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned length)
2305
35
{
2306
35
  if (length != 1) {
2307
33
    proto_tree_add_expert_format(tree, pinfo, &ei_sccp_wrong_length, tvb, 0, length,
2308
33
                                 "Wrong length indicated. Expected 1, got %u", length);
2309
33
    return;
2310
33
  }
2311
2312
2
  proto_tree_add_item(tree, hf_sccp_rsn, tvb, 0, length, ENC_NA);
2313
2
}
2314
2315
static void
2316
dissect_sccp_sequencing_segmenting_param(tvbuff_t *tvb, proto_tree *tree, unsigned length)
2317
29
{
2318
29
  proto_tree *param_tree;
2319
2320
29
  param_tree = proto_tree_add_subtree(tree, tvb, 0, length, ett_sccp_sequencing_segmenting, NULL,
2321
29
                                   val_to_str(PARAMETER_SEQUENCING_SEGMENTING,
2322
29
                                              sccp_parameter_values, "Unknown: %d"));
2323
2324
29
  proto_tree_add_item(param_tree, hf_sccp_sequencing_segmenting_ssn, tvb, 0,
2325
29
                      SEQUENCING_SEGMENTING_SSN_LENGTH, ENC_NA);
2326
29
  proto_tree_add_item(param_tree, hf_sccp_sequencing_segmenting_rsn, tvb,
2327
29
                      SEQUENCING_SEGMENTING_SSN_LENGTH,
2328
29
                      SEQUENCING_SEGMENTING_RSN_LENGTH, ENC_NA);
2329
29
  proto_tree_add_item(param_tree, hf_sccp_sequencing_segmenting_more, tvb,
2330
29
                      SEQUENCING_SEGMENTING_SSN_LENGTH,
2331
29
                      SEQUENCING_SEGMENTING_RSN_LENGTH, ENC_NA);
2332
29
}
2333
2334
static void
2335
dissect_sccp_credit_param(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned length)
2336
47
{
2337
47
  if (length != 1) {
2338
33
    proto_tree_add_expert_format(tree, pinfo, &ei_sccp_wrong_length, tvb, 0, length,
2339
33
                           "Wrong length indicated. Expected 1, got %u", length);
2340
33
    return;
2341
33
  }
2342
2343
14
  proto_tree_add_item(tree, hf_sccp_credit, tvb, 0, length, ENC_NA);
2344
14
}
2345
2346
static void
2347
dissect_sccp_release_cause_param(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned length)
2348
36
{
2349
36
  if (length != 1) {
2350
27
    proto_tree_add_expert_format(tree, pinfo, &ei_sccp_wrong_length, tvb, 0, length,
2351
27
                           "Wrong length indicated. Expected 1, got %u", length);
2352
27
    return;
2353
27
  }
2354
2355
9
  proto_tree_add_item(tree, hf_sccp_release_cause, tvb, 0, length, ENC_LITTLE_ENDIAN);
2356
2357
9
  if (show_key_params)
2358
0
    col_append_fstr(pinfo->cinfo, COL_INFO, "Cause=%d ", tvb_get_uint8(tvb, 0));
2359
9
}
2360
2361
static void
2362
dissect_sccp_return_cause_param(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned length)
2363
118
{
2364
118
  if (length != 1) {
2365
81
    proto_tree_add_expert_format(tree, pinfo, &ei_sccp_wrong_length, tvb, 0, length,
2366
81
                           "Wrong length indicated. Expected 1, got %u", length);
2367
81
    return;
2368
81
  }
2369
2370
37
  proto_tree_add_item(tree, hf_sccp_return_cause, tvb, 0, length, ENC_LITTLE_ENDIAN);
2371
2372
37
  if (show_key_params)
2373
0
    col_append_fstr(pinfo->cinfo, COL_INFO, "Cause=%d ", tvb_get_uint8(tvb, 0));
2374
37
}
2375
2376
static void
2377
dissect_sccp_reset_cause_param(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned length)
2378
15
{
2379
15
  if (length != 1) {
2380
15
    proto_tree_add_expert_format(tree, pinfo, &ei_sccp_wrong_length, tvb, 0, length,
2381
15
                           "Wrong length indicated. Expected 1, got %u", length);
2382
15
    return;
2383
15
  }
2384
2385
0
  proto_tree_add_item(tree, hf_sccp_reset_cause, tvb, 0, length, ENC_LITTLE_ENDIAN);
2386
2387
0
  if (show_key_params)
2388
0
    col_append_fstr(pinfo->cinfo, COL_INFO, "Cause=%d ", tvb_get_uint8(tvb, 0));
2389
0
}
2390
2391
static void
2392
dissect_sccp_error_cause_param(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned length)
2393
29
{
2394
29
  if (length != 1) {
2395
27
    proto_tree_add_expert_format(tree, pinfo, &ei_sccp_wrong_length, tvb, 0, length,
2396
27
                                 "Wrong length indicated. Expected 1, got %u", length);
2397
27
    return;
2398
27
  }
2399
2400
2
  proto_tree_add_item(tree, hf_sccp_error_cause, tvb, 0, length, ENC_LITTLE_ENDIAN);
2401
2402
2
  if (show_key_params)
2403
0
    col_append_fstr(pinfo->cinfo, COL_INFO, "Cause=%d ", tvb_get_uint8(tvb, 0));
2404
2
}
2405
2406
static void
2407
dissect_sccp_refusal_cause_param(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned length)
2408
61
{
2409
61
  if (length != 1) {
2410
50
    proto_tree_add_expert_format(tree, pinfo, &ei_sccp_wrong_length, tvb, 0, length,
2411
50
                                 "Wrong length indicated. Expected 1, got %u", length);
2412
50
    return;
2413
50
  }
2414
2415
11
  proto_tree_add_item(tree, hf_sccp_refusal_cause, tvb, 0, length, ENC_LITTLE_ENDIAN);
2416
2417
11
  if (show_key_params)
2418
0
    col_append_fstr(pinfo->cinfo, COL_INFO, "Cause=%d ", tvb_get_uint8(tvb, 0));
2419
11
}
2420
2421
2422
/* This function is used for both data and long data (ITU only) parameters */
2423
static void
2424
dissect_sccp_data_param(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, sccp_assoc_info_t *assoc)
2425
177
{
2426
177
  uint8_t ssn = INVALID_SSN;
2427
177
  uint8_t other_ssn = INVALID_SSN;
2428
177
  const mtp3_addr_pc_t *dpc = NULL;
2429
177
  const mtp3_addr_pc_t *opc = NULL;
2430
177
  heur_dtbl_entry_t *hdtbl_entry;
2431
177
  struct _sccp_msg_info_t* sccp_info = NULL;
2432
2433
177
  if ((trace_sccp) && (assoc && assoc != &no_assoc)) {
2434
0
    sccp_info = assoc->curr_msg;
2435
0
  }
2436
2437
177
  if (assoc) {
2438
177
    switch (pinfo->p2p_dir) {
2439
54
    case P2P_DIR_SENT:
2440
54
      ssn = assoc->calling_ssn;
2441
54
      other_ssn = assoc->called_ssn;
2442
54
      dpc = (const mtp3_addr_pc_t*)pinfo->dst.data;
2443
54
      opc = (const mtp3_addr_pc_t*)pinfo->src.data;
2444
54
      break;
2445
23
    case P2P_DIR_RECV:
2446
23
      ssn = assoc->called_ssn;
2447
23
      other_ssn = assoc->calling_ssn;
2448
23
      dpc = (const mtp3_addr_pc_t*)pinfo->src.data;
2449
23
      opc = (const mtp3_addr_pc_t*)pinfo->dst.data;
2450
23
      break;
2451
100
    default:
2452
100
      ssn = assoc->called_ssn;
2453
100
      other_ssn = assoc->calling_ssn;
2454
100
      dpc = (const mtp3_addr_pc_t*)pinfo->dst.data;
2455
100
      opc = (const mtp3_addr_pc_t*)pinfo->src.data;
2456
100
      break;
2457
177
    }
2458
177
  }
2459
2460
2461
177
  if ((num_sccp_users) && (pinfo->src.type == ss7pc_address_type)) {
2462
0
    unsigned i;
2463
0
    dissector_handle_t handle = NULL;
2464
0
    bool uses_tcap = false;
2465
2466
0
    for (i=0; i < num_sccp_users; i++) {
2467
0
      sccp_user_t *u = &(sccp_users[i]);
2468
2469
0
      if (!dpc || dpc->ni != u->ni) continue;
2470
2471
0
      if (value_is_in_range(u->called_ssn, ssn)  && value_is_in_range(u->called_pc, dpc->pc) ) {
2472
0
        handle = *(u->handlep);
2473
0
        uses_tcap = u->uses_tcap;
2474
0
        break;
2475
0
      } else if (value_is_in_range(u->called_ssn, other_ssn) && opc && value_is_in_range(u->called_pc, opc->pc) ) {
2476
0
        handle = *(u->handlep);
2477
0
        uses_tcap = u->uses_tcap;
2478
0
        break;
2479
0
      }
2480
0
    }
2481
2482
0
    if (handle) {
2483
0
      if (uses_tcap) {
2484
0
        call_tcap_dissector(handle, tvb, pinfo, tree);
2485
0
      } else {
2486
0
        call_dissector_with_data(handle, tvb, pinfo, tree, sccp_info);
2487
0
      }
2488
0
      return;
2489
0
    }
2490
2491
0
  }
2492
2493
  /* Save SSN for Decode As */
2494
177
  p_add_proto_data(pinfo->pool, pinfo, proto_sccp, 0, GUINT_TO_POINTER((unsigned)ssn));
2495
2496
177
  if ((ssn != INVALID_SSN) && dissector_try_uint_with_data(sccp_ssn_dissector_table, ssn, tvb, pinfo, tree, true, sccp_info)) {
2497
27
    return;
2498
27
  }
2499
2500
150
  if ((other_ssn != INVALID_SSN) && dissector_try_uint_with_data(sccp_ssn_dissector_table, other_ssn, tvb, pinfo, tree, true, sccp_info)) {
2501
34
    return;
2502
34
  }
2503
2504
  /* try heuristic subdissector list to see if there are any takers */
2505
116
  if (dissector_try_heuristic(heur_subdissector_list, tvb, pinfo, tree, &hdtbl_entry, sccp_info)) {
2506
0
    return;
2507
0
  }
2508
2509
  /* try user default subdissector */
2510
116
  if (default_handle) {
2511
0
    call_dissector_with_data(default_handle, tvb, pinfo, tree, sccp_info);
2512
0
    return;
2513
0
  }
2514
2515
  /* No sub-dissection occurred, treat it as raw data */
2516
116
  call_dissector(data_handle, tvb, pinfo, tree);
2517
2518
116
}
2519
2520
static void
2521
dissect_sccp_segmentation_param(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned length)
2522
50
{
2523
50
  proto_tree *param_tree;
2524
2525
50
  param_tree = proto_tree_add_subtree(tree, tvb, 0, length, ett_sccp_segmentation, NULL,
2526
50
                                   val_to_str(PARAMETER_SEGMENTATION,
2527
50
                                              sccp_parameter_values, "Unknown: %d"));
2528
2529
50
  proto_tree_add_item(param_tree, hf_sccp_segmentation_first, tvb, 0, 1, ENC_NA);
2530
50
  proto_tree_add_item(param_tree, hf_sccp_segmentation_class, tvb, 0, 1, ENC_NA);
2531
50
  proto_tree_add_item(param_tree, hf_sccp_segmentation_remaining, tvb, 0, 1, ENC_NA);
2532
2533
50
  if (length-1 != 3) {
2534
48
    proto_tree_add_expert_format(tree, pinfo, &ei_sccp_wrong_length, tvb, 0, length-1,
2535
48
                                 "Wrong length indicated. Expected 3, got %u", length-1);
2536
48
    return;
2537
48
  }
2538
2539
2
  proto_tree_add_item(param_tree, hf_sccp_segmentation_slr, tvb, 1, length-1, ENC_LITTLE_ENDIAN);
2540
2
}
2541
2542
static void
2543
dissect_sccp_hop_counter_param(tvbuff_t *tvb, proto_tree *tree, unsigned length)
2544
74
{
2545
74
  uint8_t hops;
2546
2547
74
  hops = tvb_get_uint8(tvb, 0);
2548
74
  proto_tree_add_uint(tree, hf_sccp_hop_counter, tvb, 0, length, hops);
2549
74
}
2550
2551
static void
2552
dissect_sccp_importance_param(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned length)
2553
68
{
2554
68
  if (length != 1) {
2555
68
    proto_tree_add_expert_format(tree, pinfo, &ei_sccp_wrong_length, tvb, 0, length,
2556
68
                                 "Wrong length indicated. Expected 1, got %u", length);
2557
68
    return;
2558
68
  }
2559
2560
0
  proto_tree_add_item(tree, hf_sccp_importance, tvb, 0, length, ENC_NA);
2561
0
}
2562
2563
static void
2564
dissect_sccp_isni_param(tvbuff_t *tvb, proto_tree *tree, unsigned length)
2565
0
{
2566
0
  uint8_t ti;
2567
0
  unsigned offset = 0;
2568
0
  proto_tree *param_tree;
2569
2570
  /* Create a subtree for ISNI Routing Control */
2571
0
  param_tree = proto_tree_add_subtree(tree, tvb, offset, ANSI_ISNI_ROUTING_CONTROL_LENGTH,
2572
0
                                   ett_sccp_ansi_isni_routing_control, NULL, "ISNI Routing Control");
2573
2574
0
  proto_tree_add_item(param_tree, hf_sccp_ansi_isni_mi, tvb, offset,
2575
0
                      ANSI_ISNI_ROUTING_CONTROL_LENGTH, ENC_NA);
2576
2577
0
  proto_tree_add_item(param_tree, hf_sccp_ansi_isni_iri, tvb, offset,
2578
0
                      ANSI_ISNI_ROUTING_CONTROL_LENGTH, ENC_NA);
2579
2580
0
  ti = tvb_get_uint8(tvb, offset) & ANSI_ISNI_TI_MASK;
2581
0
  proto_tree_add_uint(param_tree, hf_sccp_ansi_isni_ti, tvb, offset,
2582
0
                      ANSI_ISNI_ROUTING_CONTROL_LENGTH, ti);
2583
2584
0
  proto_tree_add_item(param_tree, hf_sccp_ansi_isni_counter, tvb, offset,
2585
0
                      ANSI_ISNI_ROUTING_CONTROL_LENGTH, ENC_NA);
2586
2587
0
  offset += ANSI_ISNI_ROUTING_CONTROL_LENGTH;
2588
2589
0
  if ((ti >> ANSI_ISNI_TI_SHIFT) == ANSI_ISNI_TYPE_1) {
2590
0
    proto_tree_add_uint(param_tree, hf_sccp_ansi_isni_netspec, tvb, offset,
2591
0
                        ANSI_ISNI_ROUTING_CONTROL_LENGTH, ti);
2592
0
    offset += ANSI_ISNI_ROUTING_CONTROL_LENGTH;
2593
0
  }
2594
2595
0
  while (offset < length) {
2596
2597
0
    proto_tree_add_item(tree, hf_sccp_ansi_isni_network, tvb, offset,
2598
0
                        ANSI_NCM_LENGTH, ENC_NA);
2599
0
    offset++;
2600
2601
0
    proto_tree_add_item(tree, hf_sccp_ansi_isni_cluster, tvb, offset,
2602
0
                        ANSI_NCM_LENGTH, ENC_NA);
2603
0
    offset++;
2604
0
  }
2605
2606
0
}
2607
2608
/*  FUNCTION dissect_sccp_parameter():
2609
 *  Dissect a parameter given its type, offset into tvb, and length.
2610
 */
2611
static uint16_t
2612
dissect_sccp_parameter(tvbuff_t *tvb, packet_info *pinfo, proto_tree *sccp_tree,
2613
                       proto_tree *tree, uint8_t parameter_type, int offset,
2614
                       uint16_t parameter_length, sccp_decode_context_t *sccp_info)
2615
2.76k
{
2616
2.76k
  tvbuff_t *parameter_tvb;
2617
2618
2.76k
  switch (parameter_type) {
2619
224
  case PARAMETER_CALLED_PARTY_ADDRESS:
2620
453
  case PARAMETER_CALLING_PARTY_ADDRESS:
2621
618
  case PARAMETER_DATA:
2622
621
  case PARAMETER_LONG_DATA:
2623
941
  case PARAMETER_SOURCE_LOCAL_REFERENCE:
2624
1.41k
  case PARAMETER_DESTINATION_LOCAL_REFERENCE:
2625
1.45k
  case PARAMETER_RELEASE_CAUSE:
2626
1.57k
  case PARAMETER_RETURN_CAUSE:
2627
1.58k
  case PARAMETER_RESET_CAUSE:
2628
1.61k
  case PARAMETER_ERROR_CAUSE:
2629
1.67k
  case PARAMETER_REFUSAL_CAUSE:
2630
2631
    /*  These parameters must be dissected even if !sccp_tree (so that
2632
     *  assoc information can be created).
2633
     */
2634
1.67k
    break;
2635
2636
1.09k
  default:
2637
1.09k
    if (!sccp_tree) return parameter_length;
2638
2639
2.76k
  }
2640
2641
2.76k
  parameter_tvb = tvb_new_subset_length(tvb, offset, parameter_length);
2642
2643
2.76k
  switch (parameter_type) {
2644
2645
72
  case PARAMETER_END_OF_OPTIONAL_PARAMETERS:
2646
72
    proto_tree_add_item(sccp_tree, hf_sccp_end_optional_param, tvb, offset, parameter_length, ENC_NA);
2647
72
    break;
2648
2649
476
  case PARAMETER_DESTINATION_LOCAL_REFERENCE:
2650
476
    dissect_sccp_dlr_param(parameter_tvb, pinfo, sccp_tree, parameter_length, sccp_info);
2651
476
    break;
2652
2653
320
  case PARAMETER_SOURCE_LOCAL_REFERENCE:
2654
320
    dissect_sccp_slr_param(parameter_tvb, pinfo, sccp_tree, parameter_length, sccp_info);
2655
320
    break;
2656
2657
224
  case PARAMETER_CALLED_PARTY_ADDRESS:
2658
224
    dissect_sccp_called_param(parameter_tvb, pinfo, sccp_tree, parameter_length, sccp_info);
2659
224
    break;
2660
2661
229
  case PARAMETER_CALLING_PARTY_ADDRESS:
2662
229
    dissect_sccp_calling_param(parameter_tvb, pinfo, sccp_tree, parameter_length, sccp_info);
2663
229
    break;
2664
2665
271
  case PARAMETER_CLASS:
2666
271
    dissect_sccp_class_param(parameter_tvb, pinfo, sccp_tree, parameter_length, sccp_info);
2667
271
    break;
2668
2669
72
  case PARAMETER_SEGMENTING_REASSEMBLING:
2670
72
    dissect_sccp_segmenting_reassembling_param(parameter_tvb, pinfo, sccp_tree,
2671
72
                                               parameter_length);
2672
72
    break;
2673
2674
35
  case PARAMETER_RECEIVE_SEQUENCE_NUMBER:
2675
35
    dissect_sccp_receive_sequence_number_param(parameter_tvb, pinfo, sccp_tree,
2676
35
                                               parameter_length);
2677
35
    break;
2678
2679
29
  case PARAMETER_SEQUENCING_SEGMENTING:
2680
29
    dissect_sccp_sequencing_segmenting_param(parameter_tvb, sccp_tree,
2681
29
                                             parameter_length);
2682
29
    break;
2683
2684
47
  case PARAMETER_CREDIT:
2685
47
    dissect_sccp_credit_param(parameter_tvb, pinfo, sccp_tree, parameter_length);
2686
47
    break;
2687
2688
36
  case PARAMETER_RELEASE_CAUSE:
2689
36
    dissect_sccp_release_cause_param(parameter_tvb, pinfo, sccp_tree, parameter_length);
2690
36
    break;
2691
2692
118
  case PARAMETER_RETURN_CAUSE:
2693
118
    dissect_sccp_return_cause_param(parameter_tvb, pinfo, sccp_tree, parameter_length);
2694
118
    break;
2695
2696
15
  case PARAMETER_RESET_CAUSE:
2697
15
    dissect_sccp_reset_cause_param(parameter_tvb, pinfo, sccp_tree, parameter_length);
2698
15
    break;
2699
2700
29
  case PARAMETER_ERROR_CAUSE:
2701
29
    dissect_sccp_error_cause_param(parameter_tvb, pinfo, sccp_tree, parameter_length);
2702
29
    break;
2703
2704
61
  case PARAMETER_REFUSAL_CAUSE:
2705
61
    dissect_sccp_refusal_cause_param(parameter_tvb, pinfo, sccp_tree, parameter_length);
2706
61
    break;
2707
2708
165
  case PARAMETER_DATA:
2709
165
    dissect_sccp_data_param(parameter_tvb, pinfo, tree, sccp_info->assoc);
2710
2711
    /* TODO? Re-adjust length of SCCP item since it may be sub-dissected */
2712
    /* sccp_length = proto_item_get_len(sccp_item);
2713
     * sccp_length -= parameter_length;
2714
     * proto_item_set_len(sccp_item, sccp_length);
2715
     *
2716
     * except that proto_item_get_len() is *NOT* guaranteed to return
2717
     * a correct value - if the item has been "faked", it will be wrong
2718
     */
2719
165
    break;
2720
2721
50
  case PARAMETER_SEGMENTATION:
2722
50
    dissect_sccp_segmentation_param(parameter_tvb, pinfo, sccp_tree, parameter_length);
2723
50
    break;
2724
2725
74
  case PARAMETER_HOP_COUNTER:
2726
74
    dissect_sccp_hop_counter_param(parameter_tvb, sccp_tree, parameter_length);
2727
74
    break;
2728
2729
68
  case PARAMETER_IMPORTANCE:
2730
68
    if (decode_mtp3_standard != ANSI_STANDARD)
2731
68
      dissect_sccp_importance_param(parameter_tvb, pinfo, sccp_tree, parameter_length);
2732
0
    else
2733
0
      dissect_sccp_unknown_param(parameter_tvb, sccp_tree, parameter_type,
2734
0
                                 parameter_length);
2735
68
    break;
2736
2737
3
  case PARAMETER_LONG_DATA:
2738
3
    dissect_sccp_data_param(parameter_tvb, pinfo, tree, sccp_info->assoc);
2739
3
    break;
2740
2741
7
  case PARAMETER_ISNI:
2742
7
    if (decode_mtp3_standard != ANSI_STANDARD)
2743
7
      dissect_sccp_unknown_param(parameter_tvb, sccp_tree, parameter_type,
2744
7
                                 parameter_length);
2745
0
    else
2746
0
      dissect_sccp_isni_param(parameter_tvb, sccp_tree, parameter_length);
2747
7
    break;
2748
2749
365
  default:
2750
365
    dissect_sccp_unknown_param(parameter_tvb, sccp_tree, parameter_type,
2751
365
                               parameter_length);
2752
365
    break;
2753
2.76k
  }
2754
2755
2.63k
  return parameter_length;
2756
2.76k
}
2757
2758
/*  FUNCTION dissect_sccp_variable_parameter():
2759
 *  Dissect a variable parameter given its type and offset into tvb.  Length
2760
 *  of the parameter is gotten from tvb[0].
2761
 *  Length returned is sum of (length + parameter).
2762
 */
2763
static uint16_t
2764
dissect_sccp_variable_parameter(tvbuff_t *tvb, packet_info *pinfo,
2765
                                proto_tree *sccp_tree, proto_tree *tree,
2766
                                uint8_t parameter_type, int offset, sccp_decode_context_t* sccp_info)
2767
2.09k
{
2768
2.09k
  int         remaining_length;
2769
2.09k
  uint16_t    parameter_length;
2770
2.09k
  uint8_t     length_length;
2771
2.09k
  proto_item *pi;
2772
2773
2.09k
  if (parameter_type != PARAMETER_LONG_DATA) {
2774
2.09k
    parameter_length = tvb_get_uint8(tvb, offset);
2775
2.09k
    length_length = PARAMETER_LENGTH_LENGTH;
2776
2.09k
  } else {
2777
    /* Long data parameter has 16 bit length */
2778
3
    parameter_length = tvb_get_letohs(tvb, offset);
2779
3
    length_length = PARAMETER_LONG_DATA_LENGTH_LENGTH;
2780
3
  }
2781
2782
2.09k
  pi = proto_tree_add_uint_format(sccp_tree, hf_sccp_param_length, tvb, offset,
2783
2.09k
                                  length_length, parameter_length, "%s length: %d",
2784
2.09k
                                  val_to_str(parameter_type, sccp_parameter_values,
2785
2.09k
                                             "Unknown: %d"),
2786
2.09k
                                  parameter_length);
2787
2.09k
  remaining_length = tvb_reported_length_remaining(tvb, offset + length_length);
2788
2.09k
  if (parameter_type == PARAMETER_DATA && remaining_length > 255 && parameter_length == 255) {
2789
3
    expert_add_info_format(pinfo, pi, &ei_sccp_externally_reassembled, "Possibly externally reassembled (remaining length %u > %u), check SCCP preferences", remaining_length, parameter_length);
2790
3
    if (dt1_ignore_length) {
2791
0
      parameter_length = remaining_length;
2792
0
    }
2793
2.09k
  } else if (!sccp_show_length) {
2794
    /* The user doesn't want to see it... */
2795
    /* Show the length anyway, though, if there was an error. */
2796
2.08k
    proto_item_set_hidden(pi);
2797
2.08k
  }
2798
2799
2.09k
  offset += length_length;
2800
2801
2.09k
  dissect_sccp_parameter(tvb, pinfo, sccp_tree, tree, parameter_type, offset,
2802
2.09k
                         parameter_length, sccp_info);
2803
2804
2.09k
  return parameter_length + length_length;
2805
2.09k
}
2806
2807
/*  FUNCTION dissect_sccp_optional_parameters():
2808
 *  Dissect all the optional parameters given the start of the optional
2809
 *  parameters into tvb.  Parameter types and lengths are read from tvb.
2810
 */
2811
static void
2812
dissect_sccp_optional_parameters(tvbuff_t *tvb, packet_info *pinfo,
2813
                                 proto_tree *sccp_tree, proto_tree *tree,
2814
                                 int offset, sccp_decode_context_t* sccp_info)
2815
206
{
2816
206
  uint8_t parameter_type;
2817
2818
2.00k
  while ((parameter_type = tvb_get_uint8(tvb, offset)) !=
2819
2.00k
         PARAMETER_END_OF_OPTIONAL_PARAMETERS) {
2820
2821
1.79k
    offset += PARAMETER_TYPE_LENGTH;
2822
1.79k
    offset += dissect_sccp_variable_parameter(tvb, pinfo, sccp_tree, tree,
2823
1.79k
                                              parameter_type, offset, sccp_info);
2824
1.79k
  }
2825
2826
  /* Process end of optional parameters */
2827
206
  dissect_sccp_parameter(tvb, pinfo, sccp_tree, tree, parameter_type, offset,
2828
206
                         END_OF_OPTIONAL_PARAMETERS_LENGTH, sccp_info);
2829
2830
206
}
2831
2832
static sccp_msg_info_t *
2833
new_ud_msg(packet_info *pinfo, uint32_t msg_type _U_)
2834
82
{
2835
82
  sccp_msg_info_t *m = wmem_new0(pinfo->pool, sccp_msg_info_t);
2836
82
  m->framenum = pinfo->num;
2837
82
  m->data.ud.calling_gt = NULL;
2838
82
  m->data.ud.called_gt = NULL;
2839
2840
82
  return m;
2841
82
}
2842
2843
static void build_assoc_tree(tvbuff_t *tvb, packet_info *pinfo, proto_tree *sccp_tree,
2844
                             sccp_decode_context_t *sccp_info, unsigned msg_offset)
2845
269
{
2846
269
  if (trace_sccp && sccp_info->assoc && (sccp_info->assoc != &no_assoc)) {
2847
0
    proto_item *pi = proto_tree_add_uint(sccp_tree, hf_sccp_assoc_id, tvb, 0, 0, sccp_info->assoc->id);
2848
0
    proto_item_set_generated(pi);
2849
0
    proto_tree *pt = proto_item_add_subtree(pi, ett_sccp_assoc);
2850
0
    if(sccp_info->assoc->imsi){
2851
0
      proto_item *pi2 = proto_tree_add_string(sccp_tree, hf_assoc_imsi, tvb, 0, 0, sccp_info->assoc->imsi);
2852
0
      proto_item_set_generated(pi2);
2853
0
    }
2854
0
    if (sccp_info->assoc->msgs) {
2855
0
      sccp_msg_info_t *m;
2856
0
      for(m = sccp_info->assoc->msgs; m ; m = m->data.co.next) {
2857
0
        pi = proto_tree_add_uint(pt, hf_sccp_assoc_msg, tvb, 0, 0, m->framenum);
2858
2859
0
        if (sccp_info->assoc->payload != SCCP_PLOAD_NONE)
2860
0
          proto_item_append_text(pi," %s", val_to_str(sccp_info->assoc->payload, assoc_protos, "Unknown: %d"));
2861
2862
0
        if (m->data.co.label)
2863
0
          proto_item_append_text(pi," %s", m->data.co.label);
2864
0
        if (m->data.co.imsi)
2865
0
          proto_item_append_text(pi, " %s", m->data.co.imsi);
2866
2867
0
        if ((m->framenum == pinfo->num) && (m->offset == msg_offset) ) {
2868
0
          tap_queue_packet(sccp_tap, pinfo, m);
2869
0
          proto_item_append_text(pi," (current)");
2870
0
        }
2871
0
        proto_item_set_generated(pi);
2872
0
      }
2873
0
    }
2874
0
  }
2875
269
}
2876
2877
static int
2878
dissect_xudt_common(tvbuff_t *tvb, packet_info *pinfo, proto_tree *sccp_tree,
2879
                    proto_tree *tree, int offset, sccp_decode_context_t *sccp_info,
2880
                    uint16_t *optional_pointer_p, uint16_t *orig_opt_ptr_p,
2881
                    uint8_t pointer_length)
2882
70
{
2883
70
  uint16_t  variable_pointer1 = 0, variable_pointer2 = 0, variable_pointer3 = 0;
2884
70
  uint16_t  optional_pointer  = 0, orig_opt_ptr = 0, optional_pointer1 = 0;
2885
70
  uint8_t   optional_param_type = 0;
2886
70
  tvbuff_t *new_tvb = NULL;
2887
70
  uint32_t  source_local_ref = 0;
2888
70
  unsigned  msg_offset = tvb_offset_from_real_beginning(tvb);
2889
2890
/* Macro for getting pointer to mandatory variable parameters */
2891
70
#define VARIABLE_POINTER(var, hf_var, ptr_size) \
2892
352
  do {                                          \
2893
352
    if (ptr_size == POINTER_LENGTH)             \
2894
352
      var = tvb_get_uint8(tvb, offset);        \
2895
352
    else                                        \
2896
352
      var = tvb_get_letohs(tvb, offset);        \
2897
352
    proto_tree_add_uint(sccp_tree, hf_var, tvb, \
2898
352
                        offset, ptr_size, var); \
2899
352
    var += offset;                              \
2900
352
    if (ptr_size == POINTER_LENGTH_LONG)        \
2901
352
      var += 1;                                 \
2902
352
    offset += ptr_size;                         \
2903
352
  } while (0)
2904
2905
/* Macro for getting pointer to optional parameters */
2906
70
#define OPTIONAL_POINTER(ptr_size)                                      \
2907
240
  do {                                                                  \
2908
240
    if (ptr_size == POINTER_LENGTH)                                     \
2909
240
      orig_opt_ptr = optional_pointer = tvb_get_uint8(tvb, offset);    \
2910
240
    else                                                                \
2911
240
      orig_opt_ptr = optional_pointer = tvb_get_letohs(tvb, offset);    \
2912
240
    proto_tree_add_uint(sccp_tree, hf_sccp_optional_pointer, tvb,       \
2913
240
                        offset, ptr_size, optional_pointer);            \
2914
240
    optional_pointer += offset;                                         \
2915
240
    if (ptr_size == POINTER_LENGTH_LONG)                                \
2916
240
      optional_pointer += 1;                                            \
2917
240
    offset += ptr_size;                                                 \
2918
240
  } while (0)
2919
2920
2921
    /*  Optional parameters are Segmentation and Importance
2922
     *  NOTE 2 - Segmentation Should not be present in case of a single XUDT
2923
     *  message.
2924
     */
2925
2926
70
  VARIABLE_POINTER(variable_pointer1, hf_sccp_variable_pointer1, pointer_length);
2927
70
  VARIABLE_POINTER(variable_pointer2, hf_sccp_variable_pointer2, pointer_length);
2928
70
  VARIABLE_POINTER(variable_pointer3, hf_sccp_variable_pointer3, pointer_length);
2929
70
  OPTIONAL_POINTER(pointer_length);
2930
2931
70
  sccp_info->assoc = get_sccp_assoc(pinfo, msg_offset, sccp_info);
2932
70
  build_assoc_tree(tvb, pinfo, sccp_tree, sccp_info, msg_offset);
2933
2934
70
  dissect_sccp_variable_parameter(tvb, pinfo, sccp_tree, tree,
2935
70
                                  PARAMETER_CALLED_PARTY_ADDRESS,
2936
70
                                  variable_pointer1, sccp_info);
2937
70
  dissect_sccp_variable_parameter(tvb, pinfo, sccp_tree, tree,
2938
70
                                  PARAMETER_CALLING_PARTY_ADDRESS,
2939
70
                                  variable_pointer2, sccp_info);
2940
2941
2942
70
  optional_pointer1 = optional_pointer;
2943
298
  while((optional_param_type = tvb_get_uint8(tvb, optional_pointer1)) != PARAMETER_END_OF_OPTIONAL_PARAMETERS) {
2944
236
    if (optional_param_type == PARAMETER_SEGMENTATION)
2945
8
      break;
2946
228
    optional_pointer1 += PARAMETER_TYPE_LENGTH;
2947
228
    optional_pointer1 += tvb_get_uint8(tvb, optional_pointer1) + PARAMETER_LENGTH_LENGTH;
2948
228
  }
2949
2950
70
  if (tvb_get_uint8(tvb, optional_pointer1) == PARAMETER_SEGMENTATION) {
2951
8
    if (!sccp_reassemble) {
2952
0
      proto_tree_add_item(sccp_tree, hf_sccp_segmented_data, tvb, variable_pointer3, tvb_get_uint8(tvb, variable_pointer3)+1, ENC_NA);
2953
8
    } else {
2954
8
      uint8_t octet;
2955
8
      bool more_frag = true;
2956
2957
      /* Get the first octet of parameter Segmentation, Ch 3.17 in Q.713
2958
       * Bit 8 of octet 1 is used for First segment indication
2959
       * Bit 7 of octet 1 is used to keep in the message in sequence
2960
       *         delivery option required by the SCCP user
2961
       * Bits 6 and 5 in octet 1 are spare bits.
2962
       * Bits 4-1 of octet 1 are used to indicate the number of
2963
       *            remaining segments.
2964
       * The values 0000 to 1111 are possible; the value 0000 indicates
2965
       * the last segment.
2966
       */
2967
8
      octet = tvb_get_uint8(tvb, optional_pointer1+2);
2968
8
      source_local_ref = tvb_get_letoh24(tvb, optional_pointer1+3);
2969
2970
8
      if ((octet & 0x0f) == 0)
2971
6
        more_frag = false;
2972
2973
8
      new_tvb = sccp_reassemble_fragments(tvb, pinfo, tree, variable_pointer3, source_local_ref, more_frag, pointer_length);
2974
2975
8
      if (new_tvb)
2976
6
        dissect_sccp_data_param(new_tvb, pinfo, tree, sccp_info->assoc);
2977
8
    }
2978
62
  } else {
2979
62
    dissect_sccp_variable_parameter(tvb, pinfo, sccp_tree, tree,
2980
62
                                    (pointer_length == POINTER_LENGTH) ? PARAMETER_DATA : PARAMETER_LONG_DATA,
2981
62
                                    variable_pointer3, sccp_info);
2982
62
  }
2983
2984
70
  *optional_pointer_p = optional_pointer;
2985
70
  *orig_opt_ptr_p = orig_opt_ptr;
2986
70
  return offset;
2987
70
}
2988
2989
static int
2990
dissect_sccp_message(tvbuff_t *tvb, packet_info *pinfo, proto_tree *sccp_tree,
2991
                     proto_tree *tree)
2992
281
{
2993
281
  uint16_t  variable_pointer1 = 0, variable_pointer2 = 0, variable_pointer3 = 0;
2994
281
  uint16_t  optional_pointer  = 0, orig_opt_ptr = 0;
2995
281
  int   offset = 0;
2996
281
  tvbuff_t *new_tvb = NULL;
2997
281
  uint32_t  source_local_ref = 0;
2998
281
  uint8_t   more;
2999
281
  unsigned  msg_offset = tvb_offset_from_real_beginning(tvb);
3000
281
  sccp_decode_context_t sccp_info = {0, INVALID_LR, INVALID_LR, NULL, NULL};
3001
3002
  /* Extract the message type;  all other processing is based on this */
3003
281
  sccp_info.message_type   = tvb_get_uint8(tvb, SCCP_MSG_TYPE_OFFSET);
3004
281
  offset = SCCP_MSG_TYPE_LENGTH;
3005
3006
  /*  Do not change col_add_fstr() to col_append_fstr() here: we _want_
3007
   *  this call to overwrite whatever's currently in the INFO column (e.g.,
3008
   *  "DATA" from the SCTP dissector).
3009
   *
3010
   *  If there's something there that should not be overwritten, whoever
3011
   *  put that info there should call col_set_fence() to protect it.
3012
   */
3013
281
  col_add_fstr(pinfo->cinfo, COL_INFO, "%s ",
3014
281
               val_to_str(sccp_info.message_type, sccp_message_type_acro_values, "Unknown: %d"));
3015
3016
281
  if (sccp_tree) {
3017
    /* add the message type to the protocol tree */
3018
281
    proto_tree_add_uint(sccp_tree, hf_sccp_message_type, tvb,
3019
281
                        SCCP_MSG_TYPE_OFFSET, SCCP_MSG_TYPE_LENGTH, sccp_info.message_type);
3020
3021
281
  };
3022
3023
281
  no_assoc.calling_dpc   = 0;
3024
281
  no_assoc.called_dpc    = 0;
3025
281
  no_assoc.calling_ssn   = INVALID_SSN;
3026
281
  no_assoc.called_ssn    = INVALID_SSN;
3027
281
  no_assoc.has_fw_key    = false;
3028
281
  no_assoc.has_bw_key    = false;
3029
281
  no_assoc.payload       = SCCP_PLOAD_NONE;
3030
281
  no_assoc.called_party  = NULL;
3031
281
  no_assoc.calling_party = NULL;
3032
281
  no_assoc.extra_info    = NULL;
3033
3034
281
  switch (sccp_info.message_type) {
3035
100
  case SCCP_MSG_TYPE_CR:
3036
    /*  TTC and NTT (Japan) say that the connection-oriented messages are
3037
     *  deleted (not standardized), but they appear to be used anyway, so
3038
     *  we'll dissect it...
3039
     */
3040
100
    offset += dissect_sccp_parameter(tvb, pinfo, sccp_tree, tree,
3041
100
                                     PARAMETER_SOURCE_LOCAL_REFERENCE,
3042
100
                                     offset, SOURCE_LOCAL_REFERENCE_LENGTH, &sccp_info);
3043
100
    offset += dissect_sccp_parameter(tvb, pinfo, sccp_tree, tree,
3044
100
                                     PARAMETER_CLASS, offset,
3045
100
                                     PROTOCOL_CLASS_LENGTH, &sccp_info);
3046
100
    sccp_info.assoc = get_sccp_assoc(pinfo, msg_offset, &sccp_info);
3047
100
    build_assoc_tree(tvb, pinfo, sccp_tree, &sccp_info, msg_offset);
3048
3049
100
    VARIABLE_POINTER(variable_pointer1, hf_sccp_variable_pointer1, POINTER_LENGTH);
3050
100
    OPTIONAL_POINTER(POINTER_LENGTH);
3051
3052
100
    dissect_sccp_variable_parameter(tvb, pinfo, sccp_tree, tree,
3053
100
                                    PARAMETER_CALLED_PARTY_ADDRESS,
3054
100
                                    variable_pointer1, &sccp_info);
3055
100
    break;
3056
3057
54
  case SCCP_MSG_TYPE_CC:
3058
    /*  TODO: connection has been established;  theoretically we could keep
3059
     *  keep track of the SLR/DLR with the called/calling from the CR and
3060
     *  track the connection (e.g., on subsequent messages regarding this
3061
     *  SLR we could set the global vars "call*_ssn" so data could get
3062
     *  sub-dissected).
3063
     */
3064
54
    offset += dissect_sccp_parameter(tvb, pinfo, sccp_tree, tree,
3065
54
                                     PARAMETER_DESTINATION_LOCAL_REFERENCE,
3066
54
                                     offset,
3067
54
                                     DESTINATION_LOCAL_REFERENCE_LENGTH, &sccp_info);
3068
54
    offset += dissect_sccp_parameter(tvb, pinfo, sccp_tree, tree,
3069
54
                                     PARAMETER_SOURCE_LOCAL_REFERENCE,
3070
54
                                     offset, SOURCE_LOCAL_REFERENCE_LENGTH, &sccp_info);
3071
3072
54
    sccp_info.assoc = get_sccp_assoc(pinfo, msg_offset, &sccp_info);
3073
54
    build_assoc_tree(tvb, pinfo, sccp_tree, &sccp_info, msg_offset);
3074
3075
54
    offset += dissect_sccp_parameter(tvb, pinfo, sccp_tree, tree,
3076
54
                                     PARAMETER_CLASS, offset,
3077
54
                                     PROTOCOL_CLASS_LENGTH, &sccp_info);
3078
54
    OPTIONAL_POINTER(POINTER_LENGTH);
3079
54
    break;
3080
3081
8
  case SCCP_MSG_TYPE_CREF:
3082
8
    offset += dissect_sccp_parameter(tvb, pinfo, sccp_tree, tree,
3083
8
                                     PARAMETER_DESTINATION_LOCAL_REFERENCE,
3084
8
                                     offset,
3085
8
                                     DESTINATION_LOCAL_REFERENCE_LENGTH, &sccp_info);
3086
3087
8
    sccp_info.assoc = get_sccp_assoc(pinfo, msg_offset, &sccp_info);
3088
8
    build_assoc_tree(tvb, pinfo, sccp_tree, &sccp_info, msg_offset);
3089
3090
8
    offset += dissect_sccp_parameter(tvb, pinfo, sccp_tree, tree,
3091
8
                                     PARAMETER_REFUSAL_CAUSE, offset,
3092
8
                                     REFUSAL_CAUSE_LENGTH, &sccp_info);
3093
8
    OPTIONAL_POINTER(POINTER_LENGTH);
3094
8
    break;
3095
3096
8
  case SCCP_MSG_TYPE_RLSD:
3097
8
    offset += dissect_sccp_parameter(tvb, pinfo, sccp_tree, tree,
3098
8
                                     PARAMETER_DESTINATION_LOCAL_REFERENCE,
3099
8
                                     offset,
3100
8
                                     DESTINATION_LOCAL_REFERENCE_LENGTH, &sccp_info);
3101
8
    offset += dissect_sccp_parameter(tvb, pinfo, sccp_tree, tree,
3102
8
                                     PARAMETER_SOURCE_LOCAL_REFERENCE,
3103
8
                                     offset, SOURCE_LOCAL_REFERENCE_LENGTH, &sccp_info);
3104
3105
8
    sccp_info.assoc = get_sccp_assoc(pinfo, msg_offset, &sccp_info);
3106
8
    build_assoc_tree(tvb, pinfo, sccp_tree, &sccp_info, msg_offset);
3107
3108
8
    offset += dissect_sccp_parameter(tvb, pinfo, sccp_tree, tree,
3109
8
                                     PARAMETER_RELEASE_CAUSE, offset,
3110
8
                                     RELEASE_CAUSE_LENGTH, &sccp_info);
3111
3112
8
    OPTIONAL_POINTER(POINTER_LENGTH);
3113
8
    break;
3114
3115
1
  case SCCP_MSG_TYPE_RLC:
3116
1
    offset += dissect_sccp_parameter(tvb, pinfo, sccp_tree, tree,
3117
1
                                     PARAMETER_DESTINATION_LOCAL_REFERENCE,
3118
1
                                     offset,
3119
1
                                     DESTINATION_LOCAL_REFERENCE_LENGTH, &sccp_info);
3120
1
    offset += dissect_sccp_parameter(tvb, pinfo, sccp_tree, tree,
3121
1
                                     PARAMETER_SOURCE_LOCAL_REFERENCE,
3122
1
                                     offset, SOURCE_LOCAL_REFERENCE_LENGTH, &sccp_info);
3123
3124
1
    sccp_info.assoc = get_sccp_assoc(pinfo, msg_offset, &sccp_info);
3125
1
    build_assoc_tree(tvb, pinfo, sccp_tree, &sccp_info, msg_offset);
3126
1
    break;
3127
3128
5
  case SCCP_MSG_TYPE_DT1:
3129
5
  {
3130
5
    int remaining_length;
3131
5
    source_local_ref = tvb_get_letoh24(tvb, offset);
3132
5
    offset += dissect_sccp_parameter(tvb, pinfo, sccp_tree, tree,
3133
5
                                     PARAMETER_DESTINATION_LOCAL_REFERENCE,
3134
5
                                     offset,
3135
5
                                     DESTINATION_LOCAL_REFERENCE_LENGTH, &sccp_info);
3136
3137
5
    sccp_info.assoc = get_sccp_assoc(pinfo, msg_offset, &sccp_info);
3138
5
    build_assoc_tree(tvb, pinfo, sccp_tree, &sccp_info, msg_offset);
3139
3140
5
    more = tvb_get_uint8(tvb, offset) & SEGMENTING_REASSEMBLING_MASK;
3141
3142
5
    offset += dissect_sccp_parameter(tvb, pinfo, sccp_tree, tree,
3143
5
                                     PARAMETER_SEGMENTING_REASSEMBLING,
3144
5
                                     offset, SEGMENTING_REASSEMBLING_LENGTH, &sccp_info);
3145
5
    VARIABLE_POINTER(variable_pointer1, hf_sccp_variable_pointer1, POINTER_LENGTH);
3146
3147
    /* Reassemble */
3148
5
    if (!sccp_reassemble) {
3149
0
      proto_tree_add_item(sccp_tree, hf_sccp_segmented_data, tvb, variable_pointer1,
3150
0
                          tvb_get_uint8(tvb, variable_pointer1)+1, ENC_NA);
3151
0
      dissect_sccp_variable_parameter(tvb, pinfo, sccp_tree, tree,
3152
0
                                      PARAMETER_DATA, variable_pointer1, &sccp_info);
3153
3154
5
    } else {
3155
5
      remaining_length = tvb_reported_length_remaining(tvb, variable_pointer1 + 1);
3156
5
      if(dt1_ignore_length && remaining_length > 255) {
3157
0
        new_tvb = tvb_new_subset_length(tvb, variable_pointer1 + 1, remaining_length);
3158
5
      } else {
3159
5
        new_tvb = sccp_reassemble_fragments(tvb, pinfo, tree, variable_pointer1, source_local_ref, more, POINTER_LENGTH);
3160
5
      }
3161
3162
5
      if (new_tvb)
3163
3
        dissect_sccp_data_param(new_tvb, pinfo, tree, sccp_info.assoc);
3164
5
    }
3165
3166
    /* End reassemble */
3167
5
    break;
3168
0
  }
3169
3170
1
  case SCCP_MSG_TYPE_DT2:
3171
1
    offset += dissect_sccp_parameter(tvb, pinfo, sccp_tree, tree,
3172
1
                                     PARAMETER_DESTINATION_LOCAL_REFERENCE,
3173
1
                                     offset,
3174
1
                                     DESTINATION_LOCAL_REFERENCE_LENGTH, &sccp_info);
3175
3176
1
    sccp_info.assoc = get_sccp_assoc(pinfo, msg_offset, &sccp_info);
3177
1
    build_assoc_tree(tvb, pinfo, sccp_tree, &sccp_info, msg_offset);
3178
3179
1
    offset += dissect_sccp_parameter(tvb, pinfo, sccp_tree, tree,
3180
1
                                     PARAMETER_SEQUENCING_SEGMENTING, offset,
3181
1
                                     SEQUENCING_SEGMENTING_LENGTH, &sccp_info);
3182
1
    VARIABLE_POINTER(variable_pointer1, hf_sccp_variable_pointer1, POINTER_LENGTH);
3183
3184
1
    dissect_sccp_variable_parameter(tvb, pinfo, sccp_tree, tree,
3185
1
                                      PARAMETER_DATA, variable_pointer1, &sccp_info);
3186
3187
1
    break;
3188
3189
1
  case SCCP_MSG_TYPE_AK:
3190
1
    offset += dissect_sccp_parameter(tvb, pinfo, sccp_tree, tree,
3191
1
                                     PARAMETER_DESTINATION_LOCAL_REFERENCE,
3192
1
                                     offset,
3193
1
                                     DESTINATION_LOCAL_REFERENCE_LENGTH, &sccp_info);
3194
3195
1
    sccp_info.assoc = get_sccp_assoc(pinfo, msg_offset, &sccp_info);
3196
1
    build_assoc_tree(tvb, pinfo, sccp_tree, &sccp_info, msg_offset);
3197
3198
1
    offset += dissect_sccp_parameter(tvb, pinfo, sccp_tree, tree,
3199
1
                                     PARAMETER_RECEIVE_SEQUENCE_NUMBER,
3200
1
                                     offset, RECEIVE_SEQUENCE_NUMBER_LENGTH, &sccp_info);
3201
1
    offset += dissect_sccp_parameter(tvb, pinfo, sccp_tree, tree,
3202
1
                                     PARAMETER_CREDIT, offset, CREDIT_LENGTH, &sccp_info);
3203
1
    break;
3204
3205
6
  case SCCP_MSG_TYPE_UDT:
3206
6
    sccp_info.sccp_msg = new_ud_msg(pinfo, sccp_info.message_type);
3207
3208
6
    offset += dissect_sccp_parameter(tvb, pinfo, sccp_tree, tree,
3209
6
                                     PARAMETER_CLASS, offset,
3210
6
                                     PROTOCOL_CLASS_LENGTH, &sccp_info);
3211
6
    VARIABLE_POINTER(variable_pointer1, hf_sccp_variable_pointer1, POINTER_LENGTH);
3212
6
    VARIABLE_POINTER(variable_pointer2, hf_sccp_variable_pointer2, POINTER_LENGTH);
3213
6
    VARIABLE_POINTER(variable_pointer3, hf_sccp_variable_pointer3, POINTER_LENGTH);
3214
3215
6
    sccp_info.assoc = get_sccp_assoc(pinfo, msg_offset, &sccp_info);
3216
6
    build_assoc_tree(tvb, pinfo, sccp_tree, &sccp_info, msg_offset);
3217
3218
6
    dissect_sccp_variable_parameter(tvb, pinfo, sccp_tree, tree,
3219
6
                                    PARAMETER_CALLED_PARTY_ADDRESS,
3220
6
                                    variable_pointer1, &sccp_info);
3221
6
    dissect_sccp_variable_parameter(tvb, pinfo, sccp_tree, tree,
3222
6
                                    PARAMETER_CALLING_PARTY_ADDRESS,
3223
6
                                    variable_pointer2, &sccp_info);
3224
3225
6
    dissect_sccp_variable_parameter(tvb, pinfo, sccp_tree, tree, PARAMETER_DATA,
3226
6
                                    variable_pointer3, &sccp_info);
3227
6
    break;
3228
3229
6
  case SCCP_MSG_TYPE_UDTS:
3230
6
  {
3231
6
    bool save_in_error_pkt = pinfo->flags.in_error_pkt;
3232
6
    pinfo->flags.in_error_pkt = true;
3233
3234
6
    sccp_info.sccp_msg = new_ud_msg(pinfo, sccp_info.message_type);
3235
3236
6
    offset += dissect_sccp_parameter(tvb, pinfo, sccp_tree, tree,
3237
6
                                     PARAMETER_RETURN_CAUSE, offset,
3238
6
                                     RETURN_CAUSE_LENGTH, &sccp_info);
3239
3240
6
    VARIABLE_POINTER(variable_pointer1, hf_sccp_variable_pointer1, POINTER_LENGTH);
3241
6
    VARIABLE_POINTER(variable_pointer2, hf_sccp_variable_pointer2, POINTER_LENGTH);
3242
6
    VARIABLE_POINTER(variable_pointer3, hf_sccp_variable_pointer3, POINTER_LENGTH);
3243
3244
6
    sccp_info.assoc = get_sccp_assoc(pinfo, msg_offset, &sccp_info);
3245
6
    build_assoc_tree(tvb, pinfo, sccp_tree, &sccp_info, msg_offset);
3246
3247
6
    dissect_sccp_variable_parameter(tvb, pinfo, sccp_tree, tree,
3248
6
                                    PARAMETER_CALLED_PARTY_ADDRESS,
3249
6
                                    variable_pointer1, &sccp_info);
3250
3251
6
    dissect_sccp_variable_parameter(tvb, pinfo, sccp_tree, tree,
3252
6
                                    PARAMETER_CALLING_PARTY_ADDRESS,
3253
6
                                    variable_pointer2, &sccp_info);
3254
3255
6
    dissect_sccp_variable_parameter(tvb, pinfo, sccp_tree, tree, PARAMETER_DATA,
3256
6
                                    variable_pointer3, &sccp_info);
3257
6
    pinfo->flags.in_error_pkt = save_in_error_pkt;
3258
6
    break;
3259
0
  }
3260
3261
0
  case SCCP_MSG_TYPE_ED:
3262
0
    offset += dissect_sccp_parameter(tvb, pinfo, sccp_tree, tree,
3263
0
                                     PARAMETER_DESTINATION_LOCAL_REFERENCE,
3264
0
                                     offset,
3265
0
                                     DESTINATION_LOCAL_REFERENCE_LENGTH, &sccp_info);
3266
3267
0
    sccp_info.assoc = get_sccp_assoc(pinfo, msg_offset, &sccp_info);
3268
0
    build_assoc_tree(tvb, pinfo, sccp_tree, &sccp_info, msg_offset);
3269
3270
0
    VARIABLE_POINTER(variable_pointer1, hf_sccp_variable_pointer1, POINTER_LENGTH);
3271
3272
0
    dissect_sccp_variable_parameter(tvb, pinfo, sccp_tree, tree, PARAMETER_DATA,
3273
0
                                    variable_pointer1, &sccp_info);
3274
0
    break;
3275
3276
1
  case SCCP_MSG_TYPE_EA:
3277
1
    offset += dissect_sccp_parameter(tvb, pinfo, sccp_tree, tree,
3278
1
                                     PARAMETER_DESTINATION_LOCAL_REFERENCE,
3279
1
                                     offset,
3280
1
                                     DESTINATION_LOCAL_REFERENCE_LENGTH, &sccp_info);
3281
1
    sccp_info.assoc = get_sccp_assoc(pinfo, msg_offset, &sccp_info);
3282
1
    build_assoc_tree(tvb, pinfo, sccp_tree, &sccp_info, msg_offset);
3283
1
    break;
3284
3285
0
  case SCCP_MSG_TYPE_RSR:
3286
0
    offset += dissect_sccp_parameter(tvb, pinfo, sccp_tree, tree,
3287
0
                                     PARAMETER_DESTINATION_LOCAL_REFERENCE,
3288
0
                                     offset,
3289
0
                                     DESTINATION_LOCAL_REFERENCE_LENGTH, &sccp_info);
3290
0
    offset += dissect_sccp_parameter(tvb, pinfo, sccp_tree, tree,
3291
0
                                     PARAMETER_SOURCE_LOCAL_REFERENCE,
3292
0
                                     offset, SOURCE_LOCAL_REFERENCE_LENGTH, &sccp_info);
3293
0
    offset += dissect_sccp_parameter(tvb, pinfo, sccp_tree, tree,
3294
0
                                     PARAMETER_RESET_CAUSE, offset,
3295
0
                                     RESET_CAUSE_LENGTH, &sccp_info);
3296
0
    sccp_info.assoc = get_sccp_assoc(pinfo, msg_offset, &sccp_info);
3297
0
    build_assoc_tree(tvb, pinfo, sccp_tree, &sccp_info, msg_offset);
3298
0
    break;
3299
3300
1
  case SCCP_MSG_TYPE_RSC:
3301
1
    offset += dissect_sccp_parameter(tvb, pinfo, sccp_tree, tree,
3302
1
                                     PARAMETER_DESTINATION_LOCAL_REFERENCE,
3303
1
                                     offset,
3304
1
                                     DESTINATION_LOCAL_REFERENCE_LENGTH, &sccp_info);
3305
1
    offset += dissect_sccp_parameter(tvb, pinfo, sccp_tree, tree,
3306
1
                                     PARAMETER_SOURCE_LOCAL_REFERENCE,
3307
1
                                     offset, SOURCE_LOCAL_REFERENCE_LENGTH, &sccp_info);
3308
1
    sccp_info.assoc = get_sccp_assoc(pinfo, msg_offset, &sccp_info);
3309
1
    build_assoc_tree(tvb, pinfo, sccp_tree, &sccp_info, msg_offset);
3310
1
    break;
3311
3312
2
  case SCCP_MSG_TYPE_ERR:
3313
2
    offset += dissect_sccp_parameter(tvb, pinfo, sccp_tree, tree,
3314
2
                                     PARAMETER_DESTINATION_LOCAL_REFERENCE,
3315
2
                                     offset,
3316
2
                                     DESTINATION_LOCAL_REFERENCE_LENGTH, &sccp_info);
3317
2
    offset += dissect_sccp_parameter(tvb, pinfo, sccp_tree, tree,
3318
2
                                     PARAMETER_ERROR_CAUSE, offset,
3319
2
                                     ERROR_CAUSE_LENGTH, &sccp_info);
3320
2
    sccp_info.assoc = get_sccp_assoc(pinfo, msg_offset, &sccp_info);
3321
2
    build_assoc_tree(tvb, pinfo, sccp_tree, &sccp_info, msg_offset);
3322
2
    break;
3323
3324
7
  case SCCP_MSG_TYPE_IT:
3325
7
    offset += dissect_sccp_parameter(tvb, pinfo, sccp_tree, tree,
3326
7
                                     PARAMETER_DESTINATION_LOCAL_REFERENCE,
3327
7
                                     offset,
3328
7
                                     DESTINATION_LOCAL_REFERENCE_LENGTH, &sccp_info);
3329
7
    offset += dissect_sccp_parameter(tvb, pinfo, sccp_tree, tree,
3330
7
                                     PARAMETER_SOURCE_LOCAL_REFERENCE,
3331
7
                                     offset, SOURCE_LOCAL_REFERENCE_LENGTH, &sccp_info);
3332
7
    sccp_info.assoc = get_sccp_assoc(pinfo, msg_offset, &sccp_info);
3333
7
    build_assoc_tree(tvb, pinfo, sccp_tree, &sccp_info, msg_offset);
3334
7
    offset += dissect_sccp_parameter(tvb, pinfo, sccp_tree, tree,
3335
7
                                     PARAMETER_CLASS, offset,
3336
7
                                     PROTOCOL_CLASS_LENGTH, &sccp_info);
3337
7
    offset += dissect_sccp_parameter(tvb, pinfo, sccp_tree, tree,
3338
7
                                     PARAMETER_SEQUENCING_SEGMENTING,
3339
7
                                     offset, SEQUENCING_SEGMENTING_LENGTH, &sccp_info);
3340
7
    offset += dissect_sccp_parameter(tvb, pinfo, sccp_tree, tree,
3341
7
                                     PARAMETER_CREDIT, offset, CREDIT_LENGTH, &sccp_info);
3342
7
    break;
3343
3344
41
  case SCCP_MSG_TYPE_XUDT:
3345
41
    sccp_info.sccp_msg = new_ud_msg(pinfo, sccp_info.message_type);
3346
41
    offset += dissect_sccp_parameter(tvb, pinfo, sccp_tree, tree,
3347
41
                                     PARAMETER_CLASS, offset,
3348
41
                                     PROTOCOL_CLASS_LENGTH, &sccp_info);
3349
41
    offset += dissect_sccp_parameter(tvb, pinfo, sccp_tree, tree,
3350
41
                                     PARAMETER_HOP_COUNTER, offset,
3351
41
                                     HOP_COUNTER_LENGTH, &sccp_info);
3352
3353
41
    offset = dissect_xudt_common(tvb, pinfo, sccp_tree, tree, offset, &sccp_info,
3354
41
                                 &optional_pointer, &orig_opt_ptr, POINTER_LENGTH);
3355
41
    break;
3356
3357
24
  case SCCP_MSG_TYPE_XUDTS:
3358
24
  {
3359
24
    bool save_in_error_pkt = pinfo->flags.in_error_pkt;
3360
24
    pinfo->flags.in_error_pkt = true;
3361
3362
24
    sccp_info.sccp_msg = new_ud_msg(pinfo, sccp_info.message_type);
3363
24
    offset += dissect_sccp_parameter(tvb, pinfo, sccp_tree, tree,
3364
24
                                     PARAMETER_RETURN_CAUSE, offset,
3365
24
                                     RETURN_CAUSE_LENGTH, &sccp_info);
3366
24
    offset += dissect_sccp_parameter(tvb, pinfo, sccp_tree, tree,
3367
24
                                     PARAMETER_HOP_COUNTER, offset,
3368
24
                                     HOP_COUNTER_LENGTH, &sccp_info);
3369
3370
24
    offset = dissect_xudt_common(tvb, pinfo, sccp_tree, tree, offset, &sccp_info,
3371
24
                                 &optional_pointer, &orig_opt_ptr, POINTER_LENGTH);
3372
3373
24
    pinfo->flags.in_error_pkt = save_in_error_pkt;
3374
24
    break;
3375
0
  }
3376
1
  case SCCP_MSG_TYPE_LUDT:
3377
1
    sccp_info.sccp_msg = new_ud_msg(pinfo, sccp_info.message_type);
3378
3379
1
    offset += dissect_sccp_parameter(tvb, pinfo, sccp_tree, tree,
3380
1
                                     PARAMETER_CLASS, offset,
3381
1
                                     PROTOCOL_CLASS_LENGTH, &sccp_info);
3382
1
    offset += dissect_sccp_parameter(tvb, pinfo, sccp_tree, tree,
3383
1
                                     PARAMETER_HOP_COUNTER, offset,
3384
1
                                     HOP_COUNTER_LENGTH, &sccp_info);
3385
3386
1
    offset = dissect_xudt_common(tvb, pinfo, sccp_tree, tree, offset, &sccp_info,
3387
1
                                 &optional_pointer, &orig_opt_ptr, POINTER_LENGTH_LONG);
3388
1
    break;
3389
3390
4
  case SCCP_MSG_TYPE_LUDTS:
3391
4
  {
3392
4
    bool save_in_error_pkt = pinfo->flags.in_error_pkt;
3393
4
    pinfo->flags.in_error_pkt = true;
3394
3395
4
    sccp_info.sccp_msg = new_ud_msg(pinfo, sccp_info.message_type);
3396
4
    offset += dissect_sccp_parameter(tvb, pinfo, sccp_tree, tree,
3397
4
                                     PARAMETER_RETURN_CAUSE, offset,
3398
4
                                     RETURN_CAUSE_LENGTH, &sccp_info);
3399
4
    offset += dissect_sccp_parameter(tvb, pinfo, sccp_tree, tree,
3400
4
                                     PARAMETER_HOP_COUNTER, offset,
3401
4
                                     HOP_COUNTER_LENGTH, &sccp_info);
3402
3403
4
    offset = dissect_xudt_common(tvb, pinfo, sccp_tree, tree, offset, &sccp_info,
3404
4
                                 &optional_pointer, &orig_opt_ptr, POINTER_LENGTH_LONG);
3405
3406
4
    pinfo->flags.in_error_pkt = save_in_error_pkt;
3407
4
    break;
3408
0
  }
3409
10
  default:
3410
10
    dissect_sccp_unknown_message(tvb, sccp_tree);
3411
281
  }
3412
3413
236
  if (orig_opt_ptr)
3414
206
    dissect_sccp_optional_parameters(tvb, pinfo, sccp_tree, tree,
3415
206
                                     optional_pointer, &sccp_info);
3416
3417
236
  return offset;
3418
281
}
3419
3420
static int
3421
dissect_sccp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_)
3422
281
{
3423
281
  proto_item *sccp_item = NULL;
3424
281
  proto_tree *sccp_tree = NULL;
3425
281
  const mtp3_addr_pc_t *mtp3_addr_p;
3426
3427
281
  if ((pinfo->src.type == ss7pc_address_type) &&
3428
281
      ((mtp3_addr_p = (const mtp3_addr_pc_t *)pinfo->src.data)->type <= CHINESE_ITU_STANDARD)) {
3429
    /*
3430
     *  Allow a protocol beneath to specify how the SCCP layer should be
3431
     *  dissected.
3432
     *
3433
     *  It is possible to have multiple sets of SCCP traffic some of which is
3434
     *  ITU and some of which is ANSI.
3435
     *  An example is A-interface traffic having ANSI MTP3/ANSI SCCP/3GPP2 IOS
3436
     *  and at the same time ITU MTP3/ITU SCCP/ANSI TCAP/ANSI MAP.
3437
     */
3438
223
    decode_mtp3_standard = mtp3_addr_p->type;
3439
223
  } else {
3440
58
    decode_mtp3_standard = (Standard_Type)mtp3_standard;
3441
58
  }
3442
3443
  /* Make entry in the Protocol column on summary display */
3444
281
  switch (decode_mtp3_standard) {
3445
281
  case ITU_STANDARD:
3446
281
    col_set_str(pinfo->cinfo, COL_PROTOCOL, "SCCP (Int. ITU)");
3447
281
    break;
3448
0
  case ANSI_STANDARD:
3449
0
    col_set_str(pinfo->cinfo, COL_PROTOCOL, "SCCP (ANSI)");
3450
0
    break;
3451
0
  case CHINESE_ITU_STANDARD:
3452
0
    col_set_str(pinfo->cinfo, COL_PROTOCOL, "SCCP (Chin. ITU)");
3453
0
    break;
3454
0
  case JAPAN_STANDARD:
3455
0
    col_set_str(pinfo->cinfo, COL_PROTOCOL, "SCCP (Japan)");
3456
0
    break;
3457
281
  };
3458
3459
  /* In the interest of speed, if "tree" is NULL, don't do any work not
3460
     necessary to generate protocol tree items. */
3461
281
  if (tree) {
3462
    /* create the sccp protocol tree */
3463
281
    sccp_item = proto_tree_add_item(tree, proto_sccp, tvb, 0, -1, ENC_NA);
3464
281
    sccp_tree = proto_item_add_subtree(sccp_item, ett_sccp);
3465
281
  }
3466
3467
  /* Set whether message is UPLINK, DOWNLINK, or of UNKNOWN direction */
3468
3469
281
  if (pinfo->src.type == ss7pc_address_type) {
3470
    /*
3471
     * XXX - we assume that the "data" pointers of the source and destination
3472
     * addresses are set to point to "mtp3_addr_pc_t" structures, so that
3473
     * we can safely cast them.
3474
     */
3475
223
    mtp3_addr_p = (const mtp3_addr_pc_t *)pinfo->src.data;
3476
3477
223
    if (sccp_source_pc_global == mtp3_addr_p->pc) {
3478
4
      pinfo->p2p_dir = P2P_DIR_SENT;
3479
219
    } else {
3480
      /* assuming if src was SS7 PC then dst will be too */
3481
219
      mtp3_addr_p = (const mtp3_addr_pc_t *)pinfo->dst.data;
3482
3483
219
      if (sccp_source_pc_global == mtp3_addr_p->pc)
3484
3
      {
3485
3
        pinfo->p2p_dir = P2P_DIR_RECV;
3486
216
      } else {
3487
216
        pinfo->p2p_dir = P2P_DIR_UNKNOWN;
3488
216
      }
3489
219
    }
3490
223
  }
3491
3492
  /* dissect the message */
3493
281
  dissect_sccp_message(tvb, pinfo, sccp_tree, tree);
3494
281
  return tvb_captured_length(tvb);
3495
281
}
3496
3497
/*** SccpUsers Table **/
3498
3499
static struct _sccp_ul {
3500
  unsigned id;
3501
  bool uses_tcap;
3502
  dissector_handle_t *handlep;
3503
} user_list[] = {
3504
3505
  {SCCP_USER_DATA,       false, &data_handle},
3506
  {SCCP_USER_TCAP,       false, &tcap_handle},
3507
  {SCCP_USER_RANAP,      false, &ranap_handle},
3508
  {SCCP_USER_BSSAP,      false, &bssap_handle},
3509
  {SCCP_USER_GSMMAP,     true,  &gsmmap_handle},
3510
  {SCCP_USER_CAMEL,      true,  &camel_handle},
3511
  {SCCP_USER_INAP,       true,  &inap_handle},
3512
  {SCCP_USER_BSAP,       false, &bsap_handle},
3513
  {SCCP_USER_BSSAP_LE,   false, &bssap_le_handle},
3514
  {SCCP_USER_BSSAP_PLUS, false, &bssap_plus_handle},
3515
  {0, false, NULL}
3516
};
3517
3518
static bool
3519
sccp_users_update_cb(void *r, char **err)
3520
0
{
3521
0
  sccp_user_t *u = (sccp_user_t *)r;
3522
0
  struct _sccp_ul *c;
3523
0
  range_t *empty;
3524
3525
0
  empty = range_empty(NULL);
3526
0
  if (ranges_are_equal(u->called_pc, empty)) {
3527
0
          *err = g_strdup("Must specify a PC");
3528
0
          wmem_free(NULL, empty);
3529
0
          return false;
3530
0
  }
3531
3532
0
  if (ranges_are_equal(u->called_ssn, empty)) {
3533
0
          *err = g_strdup("Must specify an SSN");
3534
0
          wmem_free(NULL, empty);
3535
0
          return false;
3536
0
  }
3537
3538
0
  wmem_free(NULL, empty);
3539
0
  for (c=user_list; c->handlep; c++) {
3540
0
    if (c->id == u->user) {
3541
0
      u->uses_tcap = c->uses_tcap;
3542
0
      u->handlep   = c->handlep;
3543
0
      return true;
3544
0
    }
3545
0
  }
3546
3547
0
  u->uses_tcap = false;
3548
0
  u->handlep   = &data_handle;
3549
0
  return true;
3550
0
}
3551
3552
static void *
3553
sccp_users_copy_cb(void *n, const void *o, size_t siz _U_)
3554
0
{
3555
0
  const sccp_user_t *u = (const sccp_user_t *)o;
3556
0
  sccp_user_t *un = (sccp_user_t *)n;
3557
3558
0
  un->ni        = u->ni;
3559
0
  un->user      = u->user;
3560
0
  un->uses_tcap = u->uses_tcap;
3561
0
  un->handlep   = u->handlep;
3562
3563
0
  if (u->called_pc)
3564
0
    un->called_pc  = range_copy(NULL, u->called_pc);
3565
0
  if (u->called_ssn)
3566
0
    un->called_ssn = range_copy(NULL, u->called_ssn);
3567
3568
0
  return n;
3569
0
}
3570
3571
static void
3572
sccp_users_free_cb(void *r)
3573
0
{
3574
0
  sccp_user_t *u = (sccp_user_t *)r;
3575
0
  if (u->called_pc) wmem_free(NULL, u->called_pc);
3576
0
  if (u->called_ssn) wmem_free(NULL, u->called_ssn);
3577
0
}
3578
3579
3580
UAT_DEC_CB_DEF(sccp_users, ni, sccp_user_t)
3581
UAT_RANGE_CB_DEF(sccp_users, called_pc, sccp_user_t)
3582
UAT_RANGE_CB_DEF(sccp_users, called_ssn, sccp_user_t)
3583
UAT_VS_DEF(sccp_users, user, sccp_user_t, unsigned, SCCP_USER_DATA, "Data")
3584
3585
/** End SccpUsersTable **/
3586
3587
3588
static void
3589
init_sccp(void)
3590
14
{
3591
14
  next_assoc_id = 1;
3592
14
  sccp_reassembly_id_next = 1;
3593
14
}
3594
3595
/* Register the protocol with Wireshark */
3596
void
3597
proto_register_sccp(void)
3598
14
{
3599
  /* Setup list of header fields */
3600
14
  static hf_register_info hf[] = {
3601
14
    { &hf_sccp_message_type,
3602
14
      { "Message Type", "sccp.message_type",
3603
14
        FT_UINT8, BASE_HEX, VALS(sccp_message_type_values), 0x0,
3604
14
        NULL, HFILL}
3605
14
    },
3606
14
    { &hf_sccp_variable_pointer1,
3607
14
      { "Pointer to first Mandatory Variable parameter", "sccp.variable_pointer1",
3608
14
        FT_UINT16, BASE_DEC, NULL, 0x0,
3609
14
        NULL, HFILL}
3610
14
    },
3611
14
    { &hf_sccp_variable_pointer2,
3612
14
      { "Pointer to second Mandatory Variable parameter", "sccp.variable_pointer2",
3613
14
        FT_UINT16, BASE_DEC, NULL, 0x0,
3614
14
        NULL, HFILL}
3615
14
    },
3616
14
    { &hf_sccp_variable_pointer3,
3617
14
      { "Pointer to third Mandatory Variable parameter", "sccp.variable_pointer3",
3618
14
        FT_UINT16, BASE_DEC, NULL, 0x0,
3619
14
        NULL, HFILL}
3620
14
    },
3621
14
    { &hf_sccp_optional_pointer,
3622
14
      { "Pointer to Optional parameter", "sccp.optional_pointer",
3623
14
        FT_UINT16, BASE_DEC, NULL, 0x0,
3624
14
        NULL, HFILL}
3625
14
    },
3626
14
    { &hf_sccp_param_length,
3627
14
      { "Variable parameter length", "sccp.parameter_length",
3628
14
        FT_UINT16, BASE_DEC, NULL, 0x0,
3629
14
        NULL, HFILL}
3630
14
    },
3631
14
    { &hf_sccp_ssn,
3632
14
      { "Called or Calling SubSystem Number", "sccp.ssn",
3633
14
        FT_UINT8, BASE_DEC, VALS(sccp_ssn_values), 0x0,
3634
14
        NULL, HFILL}
3635
14
    },
3636
14
    { &hf_sccp_gt_digits,
3637
14
      { "Called or Calling GT Digits", "sccp.digits",
3638
14
        FT_STRING, BASE_NONE, NULL, 0x0,
3639
14
        NULL, HFILL }
3640
14
    },
3641
14
    { &hf_sccp_called_ansi_national_indicator,
3642
14
      { "National Indicator", "sccp.called.ni",
3643
14
        FT_UINT8, BASE_HEX, VALS(sccp_ansi_national_indicator_values), ANSI_NATIONAL_MASK,
3644
14
        NULL, HFILL}
3645
14
    },
3646
14
    { &hf_sccp_called_itu_natl_use_bit,
3647
14
      { "Reserved for national use", "sccp.called.reserved",
3648
14
        FT_UINT8, BASE_HEX, NULL, ITU_RESERVED_MASK,
3649
14
        NULL, HFILL}
3650
14
    },
3651
14
    { &hf_sccp_called_routing_indicator,
3652
14
      { "Routing Indicator", "sccp.called.ri",
3653
14
        FT_UINT8, BASE_HEX, VALS(sccp_routing_indicator_values), ROUTING_INDICATOR_MASK,
3654
14
        NULL, HFILL}
3655
14
    },
3656
14
    { &hf_sccp_called_itu_global_title_indicator,
3657
14
      { "Global Title Indicator", "sccp.called.gti",
3658
14
        FT_UINT8, BASE_HEX, VALS(sccp_itu_global_title_indicator_values), GTI_MASK,
3659
14
        NULL, HFILL}
3660
14
    },
3661
14
    { &hf_sccp_called_ansi_global_title_indicator,
3662
14
      { "Global Title Indicator", "sccp.called.gti",
3663
14
        FT_UINT8, BASE_HEX, VALS(sccp_ansi_global_title_indicator_values), GTI_MASK,
3664
14
        NULL, HFILL}
3665
14
    },
3666
14
    { &hf_sccp_called_itu_ssn_indicator,
3667
14
      { "SubSystem Number Indicator", "sccp.called.ssni",
3668
14
        FT_UINT8, BASE_HEX, VALS(sccp_ai_ssni_values), ITU_SSN_INDICATOR_MASK,
3669
14
        NULL, HFILL}
3670
14
    },
3671
14
    { &hf_sccp_called_itu_point_code_indicator,
3672
14
      { "Point Code Indicator", "sccp.called.pci",
3673
14
        FT_UINT8, BASE_HEX, VALS(sccp_ai_pci_values), ITU_PC_INDICATOR_MASK,
3674
14
        NULL, HFILL}
3675
14
    },
3676
14
    { &hf_sccp_called_ansi_ssn_indicator,
3677
14
      { "SubSystem Number Indicator", "sccp.called.ssni",
3678
14
        FT_UINT8, BASE_HEX, VALS(sccp_ai_ssni_values), ANSI_SSN_INDICATOR_MASK,
3679
14
        NULL, HFILL}
3680
14
    },
3681
14
    { &hf_sccp_called_ansi_point_code_indicator,
3682
14
      { "Point Code Indicator", "sccp.called.pci",
3683
14
        FT_UINT8, BASE_HEX, VALS(sccp_ai_pci_values), ANSI_PC_INDICATOR_MASK,
3684
14
        NULL, HFILL}
3685
14
    },
3686
14
    { &hf_sccp_called_ssn,
3687
14
      { "SubSystem Number", "sccp.called.ssn",
3688
14
        FT_UINT8, BASE_DEC, VALS(sccp_ssn_values), 0x0,
3689
14
        NULL, HFILL}
3690
14
    },
3691
14
    { &hf_sccp_called_itu_pc,
3692
14
      { "PC", "sccp.called.pc",
3693
14
        FT_UINT16, BASE_DEC, NULL, ITU_PC_MASK,
3694
14
        NULL, HFILL}
3695
14
    },
3696
14
    { &hf_sccp_called_ansi_pc,
3697
14
      { "PC", "sccp.called.ansi_pc",
3698
14
        FT_STRING, BASE_NONE, NULL, 0x0,
3699
14
        NULL, HFILL}
3700
14
    },
3701
14
    { &hf_sccp_called_chinese_pc,
3702
14
      { "PC", "sccp.called.chinese_pc",
3703
14
        FT_STRING, BASE_NONE, NULL, 0x0,
3704
14
        NULL, HFILL}
3705
14
    },
3706
14
    { &hf_sccp_called_japan_pc,
3707
14
      { "PC", "sccp.called.pc",
3708
14
        FT_UINT16, BASE_DEC, NULL, 0x0,
3709
14
        NULL, HFILL}
3710
14
    },
3711
14
    { &hf_sccp_called_pc_network,
3712
14
      { "PC Network", "sccp.called.network",
3713
14
        FT_UINT24, BASE_DEC, NULL, ANSI_NETWORK_MASK,
3714
14
        NULL, HFILL }
3715
14
    },
3716
14
    { &hf_sccp_called_pc_cluster,
3717
14
      { "PC Cluster", "sccp.called.cluster",
3718
14
        FT_UINT24, BASE_DEC, NULL, ANSI_CLUSTER_MASK,
3719
14
        NULL, HFILL }
3720
14
    },
3721
14
    { &hf_sccp_called_pc_member,
3722
14
      { "PC Member", "sccp.called.member",
3723
14
        FT_UINT24, BASE_DEC, NULL, ANSI_MEMBER_MASK,
3724
14
        NULL, HFILL }
3725
14
    },
3726
14
    { &hf_sccp_called_gt_nai,
3727
14
      { "Nature of Address Indicator", "sccp.called.nai",
3728
14
        FT_UINT8, BASE_HEX, VALS(sccp_nai_values), GT_NAI_MASK,
3729
14
        NULL, HFILL }
3730
14
    },
3731
14
    { &hf_sccp_called_gt_oe,
3732
14
      { "Odd/Even Indicator", "sccp.called.oe",
3733
14
        FT_UINT8, BASE_HEX, VALS(sccp_oe_values), GT_OE_MASK,
3734
14
        NULL, HFILL }
3735
14
    },
3736
14
    { &hf_sccp_called_gt_tt,
3737
14
      { "Translation Type", "sccp.called.tt",
3738
14
        FT_UINT8, BASE_HEX_DEC, NULL, 0x0,
3739
14
        NULL, HFILL }
3740
14
    },
3741
14
    { &hf_sccp_called_gt_np,
3742
14
      { "Numbering Plan", "sccp.called.np",
3743
14
        FT_UINT8, BASE_HEX, VALS(sccp_np_values), GT_NP_MASK,
3744
14
        NULL, HFILL }
3745
14
    },
3746
14
    { &hf_sccp_called_gt_es,
3747
14
      { "Encoding Scheme", "sccp.called.es",
3748
14
        FT_UINT8, BASE_HEX, VALS(sccp_es_values), GT_ES_MASK,
3749
14
        NULL, HFILL }
3750
14
    },
3751
14
    { &hf_sccp_called_gt_digits,
3752
14
      { "Called Party Digits", "sccp.called.digits",
3753
14
        FT_STRING, BASE_NONE, NULL, 0x0,
3754
14
        NULL, HFILL }
3755
14
    },
3756
14
    { &hf_sccp_called_gt_digits_length,
3757
14
      { "Number of Called Party Digits", "sccp.called.digits.length",
3758
14
        FT_UINT8, BASE_DEC, NULL, 0x0,
3759
14
        NULL, HFILL }
3760
14
    },
3761
14
    { &hf_sccp_calling_ansi_national_indicator,
3762
14
      { "National Indicator", "sccp.calling.ni",
3763
14
        FT_UINT8, BASE_HEX, VALS(sccp_ansi_national_indicator_values), ANSI_NATIONAL_MASK,
3764
14
        NULL, HFILL}
3765
14
    },
3766
14
    { &hf_sccp_calling_itu_natl_use_bit,
3767
14
      { "Reserved for national use", "sccp.calling.reserved",
3768
14
        FT_UINT8, BASE_HEX, NULL, ITU_RESERVED_MASK,
3769
14
        NULL, HFILL}
3770
14
    },
3771
14
    { &hf_sccp_calling_routing_indicator,
3772
14
      { "Routing Indicator", "sccp.calling.ri",
3773
14
        FT_UINT8, BASE_HEX, VALS(sccp_routing_indicator_values), ROUTING_INDICATOR_MASK,
3774
14
        NULL, HFILL}
3775
14
    },
3776
14
    { &hf_sccp_calling_itu_global_title_indicator,
3777
14
      { "Global Title Indicator", "sccp.calling.gti",
3778
14
        FT_UINT8, BASE_HEX, VALS(sccp_itu_global_title_indicator_values), GTI_MASK,
3779
14
        NULL, HFILL}
3780
14
    },
3781
14
    { &hf_sccp_calling_ansi_global_title_indicator,
3782
14
      { "Global Title Indicator", "sccp.calling.gti",
3783
14
        FT_UINT8, BASE_HEX, VALS(sccp_ansi_global_title_indicator_values), GTI_MASK,
3784
14
        NULL, HFILL}
3785
14
    },
3786
14
    { &hf_sccp_calling_itu_ssn_indicator,
3787
14
      { "SubSystem Number Indicator", "sccp.calling.ssni",
3788
14
        FT_UINT8, BASE_HEX, VALS(sccp_ai_ssni_values), ITU_SSN_INDICATOR_MASK,
3789
14
        NULL, HFILL}
3790
14
    },
3791
14
    { &hf_sccp_calling_itu_point_code_indicator,
3792
14
      { "Point Code Indicator", "sccp.calling.pci",
3793
14
        FT_UINT8, BASE_HEX, VALS(sccp_ai_pci_values), ITU_PC_INDICATOR_MASK,
3794
14
        NULL, HFILL}
3795
14
    },
3796
14
    { &hf_sccp_calling_ansi_ssn_indicator,
3797
14
      { "SubSystem Number Indicator", "sccp.calling.ssni",
3798
14
        FT_UINT8, BASE_HEX, VALS(sccp_ai_ssni_values), ANSI_SSN_INDICATOR_MASK,
3799
14
        NULL, HFILL}
3800
14
    },
3801
14
    { &hf_sccp_calling_ansi_point_code_indicator,
3802
14
      { "Point Code Indicator", "sccp.calling.pci",
3803
14
        FT_UINT8, BASE_HEX, VALS(sccp_ai_pci_values), ANSI_PC_INDICATOR_MASK,
3804
14
        NULL, HFILL}
3805
14
    },
3806
14
    { &hf_sccp_calling_ssn,
3807
14
      { "SubSystem Number", "sccp.calling.ssn",
3808
14
        FT_UINT8, BASE_DEC, VALS(sccp_ssn_values), 0x0,
3809
14
        NULL, HFILL}
3810
14
    },
3811
14
    { &hf_sccp_calling_itu_pc,
3812
14
      { "PC", "sccp.calling.pc",
3813
14
        FT_UINT16, BASE_DEC, NULL, ITU_PC_MASK,
3814
14
        NULL, HFILL}
3815
14
    },
3816
14
    { &hf_sccp_calling_ansi_pc,
3817
14
      { "PC", "sccp.calling.ansi_pc",
3818
14
        FT_STRING, BASE_NONE, NULL, 0x0,
3819
14
        NULL, HFILL}
3820
14
    },
3821
14
    { &hf_sccp_calling_chinese_pc,
3822
14
      { "PC", "sccp.calling.chinese_pc",
3823
14
        FT_STRING, BASE_NONE, NULL, 0x0,
3824
14
        NULL, HFILL}
3825
14
    },
3826
14
    { &hf_sccp_calling_japan_pc,
3827
14
      { "PC", "sccp.calling.pc",
3828
14
        FT_UINT16, BASE_DEC, NULL, 0x0,
3829
14
        NULL, HFILL}
3830
14
    },
3831
14
    { &hf_sccp_calling_pc_network,
3832
14
      { "PC Network", "sccp.calling.network",
3833
14
        FT_UINT24, BASE_DEC, NULL, ANSI_NETWORK_MASK,
3834
14
        NULL, HFILL }
3835
14
    },
3836
14
    { &hf_sccp_calling_pc_cluster,
3837
14
      { "PC Cluster", "sccp.calling.cluster",
3838
14
        FT_UINT24, BASE_DEC, NULL, ANSI_CLUSTER_MASK,
3839
14
        NULL, HFILL }
3840
14
    },
3841
14
    { &hf_sccp_calling_pc_member,
3842
14
      { "PC Member", "sccp.calling.member",
3843
14
        FT_UINT24, BASE_DEC, NULL, ANSI_MEMBER_MASK,
3844
14
        NULL, HFILL }
3845
14
    },
3846
14
    { &hf_sccp_calling_gt_nai,
3847
14
      { "Nature of Address Indicator", "sccp.calling.nai",
3848
14
        FT_UINT8, BASE_HEX, VALS(sccp_nai_values), GT_NAI_MASK,
3849
14
        NULL, HFILL }
3850
14
    },
3851
14
    { &hf_sccp_calling_gt_oe,
3852
14
      { "Odd/Even Indicator", "sccp.calling.oe",
3853
14
        FT_UINT8, BASE_HEX, VALS(sccp_oe_values), GT_OE_MASK,
3854
14
        NULL, HFILL }
3855
14
    },
3856
14
    { &hf_sccp_calling_gt_tt,
3857
14
      { "Translation Type", "sccp.calling.tt",
3858
14
        FT_UINT8, BASE_HEX_DEC, NULL, 0x0,
3859
14
        NULL, HFILL }
3860
14
    },
3861
14
    { &hf_sccp_calling_gt_np,
3862
14
      { "Numbering Plan", "sccp.calling.np",
3863
14
        FT_UINT8, BASE_HEX, VALS(sccp_np_values), GT_NP_MASK,
3864
14
        NULL, HFILL }
3865
14
    },
3866
14
    { &hf_sccp_calling_gt_es,
3867
14
      { "Encoding Scheme", "sccp.calling.es",
3868
14
        FT_UINT8, BASE_HEX, VALS(sccp_es_values), GT_ES_MASK,
3869
14
        NULL, HFILL }
3870
14
    },
3871
14
    { &hf_sccp_calling_gt_digits,
3872
14
      { "Calling Party Digits", "sccp.calling.digits",
3873
14
        FT_STRING, BASE_NONE, NULL, 0x0,
3874
14
        NULL, HFILL }
3875
14
    },
3876
14
    { &hf_sccp_calling_gt_digits_length,
3877
14
      { "Number of Calling Party Digits", "sccp.calling.digits.length",
3878
14
        FT_UINT8, BASE_DEC, NULL, 0x0,
3879
14
        NULL, HFILL }
3880
14
    },
3881
14
    { &hf_sccp_dlr,
3882
14
      { "Destination Local Reference", "sccp.dlr",
3883
14
        FT_UINT24, BASE_HEX, NULL, 0x0,
3884
14
        NULL, HFILL}
3885
14
    },
3886
14
    { &hf_sccp_slr,
3887
14
      { "Source Local Reference", "sccp.slr",
3888
14
        FT_UINT24, BASE_HEX, NULL, 0x0,
3889
14
        NULL, HFILL}
3890
14
    },
3891
14
    { &hf_sccp_lr,
3892
14
      { "Local Reference", "sccp.lr",
3893
14
        FT_UINT24, BASE_HEX, NULL, 0x0,
3894
14
        NULL, HFILL}
3895
14
    },
3896
14
    { &hf_sccp_class,
3897
14
      { "Class", "sccp.class",
3898
14
        FT_UINT8, BASE_HEX, NULL, CLASS_CLASS_MASK,
3899
14
        NULL, HFILL}
3900
14
    },
3901
14
    { &hf_sccp_handling,
3902
14
      { "Message handling", "sccp.handling",
3903
14
        FT_UINT8, BASE_HEX, VALS(sccp_class_handling_values), CLASS_SPARE_HANDLING_MASK,
3904
14
        NULL, HFILL}
3905
14
    },
3906
14
    { &hf_sccp_more,
3907
14
      { "More data", "sccp.more",
3908
14
        FT_UINT8, BASE_HEX, VALS(sccp_segmenting_reassembling_values), SEGMENTING_REASSEMBLING_MASK,
3909
14
        NULL, HFILL}
3910
14
    },
3911
14
    { &hf_sccp_rsn,
3912
14
      { "Receive Sequence Number", "sccp.rsn",
3913
14
        FT_UINT8, BASE_HEX, NULL, RSN_MASK,
3914
14
        NULL, HFILL}
3915
14
    },
3916
14
    { &hf_sccp_sequencing_segmenting_ssn,
3917
14
      { "Sequencing Segmenting: Send Sequence Number", "sccp.sequencing_segmenting.ssn",
3918
14
        FT_UINT8, BASE_HEX, NULL, SEND_SEQUENCE_NUMBER_MASK,
3919
14
        NULL, HFILL}
3920
14
    },
3921
14
    { &hf_sccp_sequencing_segmenting_rsn,
3922
14
      { "Sequencing Segmenting: Receive Sequence Number", "sccp.sequencing_segmenting.rsn",
3923
14
        FT_UINT8, BASE_HEX, NULL, RECEIVE_SEQUENCE_NUMBER_MASK,
3924
14
        NULL, HFILL}
3925
14
    },
3926
14
    { &hf_sccp_sequencing_segmenting_more,
3927
14
      { "Sequencing Segmenting: More", "sccp.sequencing_segmenting.more",
3928
14
        FT_UINT8, BASE_HEX, VALS(sccp_segmenting_reassembling_values), SEQUENCING_SEGMENTING_MORE_MASK,
3929
14
        NULL, HFILL}
3930
14
    },
3931
14
    { &hf_sccp_credit,
3932
14
      { "Credit", "sccp.credit",
3933
14
        FT_UINT8, BASE_HEX, NULL, 0x0,
3934
14
        NULL, HFILL}
3935
14
    },
3936
14
    { &hf_sccp_release_cause,
3937
14
      { "Release Cause", "sccp.release_cause",
3938
14
        FT_UINT8, BASE_HEX, VALS(sccp_release_cause_values), 0x0,
3939
14
        NULL, HFILL}
3940
14
    },
3941
14
    { &hf_sccp_return_cause,
3942
14
      { "Return Cause", "sccp.return_cause",
3943
14
        FT_UINT8, BASE_HEX, VALS(sccp_return_cause_values), 0x0,
3944
14
        NULL, HFILL}
3945
14
    },
3946
14
    { &hf_sccp_reset_cause,
3947
14
      { "Reset Cause", "sccp.reset_cause",
3948
14
        FT_UINT8, BASE_HEX, VALS(sccp_reset_cause_values), 0x0,
3949
14
        NULL, HFILL}
3950
14
    },
3951
14
    { &hf_sccp_error_cause,
3952
14
      { "Error Cause", "sccp.error_cause",
3953
14
        FT_UINT8, BASE_HEX, VALS(sccp_error_cause_values), 0x0,
3954
14
        NULL, HFILL}
3955
14
    },
3956
14
    { &hf_sccp_refusal_cause,
3957
14
      { "Refusal Cause", "sccp.refusal_cause",
3958
14
        FT_UINT8, BASE_HEX, VALS(sccp_refusal_cause_values), 0x0,
3959
14
        NULL, HFILL}
3960
14
    },
3961
14
    { &hf_sccp_segmentation_first,
3962
14
      { "Segmentation: First", "sccp.segmentation.first",
3963
14
        FT_UINT8, BASE_HEX, VALS(sccp_segmentation_first_segment_values), SEGMENTATION_FIRST_SEGMENT_MASK,
3964
14
        NULL, HFILL}
3965
14
    },
3966
14
    { &hf_sccp_segmentation_class,
3967
14
      { "Segmentation: Class", "sccp.segmentation.class",
3968
14
        FT_UINT8, BASE_HEX, VALS(sccp_segmentation_class_values), SEGMENTATION_CLASS_MASK,
3969
14
        NULL, HFILL}
3970
14
    },
3971
14
    { &hf_sccp_segmentation_remaining,
3972
14
      { "Segmentation: Remaining", "sccp.segmentation.remaining",
3973
14
        FT_UINT8, BASE_HEX, NULL, SEGMENTATION_REMAINING_MASK,
3974
14
        NULL, HFILL}
3975
14
    },
3976
14
    { &hf_sccp_segmentation_slr,
3977
14
      { "Segmentation: Source Local Reference", "sccp.segmentation.slr",
3978
14
        FT_UINT24, BASE_HEX, NULL, 0x0,
3979
14
        NULL, HFILL}
3980
14
    },
3981
14
    { &hf_sccp_hop_counter,
3982
14
      { "Hop Counter", "sccp.hops",
3983
14
        FT_UINT8, BASE_HEX, NULL, 0x0,
3984
14
        NULL, HFILL}
3985
14
    },
3986
14
    { &hf_sccp_importance,
3987
14
      { "Importance", "sccp.importance",
3988
14
        FT_UINT8, BASE_HEX, NULL, IMPORTANCE_IMPORTANCE_MASK,
3989
14
        NULL, HFILL}
3990
14
    },
3991
    /* ISNI is ANSI only */
3992
14
    { &hf_sccp_ansi_isni_mi,
3993
14
      { "ISNI Mark for Identification Indicator", "sccp.isni.mi",
3994
14
        FT_UINT8, BASE_HEX, VALS(sccp_isni_mark_for_id_values), ANSI_ISNI_MI_MASK,
3995
14
        NULL, HFILL}
3996
14
    },
3997
14
    { &hf_sccp_ansi_isni_iri,
3998
14
      { "ISNI Routing Indicator", "sccp.isni.iri",
3999
14
        FT_UINT8, BASE_HEX, VALS(sccp_isni_iri_values), ANSI_ISNI_IRI_MASK,
4000
14
        NULL, HFILL}
4001
14
    },
4002
14
    { &hf_sccp_ansi_isni_ti,
4003
14
      { "ISNI Type Indicator", "sccp.isni.ti",
4004
14
        FT_UINT8, BASE_HEX, VALS(sccp_isni_ti_values), ANSI_ISNI_TI_MASK,
4005
14
        NULL, HFILL}
4006
14
    },
4007
14
    { &hf_sccp_ansi_isni_netspec,
4008
14
      { "ISNI Network Specific (Type 1)", "sccp.isni.netspec",
4009
14
        FT_UINT8, BASE_HEX, NULL, ANSI_ISNI_NETSPEC_MASK,
4010
14
        NULL, HFILL}
4011
14
    },
4012
14
    { &hf_sccp_ansi_isni_counter,
4013
14
      { "ISNI Counter", "sccp.isni.counter",
4014
14
        FT_UINT8, BASE_DEC, NULL, ANSI_ISNI_COUNTER_MASK,
4015
14
        NULL, HFILL}
4016
14
    },
4017
14
    { &hf_sccp_ansi_isni_network,
4018
14
      { "Network ID network", "sccp.isni.network",
4019
14
        FT_UINT8, BASE_DEC, NULL, 0x0,
4020
14
        NULL, HFILL}
4021
14
    },
4022
14
    { &hf_sccp_ansi_isni_cluster,
4023
14
      { "Network ID cluster", "sccp.isni.cluster",
4024
14
        FT_UINT8, BASE_DEC, NULL, 0x0,
4025
14
        NULL, HFILL}
4026
14
    },
4027
14
    {&hf_sccp_xudt_msg_fragments,
4028
14
     { "Message fragments", "sccp.msg.fragments",
4029
14
       FT_NONE, BASE_NONE, NULL, 0x00,
4030
14
       NULL, HFILL }
4031
14
    },
4032
14
    {&hf_sccp_xudt_msg_fragment,
4033
14
     { "Message fragment", "sccp.msg.fragment",
4034
14
       FT_FRAMENUM, BASE_NONE, NULL, 0x00,
4035
14
       NULL, HFILL }
4036
14
    },
4037
14
    {&hf_sccp_xudt_msg_fragment_overlap,
4038
14
     { "Message fragment overlap", "sccp.msg.fragment.overlap",
4039
14
       FT_BOOLEAN, BASE_NONE, NULL, 0x0,
4040
14
       NULL, HFILL }
4041
14
    },
4042
14
    {&hf_sccp_xudt_msg_fragment_overlap_conflicts,
4043
14
     { "Message fragment overlapping with conflicting data", "sccp.msg.fragment.overlap.conflicts",
4044
14
       FT_BOOLEAN, BASE_NONE, NULL, 0x0,
4045
14
       NULL, HFILL }
4046
14
    },
4047
14
    {&hf_sccp_xudt_msg_fragment_multiple_tails,
4048
14
     { "Message has multiple tail fragments", "sccp.msg.fragment.multiple_tails",
4049
14
       FT_BOOLEAN, BASE_NONE, NULL, 0x0,
4050
14
       NULL, HFILL }
4051
14
    },
4052
14
    {&hf_sccp_xudt_msg_fragment_too_long_fragment,
4053
14
     { "Message fragment too long", "sccp.msg.fragment.too_long_fragment",
4054
14
       FT_BOOLEAN, BASE_NONE, NULL, 0x0,
4055
14
       NULL, HFILL }
4056
14
    },
4057
14
    {&hf_sccp_xudt_msg_fragment_error,
4058
14
     { "Message defragmentation error", "sccp.msg.fragment.error",
4059
14
       FT_FRAMENUM, BASE_NONE, NULL, 0x00,
4060
14
       NULL, HFILL }
4061
14
    },
4062
14
    {&hf_sccp_xudt_msg_fragment_count,
4063
14
     { "Message fragment count", "sccp.msg.fragment.count",
4064
14
       FT_UINT32, BASE_DEC, NULL, 0x00,
4065
14
       NULL, HFILL }
4066
14
    },
4067
14
    {&hf_sccp_xudt_msg_reassembled_in,
4068
14
     { "Reassembled in", "sccp.msg.reassembled.in",
4069
14
       FT_FRAMENUM, BASE_NONE, NULL, 0x00,
4070
14
       NULL, HFILL }
4071
14
    },
4072
14
    {&hf_sccp_xudt_msg_reassembled_length,
4073
14
     { "Reassembled SCCP length", "sccp.msg.reassembled.length",
4074
14
       FT_UINT32, BASE_DEC, NULL, 0x00,
4075
14
       NULL, HFILL }
4076
14
    },
4077
14
    { &hf_sccp_assoc_id,
4078
14
      { "Association ID", "sccp.assoc.id",
4079
14
        FT_UINT32, BASE_DEC, NULL, 0x0,
4080
14
        NULL, HFILL}
4081
14
    },
4082
14
    {&hf_sccp_assoc_msg,
4083
14
     { "Message in frame", "sccp.assoc.msg",
4084
14
       FT_FRAMENUM, BASE_NONE, NULL, 0x00,
4085
14
       NULL, HFILL }
4086
14
    },
4087
14
    {&hf_sccp_segmented_data,
4088
14
     { "Segmented Data", "sccp.segmented_data",
4089
14
       FT_BYTES, BASE_NONE, NULL, 0x00,
4090
14
       NULL, HFILL }
4091
14
    },
4092
14
    {&hf_sccp_linked_dissector,
4093
14
     { "Linked dissector", "sccp.linked_dissector",
4094
14
       FT_STRING, BASE_NONE, NULL, 0x00,
4095
14
       NULL, HFILL }
4096
14
    },
4097
14
    {&hf_sccp_end_optional_param,
4098
14
     { "End of Optional", "sccp.end_optional_param",
4099
14
       FT_NONE, BASE_NONE, NULL, 0x00,
4100
14
       NULL, HFILL }
4101
14
    },
4102
14
    {&hf_sccp_unknown_message,
4103
14
     { "Unknown message", "sccp.unknown_message",
4104
14
       FT_BYTES, BASE_NONE, NULL, 0x00,
4105
14
       NULL, HFILL }
4106
14
    },
4107
14
    {&hf_sccp_unknown_parameter,
4108
14
     { "Unknown parameter", "sccp.unknown_parameter",
4109
14
       FT_BYTES, BASE_NONE, NULL, 0x00,
4110
14
       NULL, HFILL }
4111
14
    },
4112
14
  };
4113
4114
  /* Setup protocol subtree array */
4115
14
  static int *ett[] = {
4116
14
    &ett_sccp,
4117
14
    &ett_sccp_called,
4118
14
    &ett_sccp_called_ai,
4119
14
    &ett_sccp_called_pc,
4120
14
    &ett_sccp_called_gt,
4121
14
    &ett_sccp_called_gt_digits,
4122
14
    &ett_sccp_calling,
4123
14
    &ett_sccp_calling_ai,
4124
14
    &ett_sccp_calling_pc,
4125
14
    &ett_sccp_calling_gt,
4126
14
    &ett_sccp_calling_gt_digits,
4127
14
    &ett_sccp_sequencing_segmenting,
4128
14
    &ett_sccp_segmentation,
4129
14
    &ett_sccp_ansi_isni_routing_control,
4130
14
    &ett_sccp_xudt_msg_fragment,
4131
14
    &ett_sccp_xudt_msg_fragments,
4132
14
    &ett_sccp_assoc
4133
14
  };
4134
4135
14
  static ei_register_info ei[] = {
4136
14
     { &ei_sccp_wrong_length, { "sccp.wrong_length", PI_MALFORMED, PI_ERROR, "Wrong length indicated.", EXPFILL }},
4137
14
     { &ei_sccp_international_standard_address, { "sccp.international_standard_address", PI_MALFORMED, PI_WARN,
4138
14
            "Address is coded to international standards. This doesn't normally happen in ANSI networks.", EXPFILL }},
4139
14
     { &ei_sccp_no_ssn_present, { "sccp.ssn.not_present", PI_PROTOCOL, PI_WARN, "Message is routed on SSN, but SSN is not present", EXPFILL }},
4140
14
     { &ei_sccp_ssn_zero, { "sccp.ssn.is_zero", PI_PROTOCOL, PI_WARN, "Message is routed on SSN, but SSN is zero (unspecified)", EXPFILL }},
4141
14
     { &ei_sccp_class_unexpected, { "sccp.class_unexpected", PI_MALFORMED, PI_ERROR, "Unexpected message class for this message type", EXPFILL }},
4142
14
     { &ei_sccp_handling_invalid, { "sccp.handling_invalid", PI_MALFORMED, PI_ERROR, "Invalid message handling", EXPFILL }},
4143
14
     { &ei_sccp_gt_digits_missing, { "sccp.gt_digits_missing", PI_MALFORMED, PI_ERROR, "Address digits missing", EXPFILL }},
4144
14
     { &ei_sccp_externally_reassembled, { "sccp.externally_reassembled", PI_ASSUMPTION, PI_NOTE, "Possibly externally reassembled (remaining length > 255 bytes), enable in SCCP preferences", EXPFILL }},
4145
14
  };
4146
4147
  /* Decode As handling */
4148
14
  static build_valid_func sccp_da_build_value[1] = {sccp_value};
4149
14
  static decode_as_value_t sccp_da_values = {sccp_prompt, 1, sccp_da_build_value};
4150
14
  static decode_as_t sccp_da = {"sccp", "sccp.ssn", 1, 0, &sccp_da_values, NULL, NULL,
4151
14
                                    decode_as_default_populate_list, decode_as_default_reset, decode_as_default_change, NULL};
4152
4153
14
  module_t *sccp_module;
4154
14
  expert_module_t* expert_sccp;
4155
4156
14
  static uat_field_t users_flds[] = {
4157
14
    UAT_FLD_DEC(sccp_users, ni, "Network Indicator", "Network Indicator"),
4158
14
    UAT_FLD_RANGE(sccp_users, called_pc, "Called DPCs", 0xFFFFFF, "DPCs for which this protocol is to be used"),
4159
14
    UAT_FLD_RANGE(sccp_users, called_ssn, "Called SSNs", 255, "Called SSNs for which this protocol is to be used"),
4160
14
    UAT_FLD_VS(sccp_users, user, "User protocol", sccp_users_vals, "The User Protocol"),
4161
14
    UAT_END_FIELDS
4162
14
  };
4163
4164
4165
14
  uat_t *users_uat = uat_new("SCCP Users Table", sizeof(sccp_user_t),
4166
14
                             "sccp_users", true, &sccp_users,
4167
14
                             &num_sccp_users, UAT_AFFECTS_DISSECTION,
4168
14
                             "ChSccpUsers", sccp_users_copy_cb,
4169
14
                             sccp_users_update_cb, sccp_users_free_cb,
4170
14
                             NULL, NULL, users_flds );
4171
4172
  /* Register the protocol name and description */
4173
14
  proto_sccp = proto_register_protocol("Signalling Connection Control Part", "SCCP", "sccp");
4174
4175
14
  sccp_handle = register_dissector("sccp", dissect_sccp, proto_sccp);
4176
4177
  /* Required function calls to register the header fields and subtrees used */
4178
14
  proto_register_field_array(proto_sccp, hf, array_length(hf));
4179
14
  proto_register_subtree_array(ett, array_length(ett));
4180
14
  expert_sccp = expert_register_protocol(proto_sccp);
4181
14
  expert_register_field_array(expert_sccp, ei, array_length(ei));
4182
4183
14
  sccp_ssn_dissector_table = register_dissector_table("sccp.ssn", "SCCP SSN", proto_sccp, FT_UINT8, BASE_DEC);
4184
4185
14
  heur_subdissector_list = register_heur_dissector_list_with_description("sccp", "SCCP Data fallback", proto_sccp);
4186
4187
14
  sccp_module = prefs_register_protocol(proto_sccp, proto_reg_handoff_sccp);
4188
4189
14
  prefs_register_uint_preference(sccp_module, "source_pc",
4190
14
                                 "Source PC (in hex)",
4191
14
                                 "The source point code (usually MSC) (to determine whether message is uplink or downlink)",
4192
14
                                 16, &sccp_source_pc_global);
4193
4194
14
  prefs_register_bool_preference(sccp_module, "show_length", "Show length",
4195
14
                                 "Show parameter length in the protocol tree",
4196
14
                                 &sccp_show_length);
4197
4198
14
  prefs_register_bool_preference(sccp_module, "defragment_xudt",
4199
14
                                 "Reassemble SCCP messages",
4200
14
                                 "Whether SCCP messages should be reassembled",
4201
14
                                 &sccp_reassemble);
4202
4203
14
  prefs_register_bool_preference(sccp_module, "trace_sccp",
4204
14
                                 "Trace Associations",
4205
14
                                 "Whether to keep information about messages and their associations",
4206
14
                                 &trace_sccp);
4207
4208
4209
14
  prefs_register_bool_preference(sccp_module, "show_more_info",
4210
14
                                 "Show key parameters in Info Column",
4211
14
                                 "Show SLR, DLR, and CAUSE Parameters in the Information Column of the Summary",
4212
14
                                 &show_key_params);
4213
4214
4215
14
  prefs_register_uat_preference(sccp_module, "users_table", "Users Table",
4216
14
                                "A table that enumerates user protocols to be used against specific PCs and SSNs",
4217
14
                                users_uat);
4218
4219
14
  prefs_register_bool_preference(sccp_module, "set_addresses", "Set source and destination GT addresses",
4220
14
                                 "Set the source and destination addresses to the GT digits (if present)."
4221
14
                                 "  This may affect TCAP's ability to recognize which messages belong to which TCAP session.",
4222
14
                                 &set_addresses);
4223
4224
14
  prefs_register_dissector_preference(sccp_module, "default_payload", "Default Payload",
4225
14
                                   "The dissector which should be used to dissect the payload if nothing else has claimed it",
4226
14
                                   &default_payload);
4227
4228
14
  prefs_register_bool_preference(sccp_module, "dt1_ignore_length", "Dissect data past 255 byte limit",
4229
14
                                 "Use all bytes for data payload. Overcome 255 bytes limit of SCCP standard."
4230
14
                                 "  (Some tracing tools externally reassemble segmented data.)",
4231
14
                                 &dt1_ignore_length);
4232
4233
14
  register_init_routine(&init_sccp);
4234
14
  reassembly_table_register(&sccp_xudt_msg_reassembly_table,
4235
14
                         &addresses_reassembly_table_functions);
4236
4237
14
  assocs = wmem_tree_new_autoreset(wmem_epan_scope(), wmem_file_scope());
4238
4239
14
  sccp_reassembly_ids = wmem_tree_new_autoreset(wmem_epan_scope(), wmem_file_scope());
4240
14
  sccp_reassembly_id_map = wmem_map_new_autoreset(wmem_epan_scope(), wmem_file_scope(),
4241
14
      g_int64_hash, g_int64_equal);
4242
4243
14
  sccp_tap = register_tap("sccp");
4244
4245
14
  register_decode_as(&sccp_da);
4246
14
}
4247
4248
void
4249
proto_reg_handoff_sccp(void)
4250
14
{
4251
14
  static bool initialised = false;
4252
4253
14
  if (!initialised) {
4254
14
    dissector_add_uint("wtap_encap", WTAP_ENCAP_SCCP, sccp_handle);
4255
14
    dissector_add_uint("mtp3.service_indicator", MTP_SI_SCCP, sccp_handle);
4256
14
    dissector_add_string("tali.opcode", "sccp", sccp_handle);
4257
4258
14
    data_handle       = find_dissector("data");
4259
14
    tcap_handle       = find_dissector_add_dependency("tcap", proto_sccp);
4260
14
    ranap_handle      = find_dissector_add_dependency("ranap", proto_sccp);
4261
14
    bssap_handle      = find_dissector_add_dependency("bssap", proto_sccp);
4262
14
    gsmmap_handle     = find_dissector_add_dependency("gsm_map_sccp", proto_sccp);
4263
14
    camel_handle      = find_dissector_add_dependency("camel", proto_sccp);
4264
14
    inap_handle       = find_dissector_add_dependency("inap", proto_sccp);
4265
14
    bsap_handle       = find_dissector_add_dependency("bsap", proto_sccp);
4266
14
    bssap_le_handle   = find_dissector_add_dependency("bssap_le", proto_sccp);
4267
14
    bssap_plus_handle = find_dissector_add_dependency("bssap_plus", proto_sccp);
4268
4269
14
    ss7pc_address_type = address_type_get_by_name("AT_SS7PC");
4270
4271
14
    initialised = true;
4272
14
    hf_assoc_imsi = proto_registrar_get_id_byname("e212.assoc.imsi");
4273
14
  }
4274
4275
14
  default_handle = find_dissector(default_payload);
4276
14
}
4277
4278
/*
4279
 * Editor modelines  -  https://www.wireshark.org/tools/modelines.html
4280
 *
4281
 * Local Variables:
4282
 * c-basic-offset: 2
4283
 * tab-width: 8
4284
 * indent-tabs-mode: nil
4285
 * End:
4286
 *
4287
 * ex: set shiftwidth=2 tabstop=8 expandtab:
4288
 * :indentSize=2:tabSize=8:noTabs=true:
4289
 */