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