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