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