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