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