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