2 * Routines for Signalling Connection Control Part (SCCP) dissection
4 * It is hopefully compliant to:
7 * YDN 038-1997 (Chinese ITU variant)
8 * JT-Q713 and NTT-Q713 (Japan)
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.
13 * Copyright 2002, Jeff Morriss <jeff.morriss[AT]ulticom.com>
17 * Ethereal - Network traffic analyzer
18 * By Gerald Combs <gerald@ethereal.com>
19 * Copyright 1998 Gerald Combs
21 * Copied from packet-m2pa.c
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.
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.
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.
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"
56 static Standard_Type decode_mtp3_standard;
59 #define MESSAGE_TYPE_OFFSET 0
60 #define MESSAGE_TYPE_LENGTH 1
61 #define POINTER_LENGTH 1
62 #define POINTER_LENGTH_LONG 2
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
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)" },
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" },
134 #define PARAMETER_LENGTH_LENGTH 1
135 #define PARAMETER_LONG_DATA_LENGTH_LENGTH 2
136 #define PARAMETER_TYPE_LENGTH 1
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
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)" },
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
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
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
215 static const value_string sccp_national_indicator_values[] = {
216 { 0x0, "Address coded to International standard" },
217 { 0x1, "Address coded to National standard" },
220 static const value_string sccp_routing_indicator_values[] = {
221 { 0x0, "Route on GT" },
222 { 0x1, "Route on SSN" },
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" },
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" },
247 static const value_string sccp_ai_pci_values[] = {
248 { 0x1, "Point Code present" },
249 { 0x0, "Point Code not present" },
252 static const value_string sccp_ai_ssni_values[] = {
253 { 0x1, "SSN present" },
254 { 0x0, "SSN not present" },
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.
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:
284 { 0x91, "GMLC(MAP)" },
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:*/
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" },
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" },
314 #define GT_OE_MASK 0x80
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" },
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[] = {
347 /* * * * * * * * * * * * * * * * * * * * *
348 * Global Title: ITU and ANSI GTI == 0010 *
349 * * * * * * * * * * * * * * * * * * * * */
350 #define GT_TT_LENGTH 1
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[] = {
360 { 0x1, "ISDN/telephony" },
361 { 0x2, "Generic (ITU)/Reserved (ANSI)" },
364 { 0x5, "Maritime mobile" },
365 { 0x6, "Land mobile" },
366 { 0x7, "ISDN/mobile" },
367 { 0xe, "Private network or network-specific" },
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)" },
385 /* Address signals above */
388 /* * * * * * * * * * * * * * * * *
389 * Global Title: ITU GTI == 0100 *
390 * * * * * * * * * * * * * * * * */
394 /* Address signals above */
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" },
405 #define SEGMENTING_REASSEMBLING_LENGTH 1
406 #define SEGMENTING_REASSEMBLING_MASK 0x01
407 #define NO_MORE_DATA 0
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" },
416 #define RECEIVE_SEQUENCE_NUMBER_LENGTH 1
417 #define RSN_MASK 0xfe
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
427 #define CREDIT_LENGTH 1
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)" },
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)" },
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" },
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" },
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" },
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" },
538 static const value_string sccp_segmentation_class_values [] = {
539 { 0, "Class 0 selected" },
540 { 1, "Class 1 selected" },
544 #define HOP_COUNTER_LENGTH 1
546 #define IMPORTANCE_LENGTH 1
547 #define IMPORTANCE_IMPORTANCE_MASK 0x7
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
558 #define ANSI_ISNI_NETSPEC_MASK 0x03
560 static const value_string sccp_isni_mark_for_id_values [] = {
561 { 0x0, "Do not identify networks" },
562 { 0x1, "Identify networks" },
565 static const value_string sccp_isni_iri_values [] = {
566 { 0x0, "Neither constrained nor suggested ISNI routing" },
567 { 0x1, "Constrained ISNI routing" },
568 { 0x2, "Reserved for suggested ISNI routing" },
572 #define ANSI_ISNI_TYPE_0 0x0
573 #define ANSI_ISNI_TYPE_1 0x1
574 static const value_string sccp_isni_ti_values [] = {
575 { ANSI_ISNI_TYPE_0, "Type zero ISNI parameter format" },
576 { ANSI_ISNI_TYPE_1, "Type one ISNI parameter format" },
580 /* Initialize the protocol and registered fields */
581 static int proto_sccp = -1;
582 static int hf_sccp_message_type = -1;
583 static int hf_sccp_variable_pointer1 = -1;
584 static int hf_sccp_variable_pointer2 = -1;
585 static int hf_sccp_variable_pointer3 = -1;
586 static int hf_sccp_optional_pointer = -1;
587 static int hf_sccp_ssn = -1;
588 static int hf_sccp_gt_digits = -1;
590 /* Called Party address */
591 static int hf_sccp_called_national_indicator = -1;
592 static int hf_sccp_called_routing_indicator = -1;
593 static int hf_sccp_called_itu_global_title_indicator = -1;
594 static int hf_sccp_called_ansi_global_title_indicator = -1;
595 static int hf_sccp_called_itu_ssn_indicator = -1;
596 static int hf_sccp_called_itu_point_code_indicator = -1;
597 static int hf_sccp_called_ansi_ssn_indicator = -1;
598 static int hf_sccp_called_ansi_point_code_indicator = -1;
599 static int hf_sccp_called_ssn = -1;
600 static int hf_sccp_called_pc_member = -1;
601 static int hf_sccp_called_pc_cluster = -1;
602 static int hf_sccp_called_pc_network = -1;
603 static int hf_sccp_called_ansi_pc = -1;
604 static int hf_sccp_called_chinese_pc = -1;
605 static int hf_sccp_called_itu_pc = -1;
606 static int hf_sccp_called_japan_pc = -1;
607 static int hf_sccp_called_gt_nai = -1;
608 static int hf_sccp_called_gt_oe = -1;
609 static int hf_sccp_called_gt_tt = -1;
610 static int hf_sccp_called_gt_np = -1;
611 static int hf_sccp_called_gt_es = -1;
612 static int hf_sccp_called_gt_digits = -1;
614 /* Calling party address */
615 static int hf_sccp_calling_national_indicator = -1;
616 static int hf_sccp_calling_routing_indicator = -1;
617 static int hf_sccp_calling_itu_global_title_indicator = -1;
618 static int hf_sccp_calling_ansi_global_title_indicator = -1;
619 static int hf_sccp_calling_itu_ssn_indicator = -1;
620 static int hf_sccp_calling_itu_point_code_indicator = -1;
621 static int hf_sccp_calling_ansi_ssn_indicator = -1;
622 static int hf_sccp_calling_ansi_point_code_indicator = -1;
623 static int hf_sccp_calling_ssn = -1;
624 static int hf_sccp_calling_pc_member = -1;
625 static int hf_sccp_calling_pc_cluster = -1;
626 static int hf_sccp_calling_pc_network = -1;
627 static int hf_sccp_calling_ansi_pc = -1;
628 static int hf_sccp_calling_chinese_pc = -1;
629 static int hf_sccp_calling_itu_pc = -1;
630 static int hf_sccp_calling_japan_pc = -1;
631 static int hf_sccp_calling_gt_nai = -1;
632 static int hf_sccp_calling_gt_oe = -1;
633 static int hf_sccp_calling_gt_tt = -1;
634 static int hf_sccp_calling_gt_np = -1;
635 static int hf_sccp_calling_gt_es = -1;
636 static int hf_sccp_calling_gt_digits = -1;
638 /* Other parameter values */
639 static int hf_sccp_dlr = -1;
640 static int hf_sccp_slr = -1;
641 static int hf_sccp_lr = -1;
642 static int hf_sccp_class = -1;
643 static int hf_sccp_handling = -1;
644 static int hf_sccp_more = -1;
645 static int hf_sccp_rsn = -1;
646 static int hf_sccp_sequencing_segmenting_ssn = -1;
647 static int hf_sccp_sequencing_segmenting_rsn = -1;
648 static int hf_sccp_sequencing_segmenting_more = -1;
649 static int hf_sccp_credit = -1;
650 static int hf_sccp_release_cause = -1;
651 static int hf_sccp_return_cause = -1;
652 static int hf_sccp_reset_cause = -1;
653 static int hf_sccp_error_cause = -1;
654 static int hf_sccp_refusal_cause = -1;
655 static int hf_sccp_segmentation_first = -1;
656 static int hf_sccp_segmentation_class = -1;
657 static int hf_sccp_segmentation_remaining = -1;
658 static int hf_sccp_segmentation_slr = -1;
659 static int hf_sccp_hop_counter = -1;
660 static int hf_sccp_importance = -1;
661 static int hf_sccp_ansi_isni_mi = -1;
662 static int hf_sccp_ansi_isni_iri = -1;
663 static int hf_sccp_ansi_isni_ti = -1;
664 static int hf_sccp_ansi_isni_netspec = -1;
665 static int hf_sccp_ansi_isni_counter = -1;
666 static int hf_sccp_xudt_msg_fragments = -1;
667 static int hf_sccp_xudt_msg_fragment = -1;
668 static int hf_sccp_xudt_msg_fragment_overlap = -1;
669 static int hf_sccp_xudt_msg_fragment_overlap_conflicts = -1;
670 static int hf_sccp_xudt_msg_fragment_multiple_tails = -1;
671 static int hf_sccp_xudt_msg_fragment_too_long_fragment = -1;
672 static int hf_sccp_xudt_msg_fragment_error = -1;
673 static int hf_sccp_xudt_msg_reassembled_in = -1;
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 /* Declarations to desegment XUDT Messages */
692 static gboolean sccp_xudt_desegment = TRUE;
694 static const fragment_items sccp_xudt_msg_frag_items = {
695 /* Fragment subtrees */
696 &ett_sccp_xudt_msg_fragment,
697 &ett_sccp_xudt_msg_fragments,
698 /* Fragment fields */
699 &hf_sccp_xudt_msg_fragments,
700 &hf_sccp_xudt_msg_fragment,
701 &hf_sccp_xudt_msg_fragment_overlap,
702 &hf_sccp_xudt_msg_fragment_overlap_conflicts,
703 &hf_sccp_xudt_msg_fragment_multiple_tails,
704 &hf_sccp_xudt_msg_fragment_too_long_fragment,
705 &hf_sccp_xudt_msg_fragment_error,
706 /* Reassembled in field */
707 &hf_sccp_xudt_msg_reassembled_in,
709 "SCCP XUDT Message fragments"
712 static GHashTable *sccp_xudt_msg_fragment_table = NULL;
713 static GHashTable *sccp_xudt_msg_reassembled_table = NULL;
718 * Here are the global variables associated with
719 * the various user definable characteristics of the dissection
721 static guint32 sccp_source_pc_global = 0;
722 static gboolean sccp_show_length = FALSE;
724 static module_t *sccp_module;
725 static heur_dissector_list_t heur_subdissector_list;
727 /* Keep track of SSN value of current message so if/when we get to the data
728 * parameter, we can call appropriate sub-dissector. TODO: can this info
729 * be stored elsewhere?
732 static guint8 message_type = 0;
733 static guint dlr = 0;
734 static guint slr = 0;
736 static dissector_handle_t data_handle;
737 static dissector_table_t sccp_ssn_dissector_table;
739 static se_tree_t* assocs = NULL;
740 sccp_assoc_info_t* assoc;
741 sccp_assoc_info_t no_assoc = {0,0,0,0,FALSE,FALSE,SCCP_PLOAD_NONE,NULL};
743 static sccp_assoc_info_t* sccp_assoc(address* opc, address* dpc, guint src_lr, guint dst_lr) {
749 if (!src_lr && !dst_lr)
752 opck = opc->type == AT_SS7PC ? mtp3_pc_hash(opc->data) : g_str_hash(address_to_str(opc));
753 dpck = dpc->type == AT_SS7PC ? mtp3_pc_hash(dpc->data) : g_str_hash(address_to_str(dpc));
755 switch (message_type) {
756 case MESSAGE_TYPE_CR:
758 se_tree_key_t key[] = {
765 if (! ( assoc = se_tree_lookup32_array(assocs,key) ) ) {
766 assoc = se_alloc(sizeof(sccp_assoc_info_t));
768 assoc->calling_dpc = dpck;
769 assoc->called_dpc = opck;
770 assoc->calling_ssn = INVALID_SSN;
771 assoc->called_ssn = INVALID_SSN;
772 assoc->has_calling_key = FALSE;
773 assoc->has_called_key = TRUE;
774 assoc->pload = SCCP_PLOAD_NONE;
775 assoc->private_data = NULL;
777 se_tree_insert32_array(assocs,key,assoc);
781 case MESSAGE_TYPE_CC:
783 se_tree_key_t called_key[] = {
789 se_tree_key_t calling_key[] = {
796 if (( assoc = se_tree_lookup32_array(assocs,calling_key) )) {
797 if ( ! assoc->has_called_key ) {
798 se_tree_insert32_array(assocs,called_key,assoc);
799 assoc->has_called_key = TRUE;
801 } else if (( assoc = se_tree_lookup32_array(assocs,called_key) )) {
802 if ( ! assoc->has_calling_key ) {
803 se_tree_insert32_array(assocs,calling_key,assoc);
804 assoc->has_calling_key = TRUE;
807 assoc = se_alloc(sizeof(sccp_assoc_info_t));
809 assoc->calling_dpc = dpck;
810 assoc->called_dpc = opck;
811 assoc->calling_ssn = INVALID_SSN;
812 assoc->called_ssn = INVALID_SSN;
813 assoc->has_calling_key = TRUE;
814 assoc->has_called_key = TRUE;
815 assoc->pload = SCCP_PLOAD_NONE;
816 assoc->private_data = NULL;
818 se_tree_insert32_array(assocs,calling_key,assoc);
819 se_tree_insert32_array(assocs,called_key,assoc);
826 se_tree_key_t calling_key[] = {
833 assoc = se_tree_lookup32_array(assocs,calling_key);
839 return assoc ? assoc : &no_assoc;
844 dissect_sccp_unknown_message(tvbuff_t *message_tvb, proto_tree *sccp_tree)
846 guint32 message_length;
848 message_length = tvb_length(message_tvb);
850 proto_tree_add_text(sccp_tree, message_tvb, 0, message_length,
851 "Unknown message (%u byte%s)",
852 message_length, plurality(message_length, "", "s"));
856 dissect_sccp_unknown_param(tvbuff_t *tvb, proto_tree *tree, guint8 type, guint length)
858 proto_tree_add_text(tree, tvb, 0, length, "Unknown parameter 0x%x (%u byte%s)",
859 type, length, plurality(length, "", "s"));
863 dissect_sccp_dlr_param(tvbuff_t *tvb, proto_tree *tree, guint length)
867 dlr = tvb_get_letoh24(tvb, 0);
868 proto_tree_add_uint(tree, hf_sccp_dlr, tvb, 0, length, dlr);
869 lr_item = proto_tree_add_uint(tree, hf_sccp_lr, tvb, 0, length, dlr);
870 PROTO_ITEM_SET_HIDDEN(lr_item);
874 dissect_sccp_slr_param(tvbuff_t *tvb, proto_tree *tree, guint length)
878 slr = tvb_get_letoh24(tvb, 0);
879 proto_tree_add_uint(tree, hf_sccp_slr, tvb, 0, length, slr);
880 lr_item = proto_tree_add_uint(tree, hf_sccp_lr, tvb, 0, length, slr);
881 PROTO_ITEM_SET_HIDDEN(lr_item);
885 dissect_sccp_gt_address_information(tvbuff_t *tvb, proto_tree *tree,
886 guint length, gboolean even_length,
890 guint8 odd_signal, even_signal = 0x0f;
891 char gt_digits[GT_MAX_SIGNALS+1] = { 0 };
893 while(offset < length)
895 odd_signal = tvb_get_guint8(tvb, offset) & GT_ODD_SIGNAL_MASK;
896 even_signal = tvb_get_guint8(tvb, offset) & GT_EVEN_SIGNAL_MASK;
897 even_signal >>= GT_EVEN_SIGNAL_SHIFT;
899 strncat(gt_digits, val_to_str(odd_signal, sccp_address_signal_values,
900 "Unknown"), GT_MAX_SIGNALS - strlen(gt_digits));
902 /* If the last signal is NOT filler */
903 if (offset != (length - 1) || even_length == TRUE)
904 strncat(gt_digits, val_to_str(even_signal, sccp_address_signal_values,
905 "Unknown"), GT_MAX_SIGNALS - strlen(gt_digits));
907 offset += GT_SIGNAL_LENGTH;
910 proto_tree_add_string_format(tree, called ? hf_sccp_called_gt_digits
911 : hf_sccp_calling_gt_digits,
914 "Address information (digits): %s", gt_digits);
915 proto_tree_add_string_hidden(tree, called ? hf_sccp_gt_digits
922 dissect_sccp_global_title(tvbuff_t *tvb, proto_tree *tree, guint length,
923 guint8 gti, gboolean called)
925 proto_item *gt_item = 0;
926 proto_tree *gt_tree = 0;
927 tvbuff_t *signals_tvb;
929 guint8 odd_even, nai, tt, np, es;
930 gboolean even = TRUE;
932 /* Shift GTI to where we can work with it */
935 gt_item = proto_tree_add_text(tree, tvb, offset, length,
936 "Global Title 0x%x (%u byte%s)",
937 gti, length, plurality(length,"", "s"));
938 gt_tree = proto_item_add_subtree(gt_item, called ? ett_sccp_called_gt
939 : ett_sccp_calling_gt);
941 /* Decode Transation Type (if present) */
945 /* Protocol doesn't tell us, so we ASSUME even... */
948 case ITU_AI_GTI_TT_NP_ES:
949 case ITU_AI_GTI_TT_NP_ES_NAI:
950 case ANSI_AI_GTI_TT_NP_ES:
952 tt = tvb_get_guint8(tvb, offset);
953 proto_tree_add_uint(gt_tree, called ? hf_sccp_called_gt_tt
954 : hf_sccp_calling_gt_tt,
955 tvb, offset, GT_TT_LENGTH, tt);
956 offset += GT_TT_LENGTH;
959 /* Decode Numbering Plan and Encoding Scheme (if present) */
961 case ITU_AI_GTI_TT_NP_ES:
962 case ITU_AI_GTI_TT_NP_ES_NAI:
963 case ANSI_AI_GTI_TT_NP_ES:
965 np = tvb_get_guint8(tvb, offset) & GT_NP_MASK;
966 proto_tree_add_uint(gt_tree, called ? hf_sccp_called_gt_np
967 : hf_sccp_calling_gt_np,
968 tvb, offset, GT_NP_ES_LENGTH, np);
970 es = tvb_get_guint8(tvb, offset) & GT_ES_MASK;
971 proto_tree_add_uint(gt_tree, called ? hf_sccp_called_gt_es
972 : hf_sccp_calling_gt_es,
973 tvb, offset, GT_NP_ES_LENGTH, es);
975 even = (es == GT_ES_BCD_EVEN) ? TRUE : FALSE;
977 offset += GT_NP_ES_LENGTH;
980 /* Decode Odd/Even Indicator (if present) */
981 if (gti == ITU_AI_GTI_NAI) {
982 odd_even = tvb_get_guint8(tvb, offset) & GT_OE_MASK;
983 proto_tree_add_uint(gt_tree, called ? hf_sccp_called_gt_oe
984 : hf_sccp_calling_gt_oe,
985 tvb, offset, GT_NAI_LENGTH, odd_even);
986 even = (odd_even == GT_OE_EVEN) ? TRUE : FALSE;
988 /* offset doesn't change */
991 /* Decode Nature of Address Indicator (if present) */
994 case ITU_AI_GTI_TT_NP_ES_NAI:
995 nai = tvb_get_guint8(tvb, offset) & GT_NAI_MASK;
996 proto_tree_add_uint(gt_tree, called ? hf_sccp_called_gt_nai
997 : hf_sccp_calling_gt_nai,
998 tvb, offset, GT_NAI_LENGTH, nai);
1000 offset += GT_NAI_LENGTH;
1003 /* Decode address signal(s) */
1004 if (length < offset)
1006 signals_tvb = tvb_new_subset(tvb, offset, (length - offset),
1008 dissect_sccp_gt_address_information(signals_tvb, gt_tree, (length - offset),
1014 dissect_sccp_3byte_pc(tvbuff_t *tvb, proto_tree *call_tree, guint offset,
1018 proto_item *call_pc_item = 0;
1019 proto_tree *call_pc_tree = 0;
1020 char pc[ANSI_PC_STRING_LENGTH];
1023 if (decode_mtp3_standard == ANSI_STANDARD)
1026 hf_pc = &hf_sccp_called_ansi_pc;
1028 hf_pc = &hf_sccp_calling_ansi_pc;
1029 } else /* CHINESE_ITU_STANDARD */ {
1031 hf_pc = &hf_sccp_called_chinese_pc;
1033 hf_pc = &hf_sccp_calling_chinese_pc;
1036 /* create the DPC tree; modified from that in packet-mtp3.c */
1037 dpc = tvb_get_ntoh24(tvb, offset);
1038 g_snprintf(pc, sizeof(pc), "%d-%d-%d", (dpc & ANSI_NETWORK_MASK),
1039 ((dpc & ANSI_CLUSTER_MASK) >> 8),
1040 ((dpc & ANSI_MEMBER_MASK) >> 16));
1042 call_pc_item = proto_tree_add_string_format(call_tree, *hf_pc,
1043 tvb, offset, ANSI_PC_LENGTH,
1046 call_pc_tree = proto_item_add_subtree(call_pc_item,
1047 called ? ett_sccp_called_pc
1048 : ett_sccp_calling_pc);
1050 proto_tree_add_uint(call_pc_tree, called ? hf_sccp_called_pc_member
1051 : hf_sccp_calling_pc_member,
1052 tvb, offset, ANSI_NCM_LENGTH, dpc);
1053 offset += ANSI_NCM_LENGTH;
1054 proto_tree_add_uint(call_pc_tree, called ? hf_sccp_called_pc_cluster
1055 : hf_sccp_calling_pc_cluster,
1056 tvb, offset, ANSI_NCM_LENGTH, dpc);
1057 offset += ANSI_NCM_LENGTH;
1058 proto_tree_add_uint(call_pc_tree, called ? hf_sccp_called_pc_network
1059 : hf_sccp_calling_pc_network,
1060 tvb, offset, ANSI_NCM_LENGTH, dpc);
1061 offset += ANSI_NCM_LENGTH;
1066 /* FUNCTION dissect_sccp_called_calling_param():
1067 * Dissect the Calling or Called Party Address parameters.
1069 * The boolean 'called' describes whether this function is decoding a
1070 * called (TRUE) or calling (FALSE) party address. There is simply too
1071 * much code in this function to have 2 copies of it (one for called, one
1074 * NOTE: this function is called even when (!tree) so that we can get
1075 * the SSN and subsequently call subdissectors (if and when there's a data
1076 * parameter). Realistically we should put if (!tree)'s around a lot of the
1077 * code, but I think that would make it unreadable--and the expense of not
1078 * doing so does not appear to be very high.
1081 dissect_sccp_called_calling_param(tvbuff_t *tvb, proto_tree *tree,
1082 guint length, gboolean called)
1084 proto_item *call_item = 0, *call_ai_item = 0, *item;
1085 proto_tree *call_tree = 0, *call_ai_tree = 0;
1087 guint8 national = -1, routing_ind, gti, pci, ssni, ssn;
1089 dissector_handle_t ssn_dissector = NULL, tcap_ssn_dissector = NULL;
1090 const char *ssn_dissector_short_name = NULL;
1091 const char *tcap_ssn_dissector_short_name = NULL;
1093 call_item = proto_tree_add_text(tree, tvb, 0, length,
1094 "%s Party address (%u byte%s)",
1095 called ? "Called" : "Calling", length,
1096 plurality(length, "", "s"));
1097 call_tree = proto_item_add_subtree(call_item, called ? ett_sccp_called
1098 : ett_sccp_calling);
1100 call_ai_item = proto_tree_add_text(call_tree, tvb, 0,
1101 ADDRESS_INDICATOR_LENGTH,
1102 "Address Indicator");
1103 call_ai_tree = proto_item_add_subtree(call_ai_item, called ? ett_sccp_called_ai
1104 : ett_sccp_calling_ai);
1106 if (decode_mtp3_standard == ANSI_STANDARD)
1108 national = tvb_get_guint8(tvb, 0) & ANSI_NATIONAL_MASK;
1109 proto_tree_add_uint(call_ai_tree, called ? hf_sccp_called_national_indicator
1110 : hf_sccp_calling_national_indicator,
1111 tvb, 0, ADDRESS_INDICATOR_LENGTH, national);
1114 routing_ind = tvb_get_guint8(tvb, 0) & ROUTING_INDICATOR_MASK;
1115 proto_tree_add_uint(call_ai_tree, called ? hf_sccp_called_routing_indicator
1116 : hf_sccp_calling_routing_indicator,
1117 tvb, 0, ADDRESS_INDICATOR_LENGTH, routing_ind);
1119 gti = tvb_get_guint8(tvb, 0) & GTI_MASK;
1121 if (decode_mtp3_standard == ITU_STANDARD ||
1122 decode_mtp3_standard == CHINESE_ITU_STANDARD ||
1123 decode_mtp3_standard == JAPAN_STANDARD ||
1126 proto_tree_add_uint(call_ai_tree, called ? hf_sccp_called_itu_global_title_indicator
1127 : hf_sccp_called_itu_global_title_indicator,
1128 tvb, 0, ADDRESS_INDICATOR_LENGTH, gti);
1130 ssni = tvb_get_guint8(tvb, 0) & ITU_SSN_INDICATOR_MASK;
1131 proto_tree_add_uint(call_ai_tree, called ? hf_sccp_called_itu_ssn_indicator
1132 : hf_sccp_calling_itu_ssn_indicator,
1133 tvb, 0, ADDRESS_INDICATOR_LENGTH, ssni);
1135 pci = tvb_get_guint8(tvb, 0) & ITU_PC_INDICATOR_MASK;
1136 proto_tree_add_uint(call_ai_tree, called ? hf_sccp_called_itu_point_code_indicator
1137 : hf_sccp_calling_itu_point_code_indicator,
1138 tvb, 0, ADDRESS_INDICATOR_LENGTH, pci);
1140 offset = ADDRESS_INDICATOR_LENGTH;
1142 /* Dissect PC (if present) */
1144 if (decode_mtp3_standard == ITU_STANDARD) {
1146 proto_tree_add_item(call_tree, called ? hf_sccp_called_itu_pc
1147 : hf_sccp_calling_itu_pc,
1148 tvb, offset, ITU_PC_LENGTH, TRUE);
1150 offset += ITU_PC_LENGTH;
1152 } else if (decode_mtp3_standard == JAPAN_STANDARD) {
1154 proto_tree_add_item(call_tree, called ? hf_sccp_called_japan_pc
1155 : hf_sccp_calling_japan_pc,
1156 tvb, offset, JAPAN_PC_LENGTH, TRUE);
1158 offset += JAPAN_PC_LENGTH;
1160 } else /* CHINESE_ITU_STANDARD */ {
1162 offset = dissect_sccp_3byte_pc(tvb, call_tree, offset, called);
1167 /* Dissect SSN (if present) */
1169 ssn = tvb_get_guint8(tvb, offset);
1171 if (assoc) assoc->called_ssn = ssn;
1174 if (assoc) assoc->calling_ssn = ssn;
1177 proto_tree_add_uint(call_tree, called ? hf_sccp_called_ssn
1178 : hf_sccp_calling_ssn,
1179 tvb, offset, ADDRESS_SSN_LENGTH, ssn);
1180 proto_tree_add_uint_hidden(call_tree, hf_sccp_ssn, tvb, offset,
1181 ADDRESS_SSN_LENGTH, ssn);
1182 offset += ADDRESS_SSN_LENGTH;
1184 /* Get the dissector handle of the dissector registered for this ssn
1185 * And print it's name.
1187 ssn_dissector = dissector_get_port_handle(sccp_ssn_dissector_table, ssn);
1188 if (ssn_dissector) {
1189 ssn_dissector_short_name = dissector_handle_get_short_name(ssn_dissector);
1190 if(ssn_dissector_short_name) {
1191 item = proto_tree_add_text(call_tree, tvb, offset - 1, ADDRESS_SSN_LENGTH,"Linked to %s",ssn_dissector_short_name);
1192 PROTO_ITEM_SET_GENERATED(item);
1193 if (strncasecmp("TCAP",ssn_dissector_short_name,4)== 0) {
1194 tcap_ssn_dissector = get_itu_tcap_subdissector(ssn);
1195 if(tcap_ssn_dissector){
1196 tcap_ssn_dissector_short_name = dissector_handle_get_short_name(tcap_ssn_dissector);
1197 proto_item_append_text(item,", TCAP ssn Linked to %s",tcap_ssn_dissector_short_name);
1201 } /* ssn_dissector */
1205 return; /* got SSN, that's all we need here... */
1207 /* Dissect GT (if present) */
1208 if (gti != AI_GTI_NO_GT) {
1209 if (length < offset)
1211 gt_tvb = tvb_new_subset(tvb, offset, (length - offset),
1213 dissect_sccp_global_title(gt_tvb, call_tree, (length - offset), gti,
1217 } else if (decode_mtp3_standard == ANSI_STANDARD) {
1219 proto_tree_add_uint(call_ai_tree, called ? hf_sccp_called_ansi_global_title_indicator
1220 : hf_sccp_calling_ansi_global_title_indicator,
1221 tvb, 0, ADDRESS_INDICATOR_LENGTH, gti);
1223 pci = tvb_get_guint8(tvb, 0) & ANSI_PC_INDICATOR_MASK;
1224 proto_tree_add_uint(call_ai_tree, called ? hf_sccp_called_ansi_point_code_indicator
1225 : hf_sccp_calling_ansi_point_code_indicator,
1226 tvb, 0, ADDRESS_INDICATOR_LENGTH, pci);
1228 ssni = tvb_get_guint8(tvb, 0) & ANSI_SSN_INDICATOR_MASK;
1229 proto_tree_add_uint(call_ai_tree, called ? hf_sccp_called_ansi_ssn_indicator
1230 : hf_sccp_calling_ansi_ssn_indicator,
1231 tvb, 0, ADDRESS_INDICATOR_LENGTH, ssni);
1233 offset = ADDRESS_INDICATOR_LENGTH;
1235 /* Dissect SSN (if present) */
1237 ssn = tvb_get_guint8(tvb, offset);
1239 if (assoc) assoc->called_ssn = ssn;
1242 if (assoc) assoc->calling_ssn = ssn;
1245 proto_tree_add_uint(call_tree, called ? hf_sccp_called_ssn
1246 : hf_sccp_calling_ssn,
1247 tvb, offset, ADDRESS_SSN_LENGTH, ssn);
1248 proto_tree_add_uint_hidden(call_tree, hf_sccp_ssn, tvb, offset,
1249 ADDRESS_SSN_LENGTH, ssn);
1250 offset += ADDRESS_SSN_LENGTH;
1254 return; /* got SSN, that's all we need here... */
1256 /* Dissect PC (if present) */
1258 offset = dissect_sccp_3byte_pc(tvb, call_tree, offset, called);
1261 /* Dissect GT (if present) */
1262 if (gti != AI_GTI_NO_GT) {
1263 if (length < offset)
1265 gt_tvb = tvb_new_subset(tvb, offset, (length - offset),
1267 dissect_sccp_global_title(gt_tvb, call_tree, (length - offset), gti,
1276 dissect_sccp_called_param(tvbuff_t *tvb, proto_tree *tree, guint length)
1278 dissect_sccp_called_calling_param(tvb, tree, length, TRUE);
1282 dissect_sccp_calling_param(tvbuff_t *tvb, proto_tree *tree, guint length)
1284 dissect_sccp_called_calling_param(tvb, tree, length, FALSE);
1288 dissect_sccp_class_param(tvbuff_t *tvb, proto_tree *tree, guint length)
1290 guint8 class, handling;
1292 class = tvb_get_guint8(tvb, 0) & CLASS_CLASS_MASK;
1293 handling = tvb_get_guint8(tvb, 0) & CLASS_SPARE_HANDLING_MASK;
1295 proto_tree_add_uint(tree, hf_sccp_class, tvb, 0, length, class);
1297 if (class == 0 || class == 1)
1298 proto_tree_add_uint(tree, hf_sccp_handling, tvb, 0, length, handling);
1302 dissect_sccp_segmenting_reassembling_param(tvbuff_t *tvb, proto_tree *tree, guint length)
1304 proto_tree_add_item(tree, hf_sccp_more, tvb, 0, length, FALSE);
1308 dissect_sccp_receive_sequence_number_param(tvbuff_t *tvb, proto_tree *tree, guint length)
1312 rsn = tvb_get_guint8(tvb, 0) >> 1;
1313 proto_tree_add_uint(tree, hf_sccp_rsn, tvb, 0, length, rsn);
1317 dissect_sccp_sequencing_segmenting_param(tvbuff_t *tvb, proto_tree *tree, guint length)
1319 guint8 rsn, ssn, more;
1320 proto_item *param_item;
1321 proto_tree *param_tree;
1323 ssn = tvb_get_guint8(tvb, 0) >> 1;
1324 rsn = tvb_get_guint8(tvb, SEQUENCING_SEGMENTING_SSN_LENGTH) >> 1;
1325 more = tvb_get_guint8(tvb, SEQUENCING_SEGMENTING_SSN_LENGTH) & SEQUENCING_SEGMENTING_MORE_MASK;
1327 param_item = proto_tree_add_text(tree, tvb, 0, length,
1328 val_to_str(PARAMETER_SEQUENCING_SEGMENTING,
1329 sccp_parameter_values, "Unknown"));
1330 param_tree = proto_item_add_subtree(param_item,
1331 ett_sccp_sequencing_segmenting);
1333 proto_tree_add_uint(param_tree, hf_sccp_sequencing_segmenting_ssn, tvb, 0,
1334 SEQUENCING_SEGMENTING_SSN_LENGTH, ssn);
1335 proto_tree_add_uint(param_tree, hf_sccp_sequencing_segmenting_rsn, tvb,
1336 SEQUENCING_SEGMENTING_SSN_LENGTH,
1337 SEQUENCING_SEGMENTING_RSN_LENGTH, rsn);
1338 proto_tree_add_uint(param_tree, hf_sccp_sequencing_segmenting_more, tvb,
1339 SEQUENCING_SEGMENTING_SSN_LENGTH,
1340 SEQUENCING_SEGMENTING_RSN_LENGTH, more);
1344 dissect_sccp_credit_param(tvbuff_t *tvb, proto_tree *tree, guint length)
1348 credit = tvb_get_guint8(tvb, 0);
1349 proto_tree_add_uint(tree, hf_sccp_credit, tvb, 0, length, credit);
1353 dissect_sccp_release_cause_param(tvbuff_t *tvb, proto_tree *tree, guint length)
1357 cause = tvb_get_guint8(tvb, 0);
1358 proto_tree_add_uint(tree, hf_sccp_release_cause, tvb, 0, length, cause);
1362 dissect_sccp_return_cause_param(tvbuff_t *tvb, proto_tree *tree, guint length)
1366 cause = tvb_get_guint8(tvb, 0);
1367 proto_tree_add_uint(tree, hf_sccp_return_cause, tvb, 0, length, cause);
1371 dissect_sccp_reset_cause_param(tvbuff_t *tvb, proto_tree *tree, guint length)
1375 cause = tvb_get_guint8(tvb, 0);
1376 proto_tree_add_uint(tree, hf_sccp_reset_cause, tvb, 0, length, cause);
1380 dissect_sccp_error_cause_param(tvbuff_t *tvb, proto_tree *tree, guint length)
1384 cause = tvb_get_guint8(tvb, 0);
1385 proto_tree_add_uint(tree, hf_sccp_error_cause, tvb, 0, length, cause);
1389 dissect_sccp_refusal_cause_param(tvbuff_t *tvb, proto_tree *tree, guint length)
1393 cause = tvb_get_guint8(tvb, 0);
1394 proto_tree_add_uint(tree, hf_sccp_refusal_cause, tvb, 0, length, cause);
1397 /* This function is used for both data and long data (ITU only) parameters */
1399 dissect_sccp_data_param(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
1404 switch (pinfo->p2p_dir) {
1406 ssn = assoc->calling_ssn;
1409 ssn = assoc->called_ssn;
1412 ssn = assoc->called_ssn;
1413 if (ssn == INVALID_SSN) ssn = assoc->calling_ssn;
1417 ssn = assoc->called_ssn;
1421 if (ssn != INVALID_SSN && dissector_try_port(sccp_ssn_dissector_table, ssn, tvb, pinfo, tree) ) {
1425 /* try heuristic subdissector list to see if there are any takers */
1426 if (dissector_try_heuristic(heur_subdissector_list, tvb, pinfo, tree)) {
1430 /* No sub-dissection occured, treat it as raw data */
1431 call_dissector(data_handle, tvb, pinfo, tree);
1435 dissect_sccp_segmentation_param(tvbuff_t *tvb, proto_tree *tree, guint length)
1437 guint8 first, class, remaining;
1439 proto_item *param_item;
1440 proto_tree *param_tree;
1442 first = tvb_get_guint8(tvb, 0) & SEGMENTATION_FIRST_SEGMENT_MASK;
1443 class = tvb_get_guint8(tvb, 0) & SEGMENTATION_CLASS_MASK;
1444 remaining = tvb_get_guint8(tvb, 0) & SEGMENTATION_REMAINING_MASK;
1446 slr = tvb_get_letoh24(tvb, 1);
1448 param_item = proto_tree_add_text(tree, tvb, 0, length,
1449 val_to_str(PARAMETER_SEGMENTATION,
1450 sccp_parameter_values, "Unknown"));
1451 param_tree = proto_item_add_subtree(param_item, ett_sccp_segmentation);
1453 proto_tree_add_uint(param_tree, hf_sccp_segmentation_first, tvb, 0, length,
1455 proto_tree_add_uint(param_tree, hf_sccp_segmentation_class, tvb, 0, length,
1457 proto_tree_add_uint(param_tree, hf_sccp_segmentation_remaining, tvb, 0,
1459 proto_tree_add_uint(param_tree, hf_sccp_segmentation_slr, tvb, 1, length,
1464 dissect_sccp_hop_counter_param(tvbuff_t *tvb, proto_tree *tree, guint length)
1468 hops = tvb_get_guint8(tvb, 0);
1469 proto_tree_add_uint(tree, hf_sccp_hop_counter, tvb, 0, length, hops);
1473 dissect_sccp_importance_param(tvbuff_t *tvb, proto_tree *tree, guint length)
1477 importance = tvb_get_guint8(tvb, 0) & IMPORTANCE_IMPORTANCE_MASK;
1478 proto_tree_add_uint(tree, hf_sccp_importance, tvb, 0, length, importance);
1482 dissect_sccp_isni_param(tvbuff_t *tvb, proto_tree *tree, guint length)
1484 guint8 mi, iri, ti, network, netspec;
1486 proto_item *param_item;
1487 proto_tree *param_tree;
1489 /* Create a subtree for ISNI Routing Control */
1490 param_item = proto_tree_add_text(tree, tvb, offset, ANSI_ISNI_ROUTING_CONTROL_LENGTH,
1491 "ISNI Routing Control");
1492 param_tree = proto_item_add_subtree(param_item,
1493 ett_sccp_ansi_isni_routing_control);
1495 mi = tvb_get_guint8(tvb, offset) & ANSI_ISNI_MI_MASK;
1496 proto_tree_add_uint(param_tree, hf_sccp_ansi_isni_mi, tvb, offset,
1497 ANSI_ISNI_ROUTING_CONTROL_LENGTH, mi);
1499 iri = tvb_get_guint8(tvb, offset) & ANSI_ISNI_IRI_MASK;
1500 proto_tree_add_uint(param_tree, hf_sccp_ansi_isni_iri, tvb, offset,
1501 ANSI_ISNI_ROUTING_CONTROL_LENGTH, iri);
1503 ti = tvb_get_guint8(tvb, offset) & ANSI_ISNI_TI_MASK;
1504 proto_tree_add_uint(param_tree, hf_sccp_ansi_isni_ti, tvb, offset,
1505 ANSI_ISNI_ROUTING_CONTROL_LENGTH, ti);
1507 offset += ANSI_ISNI_ROUTING_CONTROL_LENGTH;
1509 if ((ti >> ANSI_ISNI_TI_SHIFT) == ANSI_ISNI_TYPE_1) {
1510 netspec = tvb_get_guint8(tvb, offset) & ANSI_ISNI_NETSPEC_MASK;
1511 proto_tree_add_uint(param_tree, hf_sccp_ansi_isni_netspec, tvb, offset,
1512 ANSI_ISNI_ROUTING_CONTROL_LENGTH, ti);
1513 offset += ANSI_ISNI_ROUTING_CONTROL_LENGTH;
1516 while (offset < length) {
1518 network = tvb_get_guint8(tvb, offset);
1519 proto_tree_add_text(tree, tvb, offset, ANSI_NCM_LENGTH,
1520 "Network ID network: %d", network);
1523 network = tvb_get_guint8(tvb, offset);
1524 proto_tree_add_text(tree, tvb, offset, ANSI_NCM_LENGTH,
1525 "Network ID cluster: %d", network);
1531 /* FUNCTION dissect_sccp_parameter():
1532 * Dissect a parameter given its type, offset into tvb, and length.
1535 dissect_sccp_parameter(tvbuff_t *tvb, packet_info *pinfo, proto_tree *sccp_tree,
1536 proto_tree *tree, guint8 parameter_type, guint16 offset,
1537 guint16 parameter_length)
1539 tvbuff_t *parameter_tvb;
1541 switch (parameter_type) {
1542 case PARAMETER_CALLED_PARTY_ADDRESS:
1543 case PARAMETER_CALLING_PARTY_ADDRESS:
1544 case PARAMETER_DATA:
1545 case PARAMETER_LONG_DATA:
1546 case PARAMETER_SOURCE_LOCAL_REFERENCE:
1547 case PARAMETER_DESTINATION_LOCAL_REFERENCE:
1549 /* These parameters must be dissected even if !sccp_tree (so that
1550 * assoc information can be created).
1556 return(parameter_length);
1560 parameter_tvb = tvb_new_subset(tvb, offset, parameter_length, parameter_length);
1562 switch (parameter_type) {
1564 case PARAMETER_END_OF_OPTIONAL_PARAMETERS:
1565 proto_tree_add_text(sccp_tree, tvb, offset, parameter_length,
1569 case PARAMETER_DESTINATION_LOCAL_REFERENCE:
1570 dissect_sccp_dlr_param(parameter_tvb, sccp_tree, parameter_length);
1573 case PARAMETER_SOURCE_LOCAL_REFERENCE:
1574 dissect_sccp_slr_param(parameter_tvb, sccp_tree, parameter_length);
1577 case PARAMETER_CALLED_PARTY_ADDRESS:
1578 dissect_sccp_called_param(parameter_tvb, sccp_tree, parameter_length);
1581 case PARAMETER_CALLING_PARTY_ADDRESS:
1582 dissect_sccp_calling_param(parameter_tvb, sccp_tree, parameter_length);
1585 case PARAMETER_CLASS:
1586 dissect_sccp_class_param(parameter_tvb, sccp_tree, parameter_length);
1589 case PARAMETER_SEGMENTING_REASSEMBLING:
1590 dissect_sccp_segmenting_reassembling_param(parameter_tvb, sccp_tree,
1594 case PARAMETER_RECEIVE_SEQUENCE_NUMBER:
1595 dissect_sccp_receive_sequence_number_param(parameter_tvb, sccp_tree,
1599 case PARAMETER_SEQUENCING_SEGMENTING:
1600 dissect_sccp_sequencing_segmenting_param(parameter_tvb, sccp_tree,
1604 case PARAMETER_CREDIT:
1605 dissect_sccp_credit_param(parameter_tvb, sccp_tree, parameter_length);
1608 case PARAMETER_RELEASE_CAUSE:
1609 dissect_sccp_release_cause_param(parameter_tvb, sccp_tree, parameter_length);
1612 case PARAMETER_RETURN_CAUSE:
1613 dissect_sccp_return_cause_param(parameter_tvb, sccp_tree, parameter_length);
1616 case PARAMETER_RESET_CAUSE:
1617 dissect_sccp_reset_cause_param(parameter_tvb, sccp_tree, parameter_length);
1620 case PARAMETER_ERROR_CAUSE:
1621 dissect_sccp_error_cause_param(parameter_tvb, sccp_tree, parameter_length);
1624 case PARAMETER_REFUSAL_CAUSE:
1625 dissect_sccp_refusal_cause_param(parameter_tvb, sccp_tree, parameter_length);
1628 case PARAMETER_DATA:
1629 dissect_sccp_data_param(parameter_tvb, pinfo, tree);
1631 /* TODO? Re-adjust length of SCCP item since it may be sub-dissected */
1632 /* sccp_length = proto_item_get_len(sccp_item);
1633 * sccp_length -= parameter_length;
1634 * proto_item_set_len(sccp_item, sccp_length);
1638 case PARAMETER_SEGMENTATION:
1639 dissect_sccp_segmentation_param(parameter_tvb, sccp_tree, parameter_length);
1642 case PARAMETER_HOP_COUNTER:
1643 dissect_sccp_hop_counter_param(parameter_tvb, sccp_tree, parameter_length);
1646 case PARAMETER_IMPORTANCE:
1647 if (decode_mtp3_standard != ANSI_STANDARD)
1648 dissect_sccp_importance_param(parameter_tvb, sccp_tree, parameter_length);
1650 dissect_sccp_unknown_param(parameter_tvb, sccp_tree, parameter_type,
1654 case PARAMETER_LONG_DATA:
1655 if (decode_mtp3_standard != ANSI_STANDARD)
1656 dissect_sccp_data_param(parameter_tvb, pinfo, tree);
1658 dissect_sccp_unknown_param(parameter_tvb, sccp_tree, parameter_type,
1662 case PARAMETER_ISNI:
1663 if (decode_mtp3_standard != ANSI_STANDARD)
1664 dissect_sccp_unknown_param(parameter_tvb, sccp_tree, parameter_type,
1667 dissect_sccp_isni_param(parameter_tvb, sccp_tree, parameter_length);
1671 dissect_sccp_unknown_param(parameter_tvb, sccp_tree, parameter_type,
1676 return(parameter_length);
1679 /* FUNCTION dissect_sccp_variable_parameter():
1680 * Dissect a variable parameter given its type and offset into tvb. Length
1681 * of the parameter is gotten from tvb[0].
1682 * Length returned is sum of (length + parameter).
1685 dissect_sccp_variable_parameter(tvbuff_t *tvb, packet_info *pinfo,
1686 proto_tree *sccp_tree, proto_tree *tree,
1687 guint8 parameter_type, guint16 offset)
1689 guint16 parameter_length;
1690 guint8 length_length;
1692 if (parameter_type != PARAMETER_LONG_DATA)
1694 parameter_length = tvb_get_guint8(tvb, offset);
1695 length_length = PARAMETER_LENGTH_LENGTH;
1699 /* Long data parameter has 16 bit length */
1700 parameter_length = tvb_get_letohs(tvb, offset);
1701 length_length = PARAMETER_LONG_DATA_LENGTH_LENGTH;
1707 proto_tree_add_text(sccp_tree, tvb, offset, length_length,
1709 val_to_str(parameter_type, sccp_parameter_values,
1714 offset += length_length;
1716 dissect_sccp_parameter(tvb, pinfo, sccp_tree, tree, parameter_type, offset,
1719 return(parameter_length + length_length);
1722 /* FUNCTION dissect_sccp_optional_parameters():
1723 * Dissect all the optional parameters given the start of the optional
1724 * parameters into tvb. Parameter types and lengths are read from tvb.
1727 dissect_sccp_optional_parameters(tvbuff_t *tvb, packet_info *pinfo,
1728 proto_tree *sccp_tree, proto_tree *tree,
1731 guint8 parameter_type;
1733 while ((parameter_type = tvb_get_guint8(tvb, offset)) !=
1734 PARAMETER_END_OF_OPTIONAL_PARAMETERS) {
1736 offset += PARAMETER_TYPE_LENGTH;
1737 offset += dissect_sccp_variable_parameter(tvb, pinfo, sccp_tree, tree,
1738 parameter_type, offset);
1741 /* Process end of optional parameters */
1742 dissect_sccp_parameter(tvb, pinfo, sccp_tree, tree, parameter_type, offset,
1743 END_OF_OPTIONAL_PARAMETERS_LENGTH);
1749 dissect_sccp_message(tvbuff_t *tvb, packet_info *pinfo, proto_tree *sccp_tree,
1752 guint16 variable_pointer1 = 0, variable_pointer2 = 0, variable_pointer3 = 0;
1753 guint16 optional_pointer = 0, orig_opt_ptr = 0;
1755 guint8 parameter_type;
1756 gboolean save_fragmented;
1757 tvbuff_t *new_tvb = NULL;
1758 fragment_data *frag_msg = NULL;
1759 guint32 source_local_ref=0;
1762 /* Macro for getting pointer to mandatory variable parameters */
1763 #define VARIABLE_POINTER(var, hf_var, ptr_size) \
1764 if (ptr_size == POINTER_LENGTH) \
1765 var = tvb_get_guint8(tvb, offset); \
1767 var = tvb_get_letohs(tvb, offset); \
1768 proto_tree_add_uint(sccp_tree, hf_var, tvb, \
1769 offset, ptr_size, var); \
1771 if (ptr_size == POINTER_LENGTH_LONG) \
1775 /* Macro for getting pointer to optional parameters */
1776 #define OPTIONAL_POINTER(ptr_size) \
1777 if (ptr_size == POINTER_LENGTH) \
1778 orig_opt_ptr = optional_pointer = tvb_get_guint8(tvb, offset); \
1780 orig_opt_ptr = optional_pointer = tvb_get_letohs(tvb, offset); \
1781 proto_tree_add_uint(sccp_tree, hf_sccp_optional_pointer, tvb, \
1782 offset, ptr_size, optional_pointer); \
1783 optional_pointer += offset; \
1784 if (ptr_size == POINTER_LENGTH_LONG) \
1785 optional_pointer += 1; \
1789 /* Extract the message type; all other processing is based on this */
1790 message_type = tvb_get_guint8(tvb, MESSAGE_TYPE_OFFSET);
1791 offset = MESSAGE_TYPE_LENGTH;
1793 if (check_col(pinfo->cinfo, COL_INFO))
1794 col_add_fstr(pinfo->cinfo, COL_INFO, "%s ",
1795 val_to_str(message_type, sccp_message_type_acro_values, "Unknown"));
1798 /* add the message type to the protocol tree */
1799 proto_tree_add_uint(sccp_tree, hf_sccp_message_type, tvb,
1800 MESSAGE_TYPE_OFFSET, MESSAGE_TYPE_LENGTH, message_type);
1804 /* Starting a new message dissection; clear the global SSN and DLR values */
1809 switch(message_type) {
1810 case MESSAGE_TYPE_CR:
1811 /* TTC and NTT (Japan) say that the connection-oriented messages are
1812 * deleted (not standardized), but they appear to be used anyway, so
1813 * we'll dissect it...
1815 offset += dissect_sccp_parameter(tvb, pinfo, sccp_tree, tree,
1816 PARAMETER_SOURCE_LOCAL_REFERENCE,
1817 offset, SOURCE_LOCAL_REFERENCE_LENGTH);
1818 offset += dissect_sccp_parameter(tvb, pinfo, sccp_tree, tree,
1819 PARAMETER_CLASS, offset,
1820 PROTOCOL_CLASS_LENGTH);
1821 assoc = sccp_assoc(&(pinfo->src), &(pinfo->dst), slr, dlr);
1823 VARIABLE_POINTER(variable_pointer1, hf_sccp_variable_pointer1, POINTER_LENGTH)
1824 OPTIONAL_POINTER(POINTER_LENGTH)
1826 dissect_sccp_variable_parameter(tvb, pinfo, sccp_tree, tree,
1827 PARAMETER_CALLED_PARTY_ADDRESS,
1831 case MESSAGE_TYPE_CC:
1832 /* TODO: connection has been established; theoretically we could keep
1833 * keep track of the SLR/DLR with the called/calling from the CR and
1834 * track the connection (e.g., on subsequent messages regarding this
1835 * SLR we could set the global vars "call*_ssn" so data could get
1838 offset += dissect_sccp_parameter(tvb, pinfo, sccp_tree, tree,
1839 PARAMETER_DESTINATION_LOCAL_REFERENCE,
1841 DESTINATION_LOCAL_REFERENCE_LENGTH);
1842 offset += dissect_sccp_parameter(tvb, pinfo, sccp_tree, tree,
1843 PARAMETER_SOURCE_LOCAL_REFERENCE,
1844 offset, SOURCE_LOCAL_REFERENCE_LENGTH);
1846 assoc = sccp_assoc(&(pinfo->src), &(pinfo->dst), slr, dlr);
1848 offset += dissect_sccp_parameter(tvb, pinfo, sccp_tree, tree,
1849 PARAMETER_CLASS, offset,
1850 PROTOCOL_CLASS_LENGTH);
1851 OPTIONAL_POINTER(POINTER_LENGTH);
1854 case MESSAGE_TYPE_CREF:
1855 offset += dissect_sccp_parameter(tvb, pinfo, sccp_tree, tree,
1856 PARAMETER_DESTINATION_LOCAL_REFERENCE,
1858 DESTINATION_LOCAL_REFERENCE_LENGTH);
1860 assoc = sccp_assoc(&(pinfo->src), &(pinfo->dst), slr, dlr);
1862 offset += dissect_sccp_parameter(tvb, pinfo, sccp_tree, tree,
1863 PARAMETER_REFUSAL_CAUSE, offset,
1864 REFUSAL_CAUSE_LENGTH);
1865 OPTIONAL_POINTER(POINTER_LENGTH);
1868 case MESSAGE_TYPE_RLSD:
1869 offset += dissect_sccp_parameter(tvb, pinfo, sccp_tree, tree,
1870 PARAMETER_DESTINATION_LOCAL_REFERENCE,
1872 DESTINATION_LOCAL_REFERENCE_LENGTH);
1873 offset += dissect_sccp_parameter(tvb, pinfo, sccp_tree, tree,
1874 PARAMETER_SOURCE_LOCAL_REFERENCE,
1875 offset, SOURCE_LOCAL_REFERENCE_LENGTH);
1877 assoc = sccp_assoc(&(pinfo->src), &(pinfo->dst), slr, dlr);
1879 offset += dissect_sccp_parameter(tvb, pinfo, sccp_tree, tree,
1880 PARAMETER_RELEASE_CAUSE, offset,
1881 RELEASE_CAUSE_LENGTH);
1883 OPTIONAL_POINTER(POINTER_LENGTH);
1884 assoc = sccp_assoc(&(pinfo->src), &(pinfo->dst), slr, dlr);
1887 case MESSAGE_TYPE_RLC:
1888 offset += dissect_sccp_parameter(tvb, pinfo, sccp_tree, tree,
1889 PARAMETER_DESTINATION_LOCAL_REFERENCE,
1891 DESTINATION_LOCAL_REFERENCE_LENGTH);
1892 offset += dissect_sccp_parameter(tvb, pinfo, sccp_tree, tree,
1893 PARAMETER_SOURCE_LOCAL_REFERENCE,
1894 offset, SOURCE_LOCAL_REFERENCE_LENGTH);
1896 assoc = sccp_assoc(&(pinfo->src), &(pinfo->dst), slr, dlr);
1900 case MESSAGE_TYPE_DT1:
1901 source_local_ref = tvb_get_letoh24(tvb, offset);
1902 offset += dissect_sccp_parameter(tvb, pinfo, sccp_tree, tree,
1903 PARAMETER_DESTINATION_LOCAL_REFERENCE,
1905 DESTINATION_LOCAL_REFERENCE_LENGTH);
1907 assoc = sccp_assoc(&(pinfo->src), &(pinfo->dst), slr, dlr);
1909 more = tvb_get_guint8(tvb, offset) & SEGMENTING_REASSEMBLING_MASK;
1911 offset += dissect_sccp_parameter(tvb, pinfo, sccp_tree, tree,
1912 PARAMETER_SEGMENTING_REASSEMBLING,
1913 offset, SEGMENTING_REASSEMBLING_LENGTH);
1914 VARIABLE_POINTER(variable_pointer1, hf_sccp_variable_pointer1, POINTER_LENGTH)
1917 if (!sccp_xudt_desegment){
1918 proto_tree_add_text(sccp_tree, tvb, variable_pointer1, tvb_get_guint8(tvb, variable_pointer1)+1, "Segmented Data" );
1919 dissect_sccp_variable_parameter(tvb, pinfo, sccp_tree, tree, PARAMETER_DATA,
1923 save_fragmented = pinfo->fragmented;
1924 pinfo->fragmented = TRUE;
1925 frag_msg = fragment_add_seq_next(tvb, variable_pointer1 + 1, pinfo,
1926 source_local_ref, /* ID for fragments belonging together */
1927 sccp_xudt_msg_fragment_table, /* list of message fragments */
1928 sccp_xudt_msg_reassembled_table, /* list of reassembled messages */
1929 tvb_get_guint8(tvb,variable_pointer1), /* fragment length - to the end */
1930 more); /* More fragments? */
1933 new_tvb = process_reassembled_data(tvb, variable_pointer1 + 1, pinfo,
1934 "Reassembled Message", frag_msg, &sccp_xudt_msg_frag_items,
1937 if (frag_msg) { /* Reassembled */
1938 if (check_col(pinfo->cinfo, COL_INFO))
1939 col_append_str(pinfo->cinfo, COL_INFO,
1940 " (Message Reassembled)");
1941 } else { /* Not last packet of reassembled Short Message */
1942 if (check_col(pinfo->cinfo, COL_INFO))
1943 col_append_fstr(pinfo->cinfo, COL_INFO,
1944 " (Message fragment )");
1946 pinfo->fragmented = save_fragmented;
1948 dissect_sccp_data_param(new_tvb, pinfo, tree);
1951 /* End reassemble */
1954 case MESSAGE_TYPE_DT2:
1955 offset += dissect_sccp_parameter(tvb, pinfo, sccp_tree, tree,
1956 PARAMETER_DESTINATION_LOCAL_REFERENCE,
1958 DESTINATION_LOCAL_REFERENCE_LENGTH);
1960 assoc = sccp_assoc(&(pinfo->src), &(pinfo->dst), slr, dlr);
1962 offset += dissect_sccp_parameter(tvb, pinfo, sccp_tree, tree,
1963 PARAMETER_SEQUENCING_SEGMENTING, offset,
1964 SEQUENCING_SEGMENTING_LENGTH);
1967 case MESSAGE_TYPE_AK:
1968 offset += dissect_sccp_parameter(tvb, pinfo, sccp_tree, tree,
1969 PARAMETER_DESTINATION_LOCAL_REFERENCE,
1971 DESTINATION_LOCAL_REFERENCE_LENGTH);
1972 assoc = sccp_assoc(&(pinfo->src), &(pinfo->dst), slr, dlr);
1974 offset += dissect_sccp_parameter(tvb, pinfo, sccp_tree, tree,
1975 PARAMETER_RECEIVE_SEQUENCE_NUMBER,
1976 offset, RECEIVE_SEQUENCE_NUMBER_LENGTH);
1977 offset += dissect_sccp_parameter(tvb, pinfo, sccp_tree, tree,
1978 PARAMETER_CREDIT, offset, CREDIT_LENGTH);
1979 assoc = sccp_assoc(&(pinfo->src), &(pinfo->dst), slr, dlr);
1982 case MESSAGE_TYPE_UDT:
1983 offset += dissect_sccp_parameter(tvb, pinfo, sccp_tree, tree,
1984 PARAMETER_CLASS, offset,
1985 PROTOCOL_CLASS_LENGTH);
1986 VARIABLE_POINTER(variable_pointer1, hf_sccp_variable_pointer1, POINTER_LENGTH)
1987 VARIABLE_POINTER(variable_pointer2, hf_sccp_variable_pointer2, POINTER_LENGTH)
1988 VARIABLE_POINTER(variable_pointer3, hf_sccp_variable_pointer3, POINTER_LENGTH)
1990 assoc = sccp_assoc(&(pinfo->src), &(pinfo->dst), slr, dlr);
1992 dissect_sccp_variable_parameter(tvb, pinfo, sccp_tree, tree,
1993 PARAMETER_CALLED_PARTY_ADDRESS,
1995 dissect_sccp_variable_parameter(tvb, pinfo, sccp_tree, tree,
1996 PARAMETER_CALLING_PARTY_ADDRESS,
1999 dissect_sccp_variable_parameter(tvb, pinfo, sccp_tree, tree, PARAMETER_DATA,
2003 case MESSAGE_TYPE_UDTS:
2004 offset += dissect_sccp_parameter(tvb, pinfo, sccp_tree, tree,
2005 PARAMETER_RETURN_CAUSE, offset,
2006 RETURN_CAUSE_LENGTH);
2008 VARIABLE_POINTER(variable_pointer1, hf_sccp_variable_pointer1, POINTER_LENGTH)
2009 VARIABLE_POINTER(variable_pointer2, hf_sccp_variable_pointer2, POINTER_LENGTH)
2010 VARIABLE_POINTER(variable_pointer3, hf_sccp_variable_pointer3, POINTER_LENGTH)
2012 assoc = sccp_assoc(&(pinfo->src), &(pinfo->dst), slr, dlr);
2014 dissect_sccp_variable_parameter(tvb, pinfo, sccp_tree, tree,
2015 PARAMETER_CALLED_PARTY_ADDRESS,
2018 dissect_sccp_variable_parameter(tvb, pinfo, sccp_tree, tree,
2019 PARAMETER_CALLING_PARTY_ADDRESS,
2022 dissect_sccp_variable_parameter(tvb, pinfo, sccp_tree, tree, PARAMETER_DATA,
2026 case MESSAGE_TYPE_ED:
2027 offset += dissect_sccp_parameter(tvb, pinfo, sccp_tree, tree,
2028 PARAMETER_DESTINATION_LOCAL_REFERENCE,
2030 DESTINATION_LOCAL_REFERENCE_LENGTH);
2032 assoc = sccp_assoc(&(pinfo->src), &(pinfo->dst), slr, dlr);
2034 VARIABLE_POINTER(variable_pointer1, hf_sccp_variable_pointer1, POINTER_LENGTH);
2036 dissect_sccp_variable_parameter(tvb, pinfo, sccp_tree, tree, PARAMETER_DATA,
2040 case MESSAGE_TYPE_EA:
2041 offset += dissect_sccp_parameter(tvb, pinfo, sccp_tree, tree,
2042 PARAMETER_DESTINATION_LOCAL_REFERENCE,
2044 DESTINATION_LOCAL_REFERENCE_LENGTH);
2045 assoc = sccp_assoc(&(pinfo->src), &(pinfo->dst), slr, dlr);
2049 case MESSAGE_TYPE_RSR:
2050 offset += dissect_sccp_parameter(tvb, pinfo, sccp_tree, tree,
2051 PARAMETER_DESTINATION_LOCAL_REFERENCE,
2053 DESTINATION_LOCAL_REFERENCE_LENGTH);
2054 offset += dissect_sccp_parameter(tvb, pinfo, sccp_tree, tree,
2055 PARAMETER_SOURCE_LOCAL_REFERENCE,
2056 offset, SOURCE_LOCAL_REFERENCE_LENGTH);
2057 offset += dissect_sccp_parameter(tvb, pinfo, sccp_tree, tree,
2058 PARAMETER_RESET_CAUSE, offset,
2059 RESET_CAUSE_LENGTH);
2060 assoc = sccp_assoc(&(pinfo->src), &(pinfo->dst), slr, dlr);
2063 case MESSAGE_TYPE_RSC:
2064 offset += dissect_sccp_parameter(tvb, pinfo, sccp_tree, tree,
2065 PARAMETER_DESTINATION_LOCAL_REFERENCE,
2067 DESTINATION_LOCAL_REFERENCE_LENGTH);
2068 offset += dissect_sccp_parameter(tvb, pinfo, sccp_tree, tree,
2069 PARAMETER_SOURCE_LOCAL_REFERENCE,
2070 offset, SOURCE_LOCAL_REFERENCE_LENGTH);
2071 assoc = sccp_assoc(&(pinfo->src), &(pinfo->dst), slr, dlr);
2074 case MESSAGE_TYPE_ERR:
2075 offset += dissect_sccp_parameter(tvb, pinfo, sccp_tree, tree,
2076 PARAMETER_DESTINATION_LOCAL_REFERENCE,
2078 DESTINATION_LOCAL_REFERENCE_LENGTH);
2079 offset += dissect_sccp_parameter(tvb, pinfo, sccp_tree, tree,
2080 PARAMETER_ERROR_CAUSE, offset,
2081 ERROR_CAUSE_LENGTH);
2082 assoc = sccp_assoc(&(pinfo->src), &(pinfo->dst), slr, dlr);
2085 case MESSAGE_TYPE_IT:
2086 offset += dissect_sccp_parameter(tvb, pinfo, sccp_tree, tree,
2087 PARAMETER_DESTINATION_LOCAL_REFERENCE,
2089 DESTINATION_LOCAL_REFERENCE_LENGTH);
2090 offset += dissect_sccp_parameter(tvb, pinfo, sccp_tree, tree,
2091 PARAMETER_SOURCE_LOCAL_REFERENCE,
2092 offset, SOURCE_LOCAL_REFERENCE_LENGTH);
2093 assoc = sccp_assoc(&(pinfo->src), &(pinfo->dst), slr, dlr);
2094 offset += dissect_sccp_parameter(tvb, pinfo, sccp_tree, tree,
2095 PARAMETER_CLASS, offset,
2096 PROTOCOL_CLASS_LENGTH);
2097 offset += dissect_sccp_parameter(tvb, pinfo, sccp_tree, tree,
2098 PARAMETER_SEQUENCING_SEGMENTING,
2099 offset, SEQUENCING_SEGMENTING_LENGTH);
2100 offset += dissect_sccp_parameter(tvb, pinfo, sccp_tree, tree,
2101 PARAMETER_CREDIT, offset, CREDIT_LENGTH);
2104 case MESSAGE_TYPE_XUDT:
2105 offset += dissect_sccp_parameter(tvb, pinfo, sccp_tree, tree,
2106 PARAMETER_CLASS, offset,
2107 PROTOCOL_CLASS_LENGTH);
2108 offset += dissect_sccp_parameter(tvb, pinfo, sccp_tree, tree,
2109 PARAMETER_HOP_COUNTER, offset,
2110 HOP_COUNTER_LENGTH);
2112 VARIABLE_POINTER(variable_pointer1, hf_sccp_variable_pointer1, POINTER_LENGTH)
2113 VARIABLE_POINTER(variable_pointer2, hf_sccp_variable_pointer2, POINTER_LENGTH)
2114 VARIABLE_POINTER(variable_pointer3, hf_sccp_variable_pointer3, POINTER_LENGTH)
2115 OPTIONAL_POINTER(POINTER_LENGTH)
2117 /* Optional parameters are Segmentation and Importance
2118 * NOTE 2 - Segmentation Should not be present in case of a single XUDT message.
2121 assoc = sccp_assoc(&(pinfo->src), &(pinfo->dst), slr, dlr);
2123 dissect_sccp_variable_parameter(tvb, pinfo, sccp_tree, tree,
2124 PARAMETER_CALLED_PARTY_ADDRESS,
2126 dissect_sccp_variable_parameter(tvb, pinfo, sccp_tree, tree,
2127 PARAMETER_CALLING_PARTY_ADDRESS,
2130 if ((parameter_type = tvb_get_guint8(tvb, optional_pointer)) ==
2131 PARAMETER_SEGMENTATION){
2132 if (!sccp_xudt_desegment){
2133 proto_tree_add_text(sccp_tree, tvb, variable_pointer3, tvb_get_guint8(tvb, variable_pointer3)+1, "Segmented Data" );
2137 gboolean more_frag = TRUE;
2140 /* Get the first octet of parameter Segmentation, Ch 3.17 in Q.713
2141 * Bit 8 of octet 1 is used for First segment indication
2142 * Bit 7 of octet 1 is used to keep in the message in sequence delivery option required by the SCCP user
2143 * Bits 6 and 5 in octet 1 are spare bits.
2144 * Bits 4-1 of octet 1 are used to indicate the number of remaining segments.
2145 * The values 0000 to 1111 are possible; the value 0000 indicates the last segment.
2147 octet = tvb_get_guint8(tvb,optional_pointer+2);
2148 source_local_ref = tvb_get_letoh24(tvb, optional_pointer+3);
2149 if ((octet&0x0f) == 0)
2151 save_fragmented = pinfo->fragmented;
2152 pinfo->fragmented = TRUE;
2153 frag_msg = fragment_add_seq_next(tvb, variable_pointer3 + 1, pinfo,
2154 source_local_ref, /* ID for fragments belonging together */
2155 sccp_xudt_msg_fragment_table, /* list of message fragments */
2156 sccp_xudt_msg_reassembled_table, /* list of reassembled messages */
2157 tvb_get_guint8(tvb,variable_pointer3), /* fragment length - to the end */
2158 more_frag); /* More fragments? */
2160 if ((octet&0x80) == 0x80)/*First segment, set number of segments*/
2161 fragment_set_tot_len(pinfo, source_local_ref, sccp_xudt_msg_fragment_table,(octet & 0xf));
2163 new_tvb = process_reassembled_data(tvb, variable_pointer3 + 1, pinfo,
2164 "Reassembled Message", frag_msg, &sccp_xudt_msg_frag_items,
2167 if (frag_msg) { /* Reassembled */
2168 if (check_col(pinfo->cinfo, COL_INFO))
2169 col_append_str(pinfo->cinfo, COL_INFO,
2170 " (Message Reassembled)");
2171 } else { /* Not last packet of reassembled Short Message */
2172 if (check_col(pinfo->cinfo, COL_INFO))
2173 col_append_fstr(pinfo->cinfo, COL_INFO,
2174 " (Message fragment )");
2176 pinfo->fragmented = save_fragmented;
2178 dissect_sccp_data_param(new_tvb, pinfo, tree);
2181 dissect_sccp_variable_parameter(tvb, pinfo, sccp_tree, tree, PARAMETER_DATA,
2186 case MESSAGE_TYPE_XUDTS:
2187 offset += dissect_sccp_parameter(tvb, pinfo, sccp_tree, tree,
2188 PARAMETER_RETURN_CAUSE, offset,
2189 RETURN_CAUSE_LENGTH);
2190 offset += dissect_sccp_parameter(tvb, pinfo, sccp_tree, tree,
2191 PARAMETER_HOP_COUNTER, offset,
2192 HOP_COUNTER_LENGTH);
2194 VARIABLE_POINTER(variable_pointer1, hf_sccp_variable_pointer1, POINTER_LENGTH)
2195 VARIABLE_POINTER(variable_pointer2, hf_sccp_variable_pointer2, POINTER_LENGTH)
2196 VARIABLE_POINTER(variable_pointer3, hf_sccp_variable_pointer3, POINTER_LENGTH)
2197 OPTIONAL_POINTER(POINTER_LENGTH)
2199 assoc = sccp_assoc(&(pinfo->src), &(pinfo->dst), slr, dlr);
2201 dissect_sccp_variable_parameter(tvb, pinfo, sccp_tree, tree,
2202 PARAMETER_CALLED_PARTY_ADDRESS,
2204 dissect_sccp_variable_parameter(tvb, pinfo, sccp_tree, tree,
2205 PARAMETER_CALLING_PARTY_ADDRESS,
2207 dissect_sccp_variable_parameter(tvb, pinfo, sccp_tree, tree, PARAMETER_DATA,
2211 case MESSAGE_TYPE_LUDT:
2212 if (decode_mtp3_standard != ANSI_STANDARD)
2214 offset += dissect_sccp_parameter(tvb, pinfo, sccp_tree, tree,
2215 PARAMETER_CLASS, offset,
2216 PROTOCOL_CLASS_LENGTH);
2217 offset += dissect_sccp_parameter(tvb, pinfo, sccp_tree, tree,
2218 PARAMETER_HOP_COUNTER, offset,
2219 HOP_COUNTER_LENGTH);
2221 VARIABLE_POINTER(variable_pointer1, hf_sccp_variable_pointer1, POINTER_LENGTH_LONG)
2222 VARIABLE_POINTER(variable_pointer2, hf_sccp_variable_pointer2, POINTER_LENGTH_LONG)
2223 VARIABLE_POINTER(variable_pointer3, hf_sccp_variable_pointer3, POINTER_LENGTH_LONG)
2224 OPTIONAL_POINTER(POINTER_LENGTH_LONG)
2226 assoc = sccp_assoc(&(pinfo->src), &(pinfo->dst), slr, dlr);
2228 dissect_sccp_variable_parameter(tvb, pinfo, sccp_tree, tree,
2229 PARAMETER_CALLED_PARTY_ADDRESS,
2231 dissect_sccp_variable_parameter(tvb, pinfo, sccp_tree, tree,
2232 PARAMETER_CALLING_PARTY_ADDRESS,
2234 dissect_sccp_variable_parameter(tvb, pinfo, sccp_tree, tree,
2235 PARAMETER_LONG_DATA, variable_pointer3);
2237 dissect_sccp_unknown_message(tvb, sccp_tree);
2240 case MESSAGE_TYPE_LUDTS:
2241 if (decode_mtp3_standard != ANSI_STANDARD)
2243 offset += dissect_sccp_parameter(tvb, pinfo, sccp_tree, tree,
2244 PARAMETER_RETURN_CAUSE, offset,
2245 RETURN_CAUSE_LENGTH);
2246 offset += dissect_sccp_parameter(tvb, pinfo, sccp_tree, tree,
2247 PARAMETER_HOP_COUNTER, offset,
2248 HOP_COUNTER_LENGTH);
2250 VARIABLE_POINTER(variable_pointer1, hf_sccp_variable_pointer1, POINTER_LENGTH_LONG)
2251 VARIABLE_POINTER(variable_pointer2, hf_sccp_variable_pointer2, POINTER_LENGTH_LONG)
2252 VARIABLE_POINTER(variable_pointer3, hf_sccp_variable_pointer3, POINTER_LENGTH_LONG)
2253 OPTIONAL_POINTER(POINTER_LENGTH_LONG)
2255 assoc = sccp_assoc(&(pinfo->src), &(pinfo->dst), slr, dlr);
2257 dissect_sccp_variable_parameter(tvb, pinfo, sccp_tree, tree,
2258 PARAMETER_CALLED_PARTY_ADDRESS,
2260 dissect_sccp_variable_parameter(tvb, pinfo, sccp_tree, tree,
2261 PARAMETER_CALLING_PARTY_ADDRESS,
2263 dissect_sccp_variable_parameter(tvb, pinfo, sccp_tree, tree,
2264 PARAMETER_LONG_DATA, variable_pointer3);
2266 dissect_sccp_unknown_message(tvb, sccp_tree);
2270 dissect_sccp_unknown_message(tvb, sccp_tree);
2274 dissect_sccp_optional_parameters(tvb, pinfo, sccp_tree, tree,
2280 dissect_sccp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
2282 proto_item *sccp_item;
2283 proto_tree *sccp_tree = NULL;
2284 const mtp3_addr_pc_t *mtp3_addr_p;
2286 if ((pinfo->src.type == AT_SS7PC) &&
2287 ((mtp3_addr_p = (const mtp3_addr_pc_t *)pinfo->src.data)->type <= CHINESE_ITU_STANDARD))
2290 * Allow a protocol beneath to specify how the SCCP layer should be dissected.
2292 * It is possible to have multiple sets of SCCP traffic some of which is ITU
2293 * and some of which is ANSI.
2294 * An example is A-interface traffic having ANSI MTP3/ANSI SCCP/3GPP2 IOS
2295 * and at the same time ITU MTP3/ITU SCCP/ANSI TCAP/ANSI MAP.
2297 decode_mtp3_standard = mtp3_addr_p->type;
2301 decode_mtp3_standard = mtp3_standard;
2304 /* Make entry in the Protocol column on summary display */
2305 if (check_col(pinfo->cinfo, COL_PROTOCOL))
2306 switch(decode_mtp3_standard) {
2308 col_set_str(pinfo->cinfo, COL_PROTOCOL, "SCCP (Int. ITU)");
2311 col_set_str(pinfo->cinfo, COL_PROTOCOL, "SCCP (ANSI)");
2313 case CHINESE_ITU_STANDARD:
2314 col_set_str(pinfo->cinfo, COL_PROTOCOL, "SCCP (Chin. ITU)");
2316 case JAPAN_STANDARD:
2317 col_set_str(pinfo->cinfo, COL_PROTOCOL, "SCCP (Japan)");
2321 /* In the interest of speed, if "tree" is NULL, don't do any work not
2322 necessary to generate protocol tree items. */
2324 /* create the sccp protocol tree */
2325 sccp_item = proto_tree_add_item(tree, proto_sccp, tvb, 0, -1, FALSE);
2326 sccp_tree = proto_item_add_subtree(sccp_item, ett_sccp);
2329 /* Set whether message is UPLINK, DOWNLINK, or of UNKNOWN direction */
2331 if (pinfo->src.type == AT_SS7PC)
2334 * XXX - we assume that the "data" pointers of the source and destination
2335 * addresses are set to point to "mtp3_addr_pc_t" structures, so that
2336 * we can safely cast them.
2338 mtp3_addr_p = (const mtp3_addr_pc_t *)pinfo->src.data;
2340 if (sccp_source_pc_global == mtp3_addr_p->pc)
2342 pinfo->p2p_dir = P2P_DIR_SENT;
2346 /* assuming if src was SS7 PC then dst will be too */
2347 mtp3_addr_p = (const mtp3_addr_pc_t *)pinfo->dst.data;
2349 if (sccp_source_pc_global == mtp3_addr_p->pc)
2351 pinfo->p2p_dir = P2P_DIR_RECV;
2355 pinfo->p2p_dir = P2P_DIR_UNKNOWN;
2360 /* dissect the message */
2361 dissect_sccp_message(tvb, pinfo, sccp_tree, tree);
2364 static void init_sccp(void) {
2365 fragment_table_init (&sccp_xudt_msg_fragment_table);
2366 reassembled_table_init(&sccp_xudt_msg_reassembled_table);
2369 /* Register the protocol with Ethereal */
2371 proto_register_sccp(void)
2373 /* Setup list of header fields */
2374 static hf_register_info hf[] = {
2375 { &hf_sccp_message_type,
2376 { "Message Type", "sccp.message_type",
2377 FT_UINT8, BASE_HEX, VALS(sccp_message_type_values), 0x0,
2379 { &hf_sccp_variable_pointer1,
2380 { "Pointer to first Mandatory Variable parameter", "sccp.variable_pointer1",
2381 FT_UINT16, BASE_DEC, NULL, 0x0,
2383 { &hf_sccp_variable_pointer2,
2384 { "Pointer to second Mandatory Variable parameter", "sccp.variable_pointer2",
2385 FT_UINT16, BASE_DEC, NULL, 0x0,
2387 { &hf_sccp_variable_pointer3,
2388 { "Pointer to third Mandatory Variable parameter", "sccp.variable_pointer3",
2389 FT_UINT16, BASE_DEC, NULL, 0x0,
2391 { &hf_sccp_optional_pointer,
2392 { "Pointer to Optional parameter", "sccp.optional_pointer",
2393 FT_UINT16, BASE_DEC, NULL, 0x0,
2396 { "Called or Calling SubSystem Number", "sccp.ssn",
2397 FT_UINT8, BASE_DEC, VALS(sccp_ssn_values), 0x0,
2399 { &hf_sccp_gt_digits,
2400 { "Called or Calling GT Digits",
2402 FT_STRING, BASE_NONE, NULL, 0x0,
2405 { &hf_sccp_called_national_indicator,
2406 { "National Indicator", "sccp.called.ni",
2407 FT_UINT8, BASE_HEX, VALS(sccp_national_indicator_values), ANSI_NATIONAL_MASK,
2409 { &hf_sccp_called_routing_indicator,
2410 { "Routing Indicator", "sccp.called.ri",
2411 FT_UINT8, BASE_HEX, VALS(sccp_routing_indicator_values), ROUTING_INDICATOR_MASK,
2413 { &hf_sccp_called_itu_global_title_indicator,
2414 { "Global Title Indicator", "sccp.called.gti",
2415 FT_UINT8, BASE_HEX, VALS(sccp_itu_global_title_indicator_values), GTI_MASK,
2417 { &hf_sccp_called_ansi_global_title_indicator,
2418 { "Global Title Indicator", "sccp.called.gti",
2419 FT_UINT8, BASE_HEX, VALS(sccp_ansi_global_title_indicator_values), GTI_MASK,
2421 { &hf_sccp_called_itu_ssn_indicator,
2422 { "SubSystem Number Indicator", "sccp.called.ssni",
2423 FT_UINT8, BASE_HEX, VALS(sccp_ai_ssni_values), ITU_SSN_INDICATOR_MASK,
2425 { &hf_sccp_called_itu_point_code_indicator,
2426 { "Point Code Indicator", "sccp.called.pci",
2427 FT_UINT8, BASE_HEX, VALS(sccp_ai_pci_values), ITU_PC_INDICATOR_MASK,
2429 { &hf_sccp_called_ansi_ssn_indicator,
2430 { "SubSystem Number Indicator", "sccp.called.ssni",
2431 FT_UINT8, BASE_HEX, VALS(sccp_ai_ssni_values), ANSI_SSN_INDICATOR_MASK,
2433 { &hf_sccp_called_ansi_point_code_indicator,
2434 { "Point Code Indicator", "sccp.called.pci",
2435 FT_UINT8, BASE_HEX, VALS(sccp_ai_pci_values), ANSI_PC_INDICATOR_MASK,
2437 { &hf_sccp_called_ssn,
2438 { "SubSystem Number", "sccp.called.ssn",
2439 FT_UINT8, BASE_DEC, VALS(sccp_ssn_values), 0x0,
2441 { &hf_sccp_called_itu_pc,
2442 { "PC", "sccp.called.pc",
2443 FT_UINT16, BASE_DEC, NULL, ITU_PC_MASK,
2445 { &hf_sccp_called_ansi_pc,
2446 { "PC", "sccp.called.ansi_pc",
2447 FT_STRING, BASE_NONE, NULL, 0x0,
2449 { &hf_sccp_called_chinese_pc,
2450 { "PC", "sccp.called.chinese_pc",
2451 FT_STRING, BASE_NONE, NULL, 0x0,
2453 { &hf_sccp_called_japan_pc,
2454 { "PC", "sccp.called.pc",
2455 FT_UINT16, BASE_DEC, NULL, 0x0,
2457 { &hf_sccp_called_pc_network,
2459 "sccp.called.network",
2460 FT_UINT24, BASE_DEC, NULL, ANSI_NETWORK_MASK,
2462 { &hf_sccp_called_pc_cluster,
2464 "sccp.called.cluster",
2465 FT_UINT24, BASE_DEC, NULL, ANSI_CLUSTER_MASK,
2467 { &hf_sccp_called_pc_member,
2469 "sccp.called.member",
2470 FT_UINT24, BASE_DEC, NULL, ANSI_MEMBER_MASK,
2472 { &hf_sccp_called_gt_nai,
2473 { "Nature of Address Indicator",
2475 FT_UINT8, BASE_HEX, VALS(sccp_nai_values), GT_NAI_MASK,
2477 { &hf_sccp_called_gt_oe,
2478 { "Odd/Even Indicator",
2480 FT_UINT8, BASE_HEX, VALS(sccp_oe_values), GT_OE_MASK,
2482 { &hf_sccp_called_gt_tt,
2483 { "Translation Type",
2485 FT_UINT8, BASE_HEX, NULL, 0x0,
2487 { &hf_sccp_called_gt_np,
2490 FT_UINT8, BASE_HEX, VALS(sccp_np_values), GT_NP_MASK,
2492 { &hf_sccp_called_gt_es,
2493 { "Encoding Scheme",
2495 FT_UINT8, BASE_HEX, VALS(sccp_es_values), GT_ES_MASK,
2497 { &hf_sccp_called_gt_digits,
2499 "sccp.called.digits",
2500 FT_STRING, BASE_NONE, NULL, 0x0,
2503 { &hf_sccp_calling_national_indicator,
2504 { "National Indicator", "sccp.calling.ni",
2505 FT_UINT8, BASE_HEX, VALS(sccp_national_indicator_values), ANSI_NATIONAL_MASK,
2507 { &hf_sccp_calling_routing_indicator,
2508 { "Routing Indicator", "sccp.calling.ri",
2509 FT_UINT8, BASE_HEX, VALS(sccp_routing_indicator_values), ROUTING_INDICATOR_MASK,
2511 { &hf_sccp_calling_itu_global_title_indicator,
2512 { "Global Title Indicator", "sccp.calling.gti",
2513 FT_UINT8, BASE_HEX, VALS(sccp_itu_global_title_indicator_values), GTI_MASK,
2515 { &hf_sccp_calling_ansi_global_title_indicator,
2516 { "Global Title Indicator", "sccp.calling.gti",
2517 FT_UINT8, BASE_HEX, VALS(sccp_ansi_global_title_indicator_values), GTI_MASK,
2519 { &hf_sccp_calling_itu_ssn_indicator,
2520 { "SubSystem Number Indicator", "sccp.calling.ssni",
2521 FT_UINT8, BASE_HEX, VALS(sccp_ai_ssni_values), ITU_SSN_INDICATOR_MASK,
2523 { &hf_sccp_calling_itu_point_code_indicator,
2524 { "Point Code Indicator", "sccp.calling.pci",
2525 FT_UINT8, BASE_HEX, VALS(sccp_ai_pci_values), ITU_PC_INDICATOR_MASK,
2527 { &hf_sccp_calling_ansi_ssn_indicator,
2528 { "SubSystem Number Indicator", "sccp.calling.ssni",
2529 FT_UINT8, BASE_HEX, VALS(sccp_ai_ssni_values), ANSI_SSN_INDICATOR_MASK,
2531 { &hf_sccp_calling_ansi_point_code_indicator,
2532 { "Point Code Indicator", "sccp.calling.pci",
2533 FT_UINT8, BASE_HEX, VALS(sccp_ai_pci_values), ANSI_PC_INDICATOR_MASK,
2535 { &hf_sccp_calling_ssn,
2536 { "SubSystem Number", "sccp.calling.ssn",
2537 FT_UINT8, BASE_DEC, VALS(sccp_ssn_values), 0x0,
2539 { &hf_sccp_calling_itu_pc,
2540 { "PC", "sccp.calling.pc",
2541 FT_UINT16, BASE_DEC, NULL, ITU_PC_MASK,
2543 { &hf_sccp_calling_ansi_pc,
2544 { "PC", "sccp.calling.ansi_pc",
2545 FT_STRING, BASE_NONE, NULL, 0x0,
2547 { &hf_sccp_calling_chinese_pc,
2548 { "PC", "sccp.calling.chinese_pc",
2549 FT_STRING, BASE_NONE, NULL, 0x0,
2551 { &hf_sccp_calling_japan_pc,
2552 { "PC", "sccp.calling.pc",
2553 FT_UINT16, BASE_DEC, NULL, 0x0,
2555 { &hf_sccp_calling_pc_network,
2557 "sccp.calling.network",
2558 FT_UINT24, BASE_DEC, NULL, ANSI_NETWORK_MASK,
2560 { &hf_sccp_calling_pc_cluster,
2562 "sccp.calling.cluster",
2563 FT_UINT24, BASE_DEC, NULL, ANSI_CLUSTER_MASK,
2565 { &hf_sccp_calling_pc_member,
2567 "sccp.calling.member",
2568 FT_UINT24, BASE_DEC, NULL, ANSI_MEMBER_MASK,
2570 { &hf_sccp_calling_gt_nai,
2571 { "Nature of Address Indicator",
2573 FT_UINT8, BASE_HEX, VALS(sccp_nai_values), GT_NAI_MASK,
2575 { &hf_sccp_calling_gt_oe,
2576 { "Odd/Even Indicator",
2578 FT_UINT8, BASE_HEX, VALS(sccp_oe_values), GT_OE_MASK,
2580 { &hf_sccp_calling_gt_tt,
2581 { "Translation Type",
2583 FT_UINT8, BASE_HEX, NULL, 0x0,
2585 { &hf_sccp_calling_gt_np,
2588 FT_UINT8, BASE_HEX, VALS(sccp_np_values), GT_NP_MASK,
2590 { &hf_sccp_calling_gt_es,
2591 { "Encoding Scheme",
2593 FT_UINT8, BASE_HEX, VALS(sccp_es_values), GT_ES_MASK,
2595 { &hf_sccp_calling_gt_digits,
2597 "sccp.calling.digits",
2598 FT_STRING, BASE_NONE, NULL, 0x0,
2602 { "Destination Local Reference", "sccp.dlr",
2603 FT_UINT24, BASE_HEX, NULL, 0x0,
2606 { "Source Local Reference", "sccp.slr",
2607 FT_UINT24, BASE_HEX, NULL, 0x0,
2610 { "Local Reference", "sccp.lr",
2611 FT_UINT24, BASE_HEX, NULL, 0x0,
2614 { "Class", "sccp.class",
2615 FT_UINT8, BASE_HEX, NULL, CLASS_CLASS_MASK,
2617 { &hf_sccp_handling,
2618 { "Message handling", "sccp.handling",
2619 FT_UINT8, BASE_HEX, VALS(sccp_class_handling_values), CLASS_SPARE_HANDLING_MASK,
2622 { "More data", "sccp.more",
2623 FT_UINT8, BASE_HEX, VALS(sccp_segmenting_reassembling_values), SEGMENTING_REASSEMBLING_MASK,
2626 { "Receive Sequence Number", "sccp.rsn",
2627 FT_UINT8, BASE_HEX, NULL, RSN_MASK,
2629 { &hf_sccp_sequencing_segmenting_ssn,
2630 { "Sequencing Segmenting: Send Sequence Number", "sccp.sequencing_segmenting.ssn",
2631 FT_UINT8, BASE_HEX, NULL, SEND_SEQUENCE_NUMBER_MASK,
2633 { &hf_sccp_sequencing_segmenting_rsn,
2634 { "Sequencing Segmenting: Receive Sequence Number", "sccp.sequencing_segmenting.rsn",
2635 FT_UINT8, BASE_HEX, NULL, RECEIVE_SEQUENCE_NUMBER_MASK,
2637 { &hf_sccp_sequencing_segmenting_more,
2638 { "Sequencing Segmenting: More", "sccp.sequencing_segmenting.more",
2639 FT_UINT8, BASE_HEX, VALS(sccp_segmenting_reassembling_values), SEQUENCING_SEGMENTING_MORE_MASK,
2642 { "Credit", "sccp.credit",
2643 FT_UINT8, BASE_HEX, NULL, 0x0,
2645 { &hf_sccp_release_cause,
2646 { "Release Cause", "sccp.release_cause",
2647 FT_UINT8, BASE_HEX, VALS(sccp_release_cause_values), 0x0,
2649 { &hf_sccp_return_cause,
2650 { "Return Cause", "sccp.return_cause",
2651 FT_UINT8, BASE_HEX, VALS(sccp_return_cause_values), 0x0,
2653 { &hf_sccp_reset_cause,
2654 { "Reset Cause", "sccp.reset_cause",
2655 FT_UINT8, BASE_HEX, VALS(sccp_reset_cause_values), 0x0,
2657 { &hf_sccp_error_cause,
2658 { "Error Cause", "sccp.error_cause",
2659 FT_UINT8, BASE_HEX, VALS(sccp_error_cause_values), 0x0,
2661 { &hf_sccp_refusal_cause,
2662 { "Refusal Cause", "sccp.refusal_cause",
2663 FT_UINT8, BASE_HEX, VALS(sccp_refusal_cause_values), 0x0,
2665 { &hf_sccp_segmentation_first,
2666 { "Segmentation: First", "sccp.segmentation.first",
2667 FT_UINT8, BASE_HEX, VALS(sccp_segmentation_first_segment_values), SEGMENTATION_FIRST_SEGMENT_MASK,
2669 { &hf_sccp_segmentation_class,
2670 { "Segmentation: Class", "sccp.segmentation.class",
2671 FT_UINT8, BASE_HEX, VALS(sccp_segmentation_class_values), SEGMENTATION_CLASS_MASK,
2673 { &hf_sccp_segmentation_remaining,
2674 { "Segmentation: Remaining", "sccp.segmentation.remaining",
2675 FT_UINT8, BASE_HEX, NULL, SEGMENTATION_REMAINING_MASK,
2677 { &hf_sccp_segmentation_slr,
2678 { "Segmentation: Source Local Reference", "sccp.segmentation.slr",
2679 FT_UINT24, BASE_HEX, NULL, 0x0,
2681 { &hf_sccp_hop_counter,
2682 { "Hop Counter", "sccp.hops",
2683 FT_UINT8, BASE_HEX, NULL, 0x0,
2685 { &hf_sccp_importance,
2686 { "Importance", "sccp.importance",
2687 FT_UINT8, BASE_HEX, NULL, IMPORTANCE_IMPORTANCE_MASK,
2690 /* ISNI is ANSI only */
2691 { &hf_sccp_ansi_isni_mi,
2692 { "ISNI Mark for Identification Indicator", "sccp.isni.mi",
2693 FT_UINT8, BASE_HEX, VALS(sccp_isni_mark_for_id_values), ANSI_ISNI_MI_MASK,
2695 { &hf_sccp_ansi_isni_iri,
2696 { "ISNI Routing Indicator", "sccp.isni.iri",
2697 FT_UINT8, BASE_HEX, VALS(sccp_isni_iri_values), ANSI_ISNI_IRI_MASK,
2699 { &hf_sccp_ansi_isni_ti,
2700 { "ISNI Type Indicator", "sccp.isni.ti",
2701 FT_UINT8, BASE_HEX, VALS(sccp_isni_ti_values), ANSI_ISNI_TI_MASK,
2703 { &hf_sccp_ansi_isni_netspec,
2704 { "ISNI Network Specific (Type 1)", "sccp.isni.netspec",
2705 FT_UINT8, BASE_HEX, NULL, ANSI_ISNI_NETSPEC_MASK,
2707 { &hf_sccp_ansi_isni_counter,
2708 { "ISNI Counter", "sccp.isni.counter",
2709 FT_UINT8, BASE_HEX, NULL, ANSI_ISNI_COUNTER_MASK,
2711 {&hf_sccp_xudt_msg_fragments,
2712 {"Message fragments", "isup_apm.msg.fragments",
2713 FT_NONE, BASE_NONE, NULL, 0x00, NULL, HFILL }
2715 {&hf_sccp_xudt_msg_fragment,
2716 {"Message fragment", "isup_apm.msg.fragment",
2717 FT_FRAMENUM, BASE_NONE, NULL, 0x00, NULL, HFILL }
2719 {&hf_sccp_xudt_msg_fragment_overlap,
2720 {"Message fragment overlap", "isup_apm.msg.fragment.overlap",
2721 FT_BOOLEAN, BASE_NONE, NULL, 0x00, NULL, HFILL }
2723 {&hf_sccp_xudt_msg_fragment_overlap_conflicts,
2724 {"Message fragment overlapping with conflicting data","isup_apm.msg.fragment.overlap.conflicts",
2725 FT_BOOLEAN, BASE_NONE, NULL, 0x00, NULL, HFILL }
2727 {&hf_sccp_xudt_msg_fragment_multiple_tails,
2728 {"Message has multiple tail fragments", "isup_apm.msg.fragment.multiple_tails",
2729 FT_BOOLEAN, BASE_NONE, NULL, 0x00, NULL, HFILL }
2731 {&hf_sccp_xudt_msg_fragment_too_long_fragment,
2732 {"Message fragment too long", "isup_apm.msg.fragment.too_long_fragment",
2733 FT_BOOLEAN, BASE_NONE, NULL, 0x00, NULL, HFILL }
2735 {&hf_sccp_xudt_msg_fragment_error,
2736 {"Message defragmentation error", "isup_apm.msg.fragment.error",
2737 FT_FRAMENUM, BASE_NONE, NULL, 0x00, NULL, HFILL }
2739 {&hf_sccp_xudt_msg_reassembled_in,
2740 {"Reassembled in", "isup_apm.msg.reassembled.in",
2741 FT_FRAMENUM, BASE_NONE, NULL, 0x00, NULL, HFILL }
2746 /* Setup protocol subtree array */
2747 static gint *ett[] = {
2750 &ett_sccp_called_ai,
2751 &ett_sccp_called_pc,
2752 &ett_sccp_called_gt,
2754 &ett_sccp_calling_ai,
2755 &ett_sccp_calling_pc,
2756 &ett_sccp_calling_gt,
2757 &ett_sccp_sequencing_segmenting,
2758 &ett_sccp_segmentation,
2759 &ett_sccp_ansi_isni_routing_control,
2760 &ett_sccp_xudt_msg_fragment,
2761 &ett_sccp_xudt_msg_fragments,
2764 /* Register the protocol name and description */
2765 proto_sccp = proto_register_protocol("Signalling Connection Control Part",
2768 register_dissector("sccp", dissect_sccp, proto_sccp);
2770 /* Required function calls to register the header fields and subtrees used */
2771 proto_register_field_array(proto_sccp, hf, array_length(hf));
2772 proto_register_subtree_array(ett, array_length(ett));
2774 sccp_ssn_dissector_table = register_dissector_table("sccp.ssn", "SCCP SSN", FT_UINT8, BASE_DEC);
2776 register_heur_dissector_list("sccp", &heur_subdissector_list);
2778 sccp_module = prefs_register_protocol(proto_sccp, NULL);
2780 prefs_register_uint_preference(sccp_module, "source_pc",
2782 "The source point code (usually MSC) (to determine whether message is uplink or downlink)",
2783 16, &sccp_source_pc_global);
2785 prefs_register_bool_preference(sccp_module, "show_length",
2787 "Show parameter length in the protocol tree",
2790 prefs_register_bool_preference(sccp_module, "defragment_xudt",
2791 "Reassemble XUDT messages",
2792 "Whether XUDT messages dshould be reassembled",
2793 &sccp_xudt_desegment);
2795 register_init_routine(&init_sccp);
2797 assocs = se_tree_create(SE_TREE_TYPE_RED_BLACK, "sccp_associations");
2802 proto_reg_handoff_sccp(void)
2804 dissector_handle_t sccp_handle;
2806 sccp_handle = find_dissector("sccp");
2808 dissector_add("mtp3.service_indicator", SCCP_SI, sccp_handle);
2809 dissector_add_string("tali.opcode", "sccp", sccp_handle);
2811 data_handle = find_dissector("data");