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