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