2 * Routines for Signalling Connection Control Part (SCCP) dissection
4 * It is hopefully compliant to:
7 * YDN 038-1997 (Chinese ITU variant)
9 * Copyright 2002, Jeff Morriss <jeff.morriss[AT]ulticom.com>
11 * $Id: packet-sccp.c,v 1.20 2004/01/08 20:19:03 guy Exp $
13 * Ethereal - Network traffic analyzer
14 * By Gerald Combs <gerald@ethereal.com>
15 * Copyright 1998 Gerald Combs
17 * Copied from packet-m2pa.c
19 * This program is free software; you can redistribute it and/or
20 * modify it under the terms of the GNU General Public License
21 * as published by the Free Software Foundation; either version 2
22 * of the License, or (at your option) any later version.
24 * This program is distributed in the hope that it will be useful,
25 * but WITHOUT ANY WARRANTY; without even the implied warranty of
26 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
27 * GNU General Public License for more details.
29 * You should have received a copy of the GNU General Public License
30 * along with this program; if not, write to the Free Software
31 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
44 #ifdef NEED_SNPRINTF_H
48 #include <epan/packet.h>
49 #include "packet-mtp3.h"
54 #define MESSAGE_TYPE_OFFSET 0
55 #define MESSAGE_TYPE_LENGTH 1
56 #define POINTER_LENGTH 1
57 #define POINTER_LENGTH_LONG 2
59 #define MESSAGE_TYPE_CR 0x01
60 #define MESSAGE_TYPE_CC 0x02
61 #define MESSAGE_TYPE_CREF 0x03
62 #define MESSAGE_TYPE_RLSD 0x04
63 #define MESSAGE_TYPE_RLC 0x05
64 #define MESSAGE_TYPE_DT1 0x06
65 #define MESSAGE_TYPE_DT2 0x07
66 #define MESSAGE_TYPE_AK 0x08
67 #define MESSAGE_TYPE_UDT 0x09
68 #define MESSAGE_TYPE_UDTS 0x0a
69 #define MESSAGE_TYPE_ED 0x0b
70 #define MESSAGE_TYPE_EA 0x0c
71 #define MESSAGE_TYPE_RSR 0x0d
72 #define MESSAGE_TYPE_RSC 0x0e
73 #define MESSAGE_TYPE_ERR 0x0f
74 #define MESSAGE_TYPE_IT 0x10
75 #define MESSAGE_TYPE_XUDT 0x11
76 #define MESSAGE_TYPE_XUDTS 0x12
77 /* The below 2 are ITU only */
78 #define MESSAGE_TYPE_LUDT 0x13
79 #define MESSAGE_TYPE_LUDTS 0x14
81 /* Same as below but with names typed out */
82 static const value_string sccp_message_type_values[] = {
83 { MESSAGE_TYPE_CR, "Connection Request" },
84 { MESSAGE_TYPE_CC, "Connection Confirm" },
85 { MESSAGE_TYPE_CREF, "Connection Refused" },
86 { MESSAGE_TYPE_RLSD, "Released" },
87 { MESSAGE_TYPE_RLC, "Release Complete" },
88 { MESSAGE_TYPE_DT1, "Data Form 1" },
89 { MESSAGE_TYPE_DT2, "Data Form 2" },
90 { MESSAGE_TYPE_AK, "Data Acknowledgement" },
91 { MESSAGE_TYPE_UDT, "Unitdata" },
92 { MESSAGE_TYPE_UDTS, "Unitdata Service" },
93 { MESSAGE_TYPE_ED, "Expedited Data" },
94 { MESSAGE_TYPE_EA, "Expedited Data Acknowledgement" },
95 { MESSAGE_TYPE_RSR, "Reset Request" },
96 { MESSAGE_TYPE_RSC, "Reset Confirmation" },
97 { MESSAGE_TYPE_ERR, "Error" },
98 { MESSAGE_TYPE_IT, "Inactivity Timer" },
99 { MESSAGE_TYPE_XUDT, "Extended Unitdata" },
100 { MESSAGE_TYPE_XUDTS, "Extended Unitdata Service" },
101 { MESSAGE_TYPE_LUDT, "Long Unitdata (ITU)" },
102 { MESSAGE_TYPE_LUDTS, "Long Unitdata Service (ITU)" },
105 /* Same as above but in acronym form (for the Info column) */
106 static const value_string sccp_message_type_acro_values[] = {
107 { MESSAGE_TYPE_CR, "CR" },
108 { MESSAGE_TYPE_CC, "CC" },
109 { MESSAGE_TYPE_CREF, "CREF" },
110 { MESSAGE_TYPE_RLSD, "RLSD" },
111 { MESSAGE_TYPE_RLC, "RLC" },
112 { MESSAGE_TYPE_DT1, "DT1" },
113 { MESSAGE_TYPE_DT2, "DT2" },
114 { MESSAGE_TYPE_AK, "AK" },
115 { MESSAGE_TYPE_UDT, "UDT" },
116 { MESSAGE_TYPE_UDTS, "UDTS" },
117 { MESSAGE_TYPE_ED, "ED" },
118 { MESSAGE_TYPE_EA, "EA" },
119 { MESSAGE_TYPE_RSR, "RSR" },
120 { MESSAGE_TYPE_RSC, "RSC" },
121 { MESSAGE_TYPE_ERR, "ERR" },
122 { MESSAGE_TYPE_IT, "IT" },
123 { MESSAGE_TYPE_XUDT, "XUDT" },
124 { MESSAGE_TYPE_XUDTS, "XUDTS" },
125 { MESSAGE_TYPE_LUDT, "LUDT" },
126 { MESSAGE_TYPE_LUDTS, "LUDTS" },
129 #define PARAMETER_LENGTH_LENGTH 1
130 #define PARAMETER_LONG_DATA_LENGTH_LENGTH 2
131 #define PARAMETER_TYPE_LENGTH 1
133 #define PARAMETER_END_OF_OPTIONAL_PARAMETERS 0x00
134 #define PARAMETER_DESTINATION_LOCAL_REFERENCE 0x01
135 #define PARAMETER_SOURCE_LOCAL_REFERENCE 0x02
136 #define PARAMETER_CALLED_PARTY_ADDRESS 0x03
137 #define PARAMETER_CALLING_PARTY_ADDRESS 0x04
138 #define PARAMETER_CLASS 0x05
139 #define PARAMETER_SEGMENTING_REASSEMBLING 0x06
140 #define PARAMETER_RECEIVE_SEQUENCE_NUMBER 0x07
141 #define PARAMETER_SEQUENCING_SEGMENTING 0x08
142 #define PARAMETER_CREDIT 0x09
143 #define PARAMETER_RELEASE_CAUSE 0x0a
144 #define PARAMETER_RETURN_CAUSE 0x0b
145 #define PARAMETER_RESET_CAUSE 0x0c
146 #define PARAMETER_ERROR_CAUSE 0x0d
147 #define PARAMETER_REFUSAL_CAUSE 0x0e
148 #define PARAMETER_DATA 0x0f
149 #define PARAMETER_SEGMENTATION 0x10
150 #define PARAMETER_HOP_COUNTER 0x11
151 /* The below 2 are ITU only */
152 #define PARAMETER_IMPORTANCE 0x12
153 #define PARAMETER_LONG_DATA 0x13
154 /* ISNI is ANSI only */
155 #define PARAMETER_ISNI 0xfa
157 static const value_string sccp_parameter_values[] = {
158 { PARAMETER_END_OF_OPTIONAL_PARAMETERS, "End of Optional Parameters" },
159 { PARAMETER_DESTINATION_LOCAL_REFERENCE, "Destination Local Reference" },
160 { PARAMETER_SOURCE_LOCAL_REFERENCE, "Source Local Reference" },
161 { PARAMETER_CALLED_PARTY_ADDRESS, "Called Party Address" },
162 { PARAMETER_CALLING_PARTY_ADDRESS, "Calling Party Address" },
163 { PARAMETER_CLASS, "Protocol Class" },
164 { PARAMETER_SEGMENTING_REASSEMBLING, "Segmenting/Reassembling" },
165 { PARAMETER_RECEIVE_SEQUENCE_NUMBER, "Receive Sequence Number" },
166 { PARAMETER_SEQUENCING_SEGMENTING, "Sequencing/Segmenting" },
167 { PARAMETER_CREDIT, "Credit" },
168 { PARAMETER_RELEASE_CAUSE, "Release Cause" },
169 { PARAMETER_RETURN_CAUSE, "Return Cause" },
170 { PARAMETER_RESET_CAUSE, "Reset Cause" },
171 { PARAMETER_ERROR_CAUSE, "Error Cause" },
172 { PARAMETER_REFUSAL_CAUSE, "Refusal Cause" },
173 { PARAMETER_DATA, "Data" },
174 { PARAMETER_SEGMENTATION, "Segmentation" },
175 { PARAMETER_HOP_COUNTER, "Hop Counter" },
176 { PARAMETER_IMPORTANCE, "Importance (ITU)" },
177 { PARAMETER_LONG_DATA, "Long Data (ITU)" },
178 { PARAMETER_ISNI, "Intermediate Signaling Network Identification (ANSI)" },
182 #define END_OF_OPTIONAL_PARAMETERS_LENGTH 1
183 #define DESTINATION_LOCAL_REFERENCE_LENGTH 3
184 #define SOURCE_LOCAL_REFERENCE_LENGTH 3
185 #define PROTOCOL_CLASS_LENGTH 1
186 #define RECEIVE_SEQUENCE_NUMBER_LENGTH 1
187 #define CREDIT_LENGTH 1
188 #define RELEASE_CAUSE_LENGTH 1
189 #define RETURN_CAUSE_LENGTH 1
190 #define RESET_CAUSE_LENGTH 1
191 #define ERROR_CAUSE_LENGTH 1
192 #define REFUSAL_CAUSE_LENGTH 1
193 #define HOP_COUNTER_LENGTH 1
194 #define IMPORTANCE_LENGTH 1
197 /* Parts of the Called and Calling Address parameters */
198 /* Address Indicator */
199 #define ADDRESS_INDICATOR_LENGTH 1
200 #define ITU_RESERVED_MASK 0x80
201 #define ANSI_NATIONAL_MASK 0x80
202 #define ROUTING_INDICATOR_MASK 0x40
203 #define GTI_MASK 0x3C
205 #define ITU_SSN_INDICATOR_MASK 0x02
206 #define ITU_PC_INDICATOR_MASK 0x01
207 #define ANSI_PC_INDICATOR_MASK 0x02
208 #define ANSI_SSN_INDICATOR_MASK 0x01
210 static const value_string sccp_national_indicator_values[] = {
211 { 0x0, "Address coded to International standard" },
212 { 0x1, "Address coded to National standard" },
215 static const value_string sccp_routing_indicator_values[] = {
216 { 0x0, "Route on GT" },
217 { 0x1, "Route on SSN" },
220 #define AI_GTI_NO_GT 0x0
221 #define ITU_AI_GTI_NAI 0x1
222 #define AI_GTI_TT 0x2
223 #define ITU_AI_GTI_TT_NP_ES 0x3
224 #define ITU_AI_GTI_TT_NP_ES_NAI 0x4
225 static const value_string sccp_itu_global_title_indicator_values[] = {
226 { AI_GTI_NO_GT, "No Global Title" },
227 { ITU_AI_GTI_NAI, "Nature of Address Indicator only" },
228 { AI_GTI_TT, "Translation Type only" },
229 { ITU_AI_GTI_TT_NP_ES, "Translation Type, Numbering Plan, and Encoding Scheme included" },
230 { ITU_AI_GTI_TT_NP_ES_NAI, "Translation Type, Numbering Plan, Encoding Scheme, and Nature of Address Indicator included" },
233 /* #define AI_GTI_NO_GT 0x0 */
234 #define ANSI_AI_GTI_TT_NP_ES 0x1
235 /* #define AI_GTI_TT 0x2 */
236 static const value_string sccp_ansi_global_title_indicator_values[] = {
237 { AI_GTI_NO_GT, "No Global Title" },
238 { ANSI_AI_GTI_TT_NP_ES, "Translation Type, Numbering Plan, and Encoding Scheme included" },
239 { AI_GTI_TT, "Translation Type only" },
242 static const value_string sccp_ai_pci_values[] = {
243 { 0x1, "Point Code present" },
244 { 0x0, "Point Code not present" },
247 static const value_string sccp_ai_ssni_values[] = {
248 { 0x1, "SSN present" },
249 { 0x0, "SSN not present" },
252 #define ADDRESS_SSN_LENGTH 1
253 #define INVALID_SSN 0xff
254 static const value_string sccp_ssn_values[] = {
255 { 0x00, "SSN not known/not used" },
256 { 0x01, "SCCP management" },
257 { 0x02, "Reserved for ITU-T allocation" },
258 { 0x03, "ISDN User Part" },
259 { 0x04, "OMAP (Operation, Maintenance, and Administration Part)" },
260 { 0x05, "MAP (Mobile Application Part)" },
261 { 0x06, "HLR (Home Location Register)" },
262 { 0x07, "VLR (Visitor Location Register)" },
263 { 0x08, "MSC (Mobile Switching Center)" },
264 { 0x09, "EIC/EIR (Equipment Identifier Center/Equipment Identification Register)" },
265 { 0x0a, "AUC/AC (Authentication Center)" },
266 { 0x0b, "ISDN supplementary services (ITU only)" },
267 { 0x0c, "Reserved for international use (ITU only)" },
268 { 0x0d, "Broadband ISDN edge-to-edge applications (ITU only)" },
269 { 0x0e, "TC test responder (ITU only)" },
272 { 0xfe, "BSSAP/BSAP" },
276 /* * * * * * * * * * * * * * * * *
277 * Global Title: ITU GTI == 0001 *
278 * * * * * * * * * * * * * * * * */
279 #define GT_NAI_MASK 0x7F
280 #define GT_NAI_LENGTH 1
281 static const value_string sccp_nai_values[] = {
282 { 0x00, "NAI unknown" },
283 { 0x01, "Subscriber Number" },
284 { 0x02, "Reserved for national use" },
285 { 0x03, "National significant number" },
286 { 0x04, "International number" },
290 #define GT_OE_MASK 0x80
293 static const value_string sccp_oe_values[] = {
294 { GT_OE_EVEN, "Even number of address signals" },
295 { GT_OE_ODD, "Odd number of address signals" },
298 #define GT_SIGNAL_LENGTH 1
299 #define GT_ODD_SIGNAL_MASK 0x0f
300 #define GT_EVEN_SIGNAL_MASK 0xf0
301 #define GT_EVEN_SIGNAL_SHIFT 4
302 #define GT_MAX_SIGNALS 32
303 static const value_string sccp_address_signal_values[] = {
323 /* * * * * * * * * * * * * * * * * * * * *
324 * Global Title: ITU and ANSI GTI == 0010 *
325 * * * * * * * * * * * * * * * * * * * * */
326 #define GT_TT_LENGTH 1
329 /* * * * * * * * * * * * * * * * * * * * * * * * * *
330 * Global Title: ITU GTI == 0011, ANSI GTI == 0001 *
331 * * * * * * * * * * * * * * * * * * * * * * * * * */
332 #define GT_NP_MASK 0xf0
333 #define GT_NP_ES_LENGTH 1
334 static const value_string sccp_np_values[] = {
336 { 0x1, "ISDN/telephony" },
337 { 0x2, "Generic (ITU)/Reserved (ANSI)" },
340 { 0x5, "Maritime mobile" },
341 { 0x6, "Land mobile" },
342 { 0x7, "ISDN/mobile" },
343 { 0xe, "Private network or network-specific" },
347 #define GT_ES_MASK 0x0f
348 #define GT_ES_UNKNOWN 0x0
349 #define GT_ES_BCD_ODD 0x1
350 #define GT_ES_BCD_EVEN 0x2
351 #define GT_ES_NATIONAL 0x3
352 #define GT_ES_RESERVED 0xf
353 static const value_string sccp_es_values[] = {
354 { GT_ES_UNKNOWN, "Unknown" },
355 { GT_ES_BCD_ODD, "BCD, odd number of digits" },
356 { GT_ES_BCD_EVEN, "BCD, even number of digits" },
357 { GT_ES_NATIONAL, "National specific" },
358 { GT_ES_RESERVED, "Reserved (ITU)/Spare (ANSI)" },
361 /* Address signals above */
364 /* * * * * * * * * * * * * * * * *
365 * Global Title: ITU GTI == 0100 *
366 * * * * * * * * * * * * * * * * */
370 /* Address signals above */
373 #define CLASS_CLASS_MASK 0xf
374 #define CLASS_SPARE_HANDLING_MASK 0xf0
375 static const value_string sccp_class_handling_values [] = {
376 { 0x0, "No special options" },
377 { 0x8, "Return message on error" },
381 #define SEGMENTING_REASSEMBLING_LENGTH 1
382 #define SEGMENTING_REASSEMBLING_MASK 0x01
383 #define NO_MORE_DATA 0
385 /* This is also used by sequencing-segmenting parameter */
386 static const value_string sccp_segmenting_reassembling_values [] = {
387 { NO_MORE_DATA, "No more data" },
388 { MORE_DATA, "More data" },
392 #define RECEIVE_SEQUENCE_NUMBER_LENGTH 1
393 #define RSN_MASK 0xfe
395 #define SEQUENCING_SEGMENTING_LENGTH 2
396 #define SEQUENCING_SEGMENTING_SSN_LENGTH 1
397 #define SEQUENCING_SEGMENTING_RSN_LENGTH 1
398 #define SEND_SEQUENCE_NUMBER_MASK 0xfe
399 #define RECEIVE_SEQUENCE_NUMBER_MASK 0xfe
400 #define SEQUENCING_SEGMENTING_MORE_MASK 0x01
403 #define CREDIT_LENGTH 1
405 #define RELEASE_CAUSE_LENGTH 1
406 static const value_string sccp_release_cause_values [] = {
407 { 0x00, "End user originated" },
408 { 0x01, "End user congestion" },
409 { 0x02, "End user failure" },
410 { 0x03, "SCCP user originated" },
411 { 0x04, "Remote procedure error" },
412 { 0x05, "Inconsistent connection data" },
413 { 0x06, "Access failure" },
414 { 0x07, "Access congestion" },
415 { 0x08, "Subsystem failure" },
416 { 0x09, "Subsystem congestion" },
417 { 0x0a, "MTP failure" },
418 { 0x0b, "Netowrk congestion" },
419 { 0x0c, "Expiration of reset timer" },
420 { 0x0d, "Expiration of receive inactivity timer" },
421 { 0x0e, "Reserved" },
422 { 0x0f, "Unqualified" },
423 { 0x10, "SCCP failure (ITU only)" },
427 #define RETURN_CAUSE_LENGTH 1
428 static const value_string sccp_return_cause_values [] = {
429 { 0x00, "No translation for an address of such nature" },
430 { 0x01, "No translation for this specific address" },
431 { 0x02, "Subsystem congestion" },
432 { 0x03, "Subsystem failure" },
433 { 0x04, "Unequipped failure" },
434 { 0x05, "MTP failure" },
435 { 0x06, "Network congestion" },
436 { 0x07, "Unqualified" },
437 { 0x08, "Error in message transport" },
438 { 0x09, "Error in local processing" },
439 { 0x0a, "Destination cannot perform reassembly" },
440 { 0x0b, "SCCP failure" },
441 { 0x0c, "Hop counter violation" },
442 { 0x0d, "Segmentation not supported (ITU only)" },
443 { 0x0e, "Segmentation failure (ITU only)" },
444 { 0xf9, "Invalid ISNI routing request (ANSI only)"},
445 { 0xfa, "Unauthorized message (ANSI only)" },
446 { 0xfb, "Message incompatibility (ANSI only)" },
447 { 0xfc, "Cannot perform ISNI constrained routing (ANSI only)" },
448 { 0xfd, "Unable to perform ISNI identification (ANSI only)" },
452 #define RESET_CAUSE_LENGTH 1
453 static const value_string sccp_reset_cause_values [] = {
454 { 0x00, "End user originated" },
455 { 0x01, "SCCP user originated" },
456 { 0x02, "Message out of order - incorrect send sequence number" },
457 { 0x03, "Message out of order - incorrect receive sequence number" },
458 { 0x04, "Remote procedure error - message out of window" },
459 { 0x05, "Remote procedure error - incorrect send sequence number after (re)initialization" },
460 { 0x06, "Remote procedure error - general" },
461 { 0x07, "Remote end user operational" },
462 { 0x08, "Network operational" },
463 { 0x09, "Access operational" },
464 { 0x0a, "Network congestion" },
465 { 0x0b, "Reserved (ITU)/Not obtainable (ANSI)" },
466 { 0x0c, "Unqualified" },
470 #define ERROR_CAUSE_LENGTH 1
471 static const value_string sccp_error_cause_values [] = {
472 { 0x00, "Local Reference Number (LRN) mismatch - unassigned destination LRN" },
473 { 0x01, "Local Reference Number (LRN) mismatch - inconsistent source LRN" },
474 { 0x02, "Point code mismatch" },
475 { 0x03, "Service class mismatch" },
476 { 0x04, "Unqualified" },
480 #define REFUSAL_CAUSE_LENGTH 1
481 static const value_string sccp_refusal_cause_values [] = {
482 { 0x00, "End user originated" },
483 { 0x01, "End user congestion" },
484 { 0x02, "End user failure" },
485 { 0x03, "SCCP user originated" },
486 { 0x04, "Destination address unknown" },
487 { 0x05, "Destination inaccessible" },
488 { 0x06, "Network resource - QOS not available/non-transient" },
489 { 0x07, "Network resource - QOS not available/transient" },
490 { 0x08, "Access failure" },
491 { 0x09, "Access congestion" },
492 { 0x0a, "Subsystem failure" },
493 { 0x0b, "Subsystem congestion" },
494 { 0x0c, "Expiration of connection establishment timer" },
495 { 0x0d, "Incompatible user data" },
496 { 0x0e, "Reserved" },
497 { 0x0f, "Unqualified" },
498 { 0x10, "Hop counter violation" },
499 { 0x11, "SCCP failure (ITU only)" },
500 { 0x12, "No translation for an address of such nature" },
501 { 0x13, "Unequipped user" },
505 #define SEGMENTATION_LENGTH 4
506 #define SEGMENTATION_FIRST_SEGMENT_MASK 0x80
507 #define SEGMENTATION_CLASS_MASK 0x40
508 #define SEGMENTATION_SPARE_MASK 0x30
509 #define SEGMENTATION_REMAINING_MASK 0x0f
510 static const value_string sccp_segmentation_first_segment_values [] = {
511 { 1, "First segment" },
512 { 0, "Not first segment" },
514 static const value_string sccp_segmentation_class_values [] = {
515 { 0, "Class 0 selected" },
516 { 1, "Class 1 selected" },
520 #define HOP_COUNTER_LENGTH 1
522 #define IMPORTANCE_LENGTH 1
523 #define IMPORTANCE_IMPORTANCE_MASK 0x7
526 #define ANSI_ISNI_ROUTING_CONTROL_LENGTH 1
527 #define ANSI_ISNI_MI_MASK 0x01
528 #define ANSI_ISNI_IRI_MASK 0x06
529 #define ANSI_ISNI_RES_MASK 0x08
530 #define ANSI_ISNI_TI_MASK 0x10
531 #define ANSI_ISNI_TI_SHIFT 4
532 #define ANSI_ISNI_COUNTER_MASK 0xe0
534 #define ANSI_ISNI_NETSPEC_MASK 0x03
536 static const value_string sccp_isni_mark_for_id_values [] = {
537 { 0x0, "Do not identify networks" },
538 { 0x1, "Identify networks" },
541 static const value_string sccp_isni_iri_values [] = {
542 { 0x0, "Neither constrained nor suggested ISNI routing" },
543 { 0x1, "Constrained ISNI routing" },
544 { 0x2, "Reserved for suggested ISNI routing" },
548 #define ANSI_ISNI_TYPE_0 0x0
549 #define ANSI_ISNI_TYPE_1 0x1
550 static const value_string sccp_isni_ti_values [] = {
551 { ANSI_ISNI_TYPE_0, "Type zero ISNI parameter format" },
552 { ANSI_ISNI_TYPE_1, "Type one ISNI parameter format" },
556 /* Initialize the protocol and registered fields */
557 static int proto_sccp = -1;
558 static int hf_sccp_message_type = -1;
559 static int hf_sccp_variable_pointer1 = -1;
560 static int hf_sccp_variable_pointer2 = -1;
561 static int hf_sccp_variable_pointer3 = -1;
562 static int hf_sccp_optional_pointer = -1;
563 static int hf_sccp_ssn = -1;
564 static int hf_sccp_gt_digits = -1;
566 /* Called Party address */
567 static int hf_sccp_called_national_indicator = -1;
568 static int hf_sccp_called_routing_indicator = -1;
569 static int hf_sccp_called_itu_global_title_indicator = -1;
570 static int hf_sccp_called_ansi_global_title_indicator = -1;
571 static int hf_sccp_called_itu_ssn_indicator = -1;
572 static int hf_sccp_called_itu_point_code_indicator = -1;
573 static int hf_sccp_called_ansi_ssn_indicator = -1;
574 static int hf_sccp_called_ansi_point_code_indicator = -1;
575 static int hf_sccp_called_ssn = -1;
576 static int hf_sccp_called_pc_member = -1;
577 static int hf_sccp_called_pc_cluster = -1;
578 static int hf_sccp_called_pc_network = -1;
579 static int hf_sccp_called_ansi_pc = -1;
580 static int hf_sccp_called_chinese_pc = -1;
581 static int hf_sccp_called_itu_pc = -1;
582 static int hf_sccp_called_gt_nai = -1;
583 static int hf_sccp_called_gt_oe = -1;
584 static int hf_sccp_called_gt_tt = -1;
585 static int hf_sccp_called_gt_np = -1;
586 static int hf_sccp_called_gt_es = -1;
587 static int hf_sccp_called_gt_digits = -1;
589 /* Calling party address */
590 static int hf_sccp_calling_national_indicator = -1;
591 static int hf_sccp_calling_routing_indicator = -1;
592 static int hf_sccp_calling_itu_global_title_indicator = -1;
593 static int hf_sccp_calling_ansi_global_title_indicator = -1;
594 static int hf_sccp_calling_itu_ssn_indicator = -1;
595 static int hf_sccp_calling_itu_point_code_indicator = -1;
596 static int hf_sccp_calling_ansi_ssn_indicator = -1;
597 static int hf_sccp_calling_ansi_point_code_indicator = -1;
598 static int hf_sccp_calling_ssn = -1;
599 static int hf_sccp_calling_pc_member = -1;
600 static int hf_sccp_calling_pc_cluster = -1;
601 static int hf_sccp_calling_pc_network = -1;
602 static int hf_sccp_calling_ansi_pc = -1;
603 static int hf_sccp_calling_chinese_pc = -1;
604 static int hf_sccp_calling_itu_pc = -1;
605 static int hf_sccp_calling_gt_nai = -1;
606 static int hf_sccp_calling_gt_oe = -1;
607 static int hf_sccp_calling_gt_tt = -1;
608 static int hf_sccp_calling_gt_np = -1;
609 static int hf_sccp_calling_gt_es = -1;
610 static int hf_sccp_calling_gt_digits = -1;
612 /* Other parameter values */
613 static int hf_sccp_dlr = -1;
614 static int hf_sccp_slr = -1;
615 static int hf_sccp_class = -1;
616 static int hf_sccp_handling = -1;
617 static int hf_sccp_more = -1;
618 static int hf_sccp_rsn = -1;
619 static int hf_sccp_sequencing_segmenting_ssn = -1;
620 static int hf_sccp_sequencing_segmenting_rsn = -1;
621 static int hf_sccp_sequencing_segmenting_more = -1;
622 static int hf_sccp_credit = -1;
623 static int hf_sccp_release_cause = -1;
624 static int hf_sccp_return_cause = -1;
625 static int hf_sccp_reset_cause = -1;
626 static int hf_sccp_error_cause = -1;
627 static int hf_sccp_refusal_cause = -1;
628 static int hf_sccp_segmentation_first = -1;
629 static int hf_sccp_segmentation_class = -1;
630 static int hf_sccp_segmentation_remaining = -1;
631 static int hf_sccp_segmentation_slr = -1;
632 static int hf_sccp_hop_counter = -1;
633 static int hf_sccp_importance = -1;
634 static int hf_sccp_ansi_isni_mi = -1;
635 static int hf_sccp_ansi_isni_iri = -1;
636 static int hf_sccp_ansi_isni_ti = -1;
637 static int hf_sccp_ansi_isni_netspec = -1;
638 static int hf_sccp_ansi_isni_counter = -1;
641 /* Initialize the subtree pointers */
642 static gint ett_sccp = -1;
643 static gint ett_sccp_called = -1;
644 static gint ett_sccp_called_ai = -1;
645 static gint ett_sccp_called_pc = -1;
646 static gint ett_sccp_called_gt = -1;
647 static gint ett_sccp_calling = -1;
648 static gint ett_sccp_calling_ai = -1;
649 static gint ett_sccp_calling_pc = -1;
650 static gint ett_sccp_calling_gt = -1;
651 static gint ett_sccp_sequencing_segmenting = -1;
652 static gint ett_sccp_segmentation = -1;
653 static gint ett_sccp_ansi_isni_routing_control = -1;
656 * Here are the global variables associated with
657 * the various user definable characteristics of the dissection
659 static guint32 sccp_source_pc_global = 0;
660 static gboolean sccp_show_length = FALSE;
662 static module_t *sccp_module;
663 static heur_dissector_list_t heur_subdissector_list;
665 /* Keep track of SSN value of current message so if/when we get to the data
666 * parameter, we can call appropriate sub-dissector. TODO: can this info
667 * be stored elsewhere?
669 static guint8 called_ssn = INVALID_SSN;
670 static guint8 calling_ssn = INVALID_SSN;
672 static dissector_handle_t data_handle;
673 static dissector_table_t sccp_ssn_dissector_table;
676 dissect_sccp_unknown_message(tvbuff_t *message_tvb, proto_tree *sccp_tree)
678 guint32 message_length;
680 message_length = tvb_length(message_tvb);
682 proto_tree_add_text(sccp_tree, message_tvb, 0, message_length,
683 "Unknown message (%u byte%s)",
684 message_length, plurality(message_length, "", "s"));
688 dissect_sccp_unknown_param(tvbuff_t *tvb, proto_tree *tree, guint8 type, guint length)
690 proto_tree_add_text(tree, tvb, 0, length, "Unknown parameter 0x%x (%u byte%s)",
691 type, length, plurality(length, "", "s"));
695 dissect_sccp_dlr_param(tvbuff_t *tvb, proto_tree *tree, guint length)
699 reference = tvb_get_letoh24(tvb, 0);
700 proto_tree_add_uint(tree, hf_sccp_dlr, tvb, 0, length, reference);
704 dissect_sccp_slr_param(tvbuff_t *tvb, proto_tree *tree, guint length)
708 reference = tvb_get_letoh24(tvb, 0);
709 proto_tree_add_uint(tree, hf_sccp_slr, tvb, 0, length, reference);
713 dissect_sccp_gt_address_information(tvbuff_t *tvb, proto_tree *tree,
714 guint length, gboolean even_length,
718 guint8 odd_signal, even_signal = 0x0f;
719 char gt_digits[GT_MAX_SIGNALS] = { 0 };
721 while(offset < length)
723 odd_signal = tvb_get_guint8(tvb, offset) & GT_ODD_SIGNAL_MASK;
724 even_signal = tvb_get_guint8(tvb, offset) & GT_EVEN_SIGNAL_MASK;
725 even_signal >>= GT_EVEN_SIGNAL_SHIFT;
727 strcat(gt_digits, val_to_str(odd_signal, sccp_address_signal_values,
730 /* If the last signal is NOT filler */
731 if (offset != (length - 1) || even_length == TRUE)
732 strcat(gt_digits, val_to_str(even_signal, sccp_address_signal_values,
735 offset += GT_SIGNAL_LENGTH;
738 proto_tree_add_string_format(tree, called ? hf_sccp_called_gt_digits
739 : hf_sccp_calling_gt_digits,
742 "Address information (digits): %s", gt_digits);
743 proto_tree_add_string_hidden(tree, called ? hf_sccp_gt_digits
750 dissect_sccp_global_title(tvbuff_t *tvb, proto_tree *tree, guint length,
751 guint8 gti, gboolean called)
753 proto_item *gt_item = 0;
754 proto_tree *gt_tree = 0;
755 tvbuff_t *signals_tvb;
757 guint8 odd_even, nai, tt, np, es;
758 gboolean even = TRUE;
760 /* Shift GTI to where we can work with it */
763 gt_item = proto_tree_add_text(tree, tvb, offset, length,
764 "Global Title 0x%x (%u byte%s)",
765 gti, length, plurality(length,"", "s"));
766 gt_tree = proto_item_add_subtree(gt_item, called ? ett_sccp_called_gt
767 : ett_sccp_calling_gt);
769 /* Decode Transation Type (if present) */
773 /* Protocol doesn't tell us, so we ASSUME even... */
776 case ITU_AI_GTI_TT_NP_ES:
777 case ITU_AI_GTI_TT_NP_ES_NAI:
778 case ANSI_AI_GTI_TT_NP_ES:
780 tt = tvb_get_guint8(tvb, offset);
781 proto_tree_add_uint(gt_tree, called ? hf_sccp_called_gt_tt
782 : hf_sccp_calling_gt_tt,
783 tvb, offset, GT_TT_LENGTH, tt);
784 offset += GT_TT_LENGTH;
787 /* Decode Numbering Plan and Encoding Scheme (if present) */
789 case ITU_AI_GTI_TT_NP_ES:
790 case ITU_AI_GTI_TT_NP_ES_NAI:
791 case ANSI_AI_GTI_TT_NP_ES:
793 np = tvb_get_guint8(tvb, offset) & GT_NP_MASK;
794 proto_tree_add_uint(gt_tree, called ? hf_sccp_called_gt_np
795 : hf_sccp_calling_gt_np,
796 tvb, offset, GT_NP_ES_LENGTH, np);
798 es = tvb_get_guint8(tvb, offset) & GT_ES_MASK;
799 proto_tree_add_uint(gt_tree, called ? hf_sccp_called_gt_es
800 : hf_sccp_calling_gt_es,
801 tvb, offset, GT_NP_ES_LENGTH, es);
803 even = (es == GT_ES_BCD_EVEN) ? TRUE : FALSE;
805 offset += GT_NP_ES_LENGTH;
808 /* Decode Odd/Even Indicator (if present) */
809 if (gti == ITU_AI_GTI_NAI) {
810 odd_even = tvb_get_guint8(tvb, offset) & GT_OE_MASK;
811 proto_tree_add_uint(gt_tree, called ? hf_sccp_called_gt_oe
812 : hf_sccp_calling_gt_oe,
813 tvb, offset, GT_NAI_LENGTH, odd_even);
814 even = (odd_even == GT_OE_EVEN) ? TRUE : FALSE;
816 /* offset doesn't change */
819 /* Decode Nature of Address Indicator (if present) */
822 case ITU_AI_GTI_TT_NP_ES_NAI:
823 nai = tvb_get_guint8(tvb, offset) & GT_NAI_MASK;
824 proto_tree_add_uint(gt_tree, called ? hf_sccp_called_gt_nai
825 : hf_sccp_calling_gt_nai,
826 tvb, offset, GT_NAI_LENGTH, nai);
828 offset += GT_NAI_LENGTH;
831 /* Decode address signal(s) */
834 signals_tvb = tvb_new_subset(tvb, offset, (length - offset),
836 dissect_sccp_gt_address_information(signals_tvb, gt_tree, (length - offset),
842 dissect_sccp_3byte_pc(tvbuff_t *tvb, proto_tree *call_tree, guint offset,
846 proto_item *call_pc_item = 0;
847 proto_tree *call_pc_tree = 0;
848 char pc[ANSI_PC_STRING_LENGTH];
851 if (mtp3_standard == ANSI_STANDARD)
854 hf_pc = &hf_sccp_called_ansi_pc;
856 hf_pc = &hf_sccp_calling_ansi_pc;
857 } else /* CHINESE_ITU_STANDARD */ {
859 hf_pc = &hf_sccp_called_chinese_pc;
861 hf_pc = &hf_sccp_calling_chinese_pc;
864 /* create the DPC tree; modified from that in packet-mtp3.c */
865 dpc = tvb_get_ntoh24(tvb, offset);
866 snprintf(pc, sizeof(pc), "%d-%d-%d", (dpc & ANSI_NETWORK_MASK),
867 ((dpc & ANSI_CLUSTER_MASK) >> 8),
868 ((dpc & ANSI_MEMBER_MASK) >> 16));
870 call_pc_item = proto_tree_add_string_format(call_tree, *hf_pc,
871 tvb, offset, ANSI_PC_LENGTH,
874 call_pc_tree = proto_item_add_subtree(call_pc_item,
875 called ? ett_sccp_called_pc
876 : ett_sccp_calling_pc);
878 proto_tree_add_uint(call_pc_tree, called ? hf_sccp_called_pc_member
879 : hf_sccp_calling_pc_member,
880 tvb, offset, ANSI_NCM_LENGTH, dpc);
881 offset += ANSI_NCM_LENGTH;
882 proto_tree_add_uint(call_pc_tree, called ? hf_sccp_called_pc_cluster
883 : hf_sccp_calling_pc_cluster,
884 tvb, offset, ANSI_NCM_LENGTH, dpc);
885 offset += ANSI_NCM_LENGTH;
886 proto_tree_add_uint(call_pc_tree, called ? hf_sccp_called_pc_network
887 : hf_sccp_calling_pc_network,
888 tvb, offset, ANSI_NCM_LENGTH, dpc);
889 offset += ANSI_NCM_LENGTH;
894 /* FUNCTION dissect_sccp_called_calling_param():
895 * Dissect the Calling or Called Party Address parameters.
897 * The boolean 'called' describes whether this function is decoding a
898 * called (TRUE) or calling (FALSE) party address. There is simply too
899 * much code in this function to have 2 copies of it (one for called, one
902 * NOTE: this function is called even when (!tree) so that we can get
903 * the SSN and subsequently call subdissectors (if and when there's a data
904 * parameter). Realistically we should put if (!tree)'s around a lot of the
905 * code, but I think that would make it unreadable--and the expense of not
906 * doing so does not appear to be very high.
909 dissect_sccp_called_calling_param(tvbuff_t *tvb, proto_tree *tree,
910 guint length, gboolean called)
912 proto_item *call_item = 0, *call_ai_item = 0;
913 proto_tree *call_tree = 0, *call_ai_tree = 0;
915 guint8 national = -1, routing_ind, gti, pci, ssni, ssn;
919 call_item = proto_tree_add_text(tree, tvb, 0, length,
920 "%s Party address (%u byte%s)",
921 called ? "Called" : "Calling", length,
922 plurality(length, "", "s"));
923 call_tree = proto_item_add_subtree(call_item, called ? ett_sccp_called
926 call_ai_item = proto_tree_add_text(call_tree, tvb, 0,
927 ADDRESS_INDICATOR_LENGTH,
928 "Address Indicator");
929 call_ai_tree = proto_item_add_subtree(call_ai_item, called ? ett_sccp_called_ai
930 : ett_sccp_calling_ai);
932 if (mtp3_standard == ANSI_STANDARD)
934 national = tvb_get_guint8(tvb, 0) & ANSI_NATIONAL_MASK;
935 proto_tree_add_uint(call_ai_tree, called ? hf_sccp_called_national_indicator
936 : hf_sccp_calling_national_indicator,
937 tvb, 0, ADDRESS_INDICATOR_LENGTH, national);
940 routing_ind = tvb_get_guint8(tvb, 0) & ROUTING_INDICATOR_MASK;
941 proto_tree_add_uint(call_ai_tree, called ? hf_sccp_called_routing_indicator
942 : hf_sccp_calling_routing_indicator,
943 tvb, 0, ADDRESS_INDICATOR_LENGTH, routing_ind);
945 gti = tvb_get_guint8(tvb, 0) & GTI_MASK;
947 if (mtp3_standard == ITU_STANDARD ||
948 mtp3_standard == CHINESE_ITU_STANDARD ||
951 proto_tree_add_uint(call_ai_tree, called ? hf_sccp_called_itu_global_title_indicator
952 : hf_sccp_called_itu_global_title_indicator,
953 tvb, 0, ADDRESS_INDICATOR_LENGTH, gti);
955 ssni = tvb_get_guint8(tvb, 0) & ITU_SSN_INDICATOR_MASK;
956 proto_tree_add_uint(call_ai_tree, called ? hf_sccp_called_itu_ssn_indicator
957 : hf_sccp_calling_itu_ssn_indicator,
958 tvb, 0, ADDRESS_INDICATOR_LENGTH, ssni);
960 pci = tvb_get_guint8(tvb, 0) & ITU_PC_INDICATOR_MASK;
961 proto_tree_add_uint(call_ai_tree, called ? hf_sccp_called_itu_point_code_indicator
962 : hf_sccp_calling_itu_point_code_indicator,
963 tvb, 0, ADDRESS_INDICATOR_LENGTH, pci);
965 offset = ADDRESS_INDICATOR_LENGTH;
967 /* Dissect PC (if present) */
969 if (mtp3_standard == ITU_STANDARD)
972 dpc = tvb_get_letohs(tvb, offset) & ITU_PC_MASK;
973 proto_tree_add_uint(call_tree, called ? hf_sccp_called_itu_pc
974 : hf_sccp_calling_itu_pc,
975 tvb, offset, ITU_PC_LENGTH, dpc);
976 offset += ITU_PC_LENGTH;
978 } else /* CHINESE_ITU_STANDARD */ {
980 offset = dissect_sccp_3byte_pc(tvb, call_tree, offset, called);
985 /* Dissect SSN (if present) */
987 ssn = tvb_get_guint8(tvb, offset);
995 proto_tree_add_uint(call_tree, called ? hf_sccp_called_ssn
996 : hf_sccp_calling_ssn,
997 tvb, offset, ADDRESS_SSN_LENGTH, ssn);
998 proto_tree_add_uint_hidden(call_tree, hf_sccp_ssn, tvb, offset,
999 ADDRESS_SSN_LENGTH, ssn);
1000 offset += ADDRESS_SSN_LENGTH;
1004 return; /* got SSN, that's all we need here... */
1006 /* Dissect GT (if present) */
1007 if (gti != AI_GTI_NO_GT) {
1008 if (length < offset)
1010 gt_tvb = tvb_new_subset(tvb, offset, (length - offset),
1012 dissect_sccp_global_title(gt_tvb, call_tree, (length - offset), gti,
1016 } else if (mtp3_standard == ANSI_STANDARD) {
1018 proto_tree_add_uint(call_ai_tree, called ? hf_sccp_called_ansi_global_title_indicator
1019 : hf_sccp_calling_ansi_global_title_indicator,
1020 tvb, 0, ADDRESS_INDICATOR_LENGTH, gti);
1022 pci = tvb_get_guint8(tvb, 0) & ANSI_PC_INDICATOR_MASK;
1023 proto_tree_add_uint(call_ai_tree, called ? hf_sccp_called_ansi_point_code_indicator
1024 : hf_sccp_calling_ansi_point_code_indicator,
1025 tvb, 0, ADDRESS_INDICATOR_LENGTH, pci);
1027 ssni = tvb_get_guint8(tvb, 0) & ANSI_SSN_INDICATOR_MASK;
1028 proto_tree_add_uint(call_ai_tree, called ? hf_sccp_called_ansi_ssn_indicator
1029 : hf_sccp_calling_ansi_ssn_indicator,
1030 tvb, 0, ADDRESS_INDICATOR_LENGTH, ssni);
1032 offset = ADDRESS_INDICATOR_LENGTH;
1034 /* Dissect SSN (if present) */
1036 ssn = tvb_get_guint8(tvb, offset);
1044 proto_tree_add_uint(call_tree, called ? hf_sccp_called_ssn
1045 : hf_sccp_calling_ssn,
1046 tvb, offset, ADDRESS_SSN_LENGTH, ssn);
1047 proto_tree_add_uint_hidden(call_tree, hf_sccp_ssn, tvb, offset,
1048 ADDRESS_SSN_LENGTH, ssn);
1049 offset += ADDRESS_SSN_LENGTH;
1053 return; /* got SSN, that's all we need here... */
1055 /* Dissect PC (if present) */
1057 offset = dissect_sccp_3byte_pc(tvb, call_tree, offset, called);
1060 /* Dissect GT (if present) */
1061 if (gti != AI_GTI_NO_GT) {
1062 if (length < offset)
1064 gt_tvb = tvb_new_subset(tvb, offset, (length - offset),
1066 dissect_sccp_global_title(gt_tvb, call_tree, (length - offset), gti,
1075 dissect_sccp_called_param(tvbuff_t *tvb, proto_tree *tree, guint length)
1077 dissect_sccp_called_calling_param(tvb, tree, length, TRUE);
1081 dissect_sccp_calling_param(tvbuff_t *tvb, proto_tree *tree, guint length)
1083 dissect_sccp_called_calling_param(tvb, tree, length, FALSE);
1087 dissect_sccp_class_param(tvbuff_t *tvb, proto_tree *tree, guint length)
1089 guint8 class, handling;
1091 class = tvb_get_guint8(tvb, 0) & CLASS_CLASS_MASK;
1092 handling = tvb_get_guint8(tvb, 0) & CLASS_SPARE_HANDLING_MASK;
1094 proto_tree_add_uint(tree, hf_sccp_class, tvb, 0, length, class);
1096 if (class == 0 || class == 1)
1097 proto_tree_add_uint(tree, hf_sccp_handling, tvb, 0, length, handling);
1101 dissect_sccp_segmenting_reassembling_param(tvbuff_t *tvb, proto_tree *tree, guint length)
1105 more = tvb_get_guint8(tvb, 0) & SEGMENTING_REASSEMBLING_MASK;
1106 proto_tree_add_uint(tree, hf_sccp_more, tvb, 0, length, more);
1110 dissect_sccp_receive_sequence_number_param(tvbuff_t *tvb, proto_tree *tree, guint length)
1114 rsn = tvb_get_guint8(tvb, 0) >> 1;
1115 proto_tree_add_uint(tree, hf_sccp_rsn, tvb, 0, length, rsn);
1119 dissect_sccp_sequencing_segmenting_param(tvbuff_t *tvb, proto_tree *tree, guint length)
1121 guint8 rsn, ssn, more;
1122 proto_item *param_item;
1123 proto_tree *param_tree;
1125 ssn = tvb_get_guint8(tvb, 0) >> 1;
1126 rsn = tvb_get_guint8(tvb, SEQUENCING_SEGMENTING_SSN_LENGTH) >> 1;
1127 more = tvb_get_guint8(tvb, SEQUENCING_SEGMENTING_SSN_LENGTH) & SEQUENCING_SEGMENTING_MORE_MASK;
1129 param_item = proto_tree_add_text(tree, tvb, 0, length,
1130 val_to_str(PARAMETER_SEQUENCING_SEGMENTING,
1131 sccp_parameter_values, "Unknown"));
1132 param_tree = proto_item_add_subtree(param_item,
1133 ett_sccp_sequencing_segmenting);
1135 proto_tree_add_uint(param_tree, hf_sccp_sequencing_segmenting_ssn, tvb, 0,
1136 SEQUENCING_SEGMENTING_SSN_LENGTH, ssn);
1137 proto_tree_add_uint(param_tree, hf_sccp_sequencing_segmenting_rsn, tvb,
1138 SEQUENCING_SEGMENTING_SSN_LENGTH,
1139 SEQUENCING_SEGMENTING_RSN_LENGTH, rsn);
1140 proto_tree_add_uint(param_tree, hf_sccp_sequencing_segmenting_more, tvb,
1141 SEQUENCING_SEGMENTING_SSN_LENGTH,
1142 SEQUENCING_SEGMENTING_RSN_LENGTH, more);
1146 dissect_sccp_credit_param(tvbuff_t *tvb, proto_tree *tree, guint length)
1150 credit = tvb_get_guint8(tvb, 0);
1151 proto_tree_add_uint(tree, hf_sccp_credit, tvb, 0, length, credit);
1155 dissect_sccp_release_cause_param(tvbuff_t *tvb, proto_tree *tree, guint length)
1159 cause = tvb_get_guint8(tvb, 0);
1160 proto_tree_add_uint(tree, hf_sccp_release_cause, tvb, 0, length, cause);
1164 dissect_sccp_return_cause_param(tvbuff_t *tvb, proto_tree *tree, guint length)
1168 cause = tvb_get_guint8(tvb, 0);
1169 proto_tree_add_uint(tree, hf_sccp_return_cause, tvb, 0, length, cause);
1173 dissect_sccp_reset_cause_param(tvbuff_t *tvb, proto_tree *tree, guint length)
1177 cause = tvb_get_guint8(tvb, 0);
1178 proto_tree_add_uint(tree, hf_sccp_reset_cause, tvb, 0, length, cause);
1182 dissect_sccp_error_cause_param(tvbuff_t *tvb, proto_tree *tree, guint length)
1186 cause = tvb_get_guint8(tvb, 0);
1187 proto_tree_add_uint(tree, hf_sccp_error_cause, tvb, 0, length, cause);
1191 dissect_sccp_refusal_cause_param(tvbuff_t *tvb, proto_tree *tree, guint length)
1195 cause = tvb_get_guint8(tvb, 0);
1196 proto_tree_add_uint(tree, hf_sccp_refusal_cause, tvb, 0, length, cause);
1199 /* This function is used for both data and long data (ITU only) parameters */
1201 dissect_sccp_data_param(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
1204 /* Try subdissectors (if we found a valid SSN on the current message) */
1205 if ((called_ssn != INVALID_SSN &&
1206 dissector_try_port(sccp_ssn_dissector_table, called_ssn, tvb, pinfo,
1208 (calling_ssn != INVALID_SSN &&
1209 dissector_try_port(sccp_ssn_dissector_table, calling_ssn, tvb, pinfo,
1213 /* try heuristic subdissector list to see if there are any takers */
1214 if (dissector_try_heuristic(heur_subdissector_list, tvb, pinfo, tree))
1219 /* No sub-dissection occured, treat it as raw data */
1220 call_dissector(data_handle, tvb, pinfo, tree);
1224 dissect_sccp_segmentation_param(tvbuff_t *tvb, proto_tree *tree, guint length)
1226 guint8 first, class, remaining;
1228 proto_item *param_item;
1229 proto_tree *param_tree;
1231 first = tvb_get_guint8(tvb, 0) & SEGMENTATION_FIRST_SEGMENT_MASK;
1232 class = tvb_get_guint8(tvb, 0) & SEGMENTATION_CLASS_MASK;
1233 remaining = tvb_get_guint8(tvb, 0) & SEGMENTATION_REMAINING_MASK;
1235 slr = tvb_get_letoh24(tvb, 1);
1237 param_item = proto_tree_add_text(tree, tvb, 0, length,
1238 val_to_str(PARAMETER_SEGMENTATION,
1239 sccp_parameter_values, "Unknown"));
1240 param_tree = proto_item_add_subtree(param_item, ett_sccp_segmentation);
1242 proto_tree_add_uint(param_tree, hf_sccp_segmentation_first, tvb, 0, length,
1244 proto_tree_add_uint(param_tree, hf_sccp_segmentation_class, tvb, 0, length,
1246 proto_tree_add_uint(param_tree, hf_sccp_segmentation_remaining, tvb, 0,
1248 proto_tree_add_uint(param_tree, hf_sccp_segmentation_slr, tvb, 1, length,
1253 dissect_sccp_hop_counter_param(tvbuff_t *tvb, proto_tree *tree, guint length)
1257 hops = tvb_get_guint8(tvb, 0);
1258 proto_tree_add_uint(tree, hf_sccp_hop_counter, tvb, 0, length, hops);
1262 dissect_sccp_importance_param(tvbuff_t *tvb, proto_tree *tree, guint length)
1266 importance = tvb_get_guint8(tvb, 0) & IMPORTANCE_IMPORTANCE_MASK;
1267 proto_tree_add_uint(tree, hf_sccp_importance, tvb, 0, length, importance);
1271 dissect_sccp_isni_param(tvbuff_t *tvb, proto_tree *tree, guint length)
1273 guint8 mi, iri, ti, network, netspec;
1275 proto_item *param_item;
1276 proto_tree *param_tree;
1278 /* Create a subtree for ISNI Routing Control */
1279 param_item = proto_tree_add_text(tree, tvb, offset, ANSI_ISNI_ROUTING_CONTROL_LENGTH,
1280 "ISNI Routing Control");
1281 param_tree = proto_item_add_subtree(param_item,
1282 ett_sccp_ansi_isni_routing_control);
1284 mi = tvb_get_guint8(tvb, offset) & ANSI_ISNI_MI_MASK;
1285 proto_tree_add_uint(param_tree, hf_sccp_ansi_isni_mi, tvb, offset,
1286 ANSI_ISNI_ROUTING_CONTROL_LENGTH, mi);
1288 iri = tvb_get_guint8(tvb, offset) & ANSI_ISNI_IRI_MASK;
1289 proto_tree_add_uint(param_tree, hf_sccp_ansi_isni_iri, tvb, offset,
1290 ANSI_ISNI_ROUTING_CONTROL_LENGTH, iri);
1292 ti = tvb_get_guint8(tvb, offset) & ANSI_ISNI_TI_MASK;
1293 proto_tree_add_uint(param_tree, hf_sccp_ansi_isni_ti, tvb, offset,
1294 ANSI_ISNI_ROUTING_CONTROL_LENGTH, ti);
1296 offset += ANSI_ISNI_ROUTING_CONTROL_LENGTH;
1298 if ((ti >> ANSI_ISNI_TI_SHIFT) == ANSI_ISNI_TYPE_1) {
1299 netspec = tvb_get_guint8(tvb, offset) & ANSI_ISNI_NETSPEC_MASK;
1300 proto_tree_add_uint(param_tree, hf_sccp_ansi_isni_netspec, tvb, offset,
1301 ANSI_ISNI_ROUTING_CONTROL_LENGTH, ti);
1302 offset += ANSI_ISNI_ROUTING_CONTROL_LENGTH;
1305 while (offset < length) {
1307 network = tvb_get_guint8(tvb, offset);
1308 proto_tree_add_text(tree, tvb, offset, ANSI_NCM_LENGTH,
1309 "Network ID network: %d", network);
1312 network = tvb_get_guint8(tvb, offset);
1313 proto_tree_add_text(tree, tvb, offset, ANSI_NCM_LENGTH,
1314 "Network ID cluster: %d", network);
1320 /* FUNCTION dissect_sccp_parameter():
1321 * Dissect a parameter given its type, offset into tvb, and length.
1324 dissect_sccp_parameter(tvbuff_t *tvb, packet_info *pinfo, proto_tree *sccp_tree,
1325 proto_tree *tree, guint8 parameter_type, guint16 offset,
1326 guint16 parameter_length)
1328 tvbuff_t *parameter_tvb;
1330 switch (parameter_type) {
1331 case PARAMETER_CALLED_PARTY_ADDRESS:
1332 case PARAMETER_CALLING_PARTY_ADDRESS:
1333 case PARAMETER_DATA:
1334 case PARAMETER_LONG_DATA:
1335 /* These parameters must be dissected even if !sccp_tree (so that
1336 * subdissectors can be called).
1342 return(parameter_length);
1346 parameter_tvb = tvb_new_subset(tvb, offset, parameter_length, parameter_length);
1348 switch (parameter_type) {
1350 case PARAMETER_END_OF_OPTIONAL_PARAMETERS:
1351 proto_tree_add_text(sccp_tree, tvb, offset, parameter_length,
1355 case PARAMETER_DESTINATION_LOCAL_REFERENCE:
1356 dissect_sccp_dlr_param(parameter_tvb, sccp_tree, parameter_length);
1359 case PARAMETER_SOURCE_LOCAL_REFERENCE:
1360 dissect_sccp_slr_param(parameter_tvb, sccp_tree, parameter_length);
1363 case PARAMETER_CALLED_PARTY_ADDRESS:
1364 dissect_sccp_called_param(parameter_tvb, sccp_tree, parameter_length);
1367 case PARAMETER_CALLING_PARTY_ADDRESS:
1368 dissect_sccp_calling_param(parameter_tvb, sccp_tree, parameter_length);
1371 case PARAMETER_CLASS:
1372 dissect_sccp_class_param(parameter_tvb, sccp_tree, parameter_length);
1375 case PARAMETER_SEGMENTING_REASSEMBLING:
1376 dissect_sccp_segmenting_reassembling_param(parameter_tvb, sccp_tree,
1380 case PARAMETER_RECEIVE_SEQUENCE_NUMBER:
1381 dissect_sccp_receive_sequence_number_param(parameter_tvb, sccp_tree,
1385 case PARAMETER_SEQUENCING_SEGMENTING:
1386 dissect_sccp_sequencing_segmenting_param(parameter_tvb, sccp_tree,
1390 case PARAMETER_CREDIT:
1391 dissect_sccp_credit_param(parameter_tvb, sccp_tree, parameter_length);
1394 case PARAMETER_RELEASE_CAUSE:
1395 dissect_sccp_release_cause_param(parameter_tvb, sccp_tree, parameter_length);
1398 case PARAMETER_RETURN_CAUSE:
1399 dissect_sccp_return_cause_param(parameter_tvb, sccp_tree, parameter_length);
1402 case PARAMETER_RESET_CAUSE:
1403 dissect_sccp_reset_cause_param(parameter_tvb, sccp_tree, parameter_length);
1406 case PARAMETER_ERROR_CAUSE:
1407 dissect_sccp_error_cause_param(parameter_tvb, sccp_tree, parameter_length);
1410 case PARAMETER_REFUSAL_CAUSE:
1411 dissect_sccp_refusal_cause_param(parameter_tvb, sccp_tree, parameter_length);
1414 case PARAMETER_DATA:
1415 dissect_sccp_data_param(parameter_tvb, pinfo, tree);
1417 /* TODO? Re-adjust length of SCCP item since it may be sub-dissected */
1418 /* sccp_length = proto_item_get_len(sccp_item);
1419 * sccp_length -= parameter_length;
1420 * proto_item_set_len(sccp_item, sccp_length);
1424 case PARAMETER_SEGMENTATION:
1425 dissect_sccp_segmentation_param(parameter_tvb, sccp_tree, parameter_length);
1428 case PARAMETER_HOP_COUNTER:
1429 dissect_sccp_hop_counter_param(parameter_tvb, sccp_tree, parameter_length);
1432 case PARAMETER_IMPORTANCE:
1433 if (mtp3_standard != ANSI_STANDARD)
1434 dissect_sccp_importance_param(parameter_tvb, sccp_tree, parameter_length);
1436 dissect_sccp_unknown_param(parameter_tvb, sccp_tree, parameter_type,
1440 case PARAMETER_LONG_DATA:
1441 if (mtp3_standard != ANSI_STANDARD)
1442 dissect_sccp_data_param(parameter_tvb, pinfo, tree);
1444 dissect_sccp_unknown_param(parameter_tvb, sccp_tree, parameter_type,
1448 case PARAMETER_ISNI:
1449 if (mtp3_standard != ANSI_STANDARD)
1450 dissect_sccp_unknown_param(parameter_tvb, sccp_tree, parameter_type,
1453 dissect_sccp_isni_param(parameter_tvb, sccp_tree, parameter_length);
1457 dissect_sccp_unknown_param(parameter_tvb, sccp_tree, parameter_type,
1462 return(parameter_length);
1465 /* FUNCTION dissect_sccp_variable_parameter():
1466 * Dissect a variable parameter given its type and offset into tvb. Length
1467 * of the parameter is gotten from tvb[0].
1468 * Length returned is sum of (length + parameter).
1471 dissect_sccp_variable_parameter(tvbuff_t *tvb, packet_info *pinfo,
1472 proto_tree *sccp_tree, proto_tree *tree,
1473 guint8 parameter_type, guint16 offset)
1475 guint16 parameter_length;
1476 guint8 length_length;
1478 if (parameter_type != PARAMETER_LONG_DATA)
1480 parameter_length = tvb_get_guint8(tvb, offset);
1481 length_length = PARAMETER_LENGTH_LENGTH;
1485 /* Long data parameter has 16 bit length */
1486 parameter_length = tvb_get_letohs(tvb, offset);
1487 length_length = PARAMETER_LONG_DATA_LENGTH_LENGTH;
1493 proto_tree_add_text(sccp_tree, tvb, offset, length_length,
1495 val_to_str(parameter_type, sccp_parameter_values,
1500 offset += length_length;
1502 dissect_sccp_parameter(tvb, pinfo, sccp_tree, tree, parameter_type, offset,
1505 return(parameter_length + length_length);
1508 /* FUNCTION dissect_sccp_optional_parameters():
1509 * Dissect all the optional parameters given the start of the optional
1510 * parameters into tvb. Parameter types and lengths are read from tvb.
1513 dissect_sccp_optional_parameters(tvbuff_t *tvb, packet_info *pinfo,
1514 proto_tree *sccp_tree, proto_tree *tree,
1517 guint8 parameter_type;
1519 while ((parameter_type = tvb_get_guint8(tvb, offset)) !=
1520 PARAMETER_END_OF_OPTIONAL_PARAMETERS) {
1522 offset += PARAMETER_TYPE_LENGTH;
1523 offset += dissect_sccp_variable_parameter(tvb, pinfo, sccp_tree, tree,
1524 parameter_type, offset);
1527 /* Process end of optional parameters */
1528 dissect_sccp_parameter(tvb, pinfo, sccp_tree, tree, parameter_type, offset,
1529 END_OF_OPTIONAL_PARAMETERS_LENGTH);
1535 dissect_sccp_message(tvbuff_t *tvb, packet_info *pinfo, proto_tree *sccp_tree,
1538 guint8 message_type;
1539 guint16 variable_pointer1 = 0, variable_pointer2 = 0, variable_pointer3 = 0;
1540 guint16 optional_pointer = 0;
1543 /* Macro for getting pointer to mandatory variable parameters */
1544 #define VARIABLE_POINTER(var, hf_var, ptr_size) \
1545 if (ptr_size == POINTER_LENGTH) \
1546 var = tvb_get_guint8(tvb, offset); \
1548 var = tvb_get_letohs(tvb, offset); \
1549 proto_tree_add_uint(sccp_tree, hf_var, tvb, \
1550 offset, ptr_size, var); \
1552 if (ptr_size == POINTER_LENGTH_LONG) \
1556 /* Macro for getting pointer to optional parameters */
1557 #define OPTIONAL_POINTER(ptr_size) \
1558 if (ptr_size == POINTER_LENGTH) \
1559 optional_pointer = tvb_get_guint8(tvb, offset); \
1561 optional_pointer = tvb_get_letohs(tvb, offset); \
1562 proto_tree_add_uint(sccp_tree, hf_sccp_optional_pointer, tvb, \
1563 offset, ptr_size, optional_pointer); \
1564 optional_pointer += offset; \
1565 if (ptr_size == POINTER_LENGTH_LONG) \
1566 optional_pointer += 1; \
1570 /* Extract the message type; all other processing is based on this */
1571 message_type = tvb_get_guint8(tvb, MESSAGE_TYPE_OFFSET);
1572 offset = MESSAGE_TYPE_LENGTH;
1574 if (check_col(pinfo->cinfo, COL_INFO))
1575 col_add_fstr(pinfo->cinfo, COL_INFO, "%s ",
1576 val_to_str(message_type, sccp_message_type_acro_values, "Unknown"));
1579 /* add the message type to the protocol tree */
1580 proto_tree_add_uint(sccp_tree, hf_sccp_message_type, tvb,
1581 MESSAGE_TYPE_OFFSET, MESSAGE_TYPE_LENGTH, message_type);
1585 /* Starting a new message dissection; clear the global SSN values */
1586 called_ssn = INVALID_SSN;
1587 calling_ssn = INVALID_SSN;
1589 switch(message_type) {
1590 case MESSAGE_TYPE_CR:
1591 offset += dissect_sccp_parameter(tvb, pinfo, sccp_tree, tree,
1592 PARAMETER_SOURCE_LOCAL_REFERENCE,
1593 offset, SOURCE_LOCAL_REFERENCE_LENGTH);
1594 offset += dissect_sccp_parameter(tvb, pinfo, sccp_tree, tree,
1595 PARAMETER_CLASS, offset,
1596 PROTOCOL_CLASS_LENGTH);
1598 VARIABLE_POINTER(variable_pointer1, hf_sccp_variable_pointer1, POINTER_LENGTH)
1599 OPTIONAL_POINTER(POINTER_LENGTH)
1601 dissect_sccp_variable_parameter(tvb, pinfo, sccp_tree, tree,
1602 PARAMETER_CALLED_PARTY_ADDRESS,
1606 case MESSAGE_TYPE_CC:
1607 /* TODO: connection has been established; theoretically we could keep
1608 * keep track of the SLR/DLR with the called/calling from the CR and
1609 * track the connection (e.g., on subsequent messages regarding this
1610 * SLR we could set the global vars "call*_ssn" so data could get
1613 offset += dissect_sccp_parameter(tvb, pinfo, sccp_tree, tree,
1614 PARAMETER_DESTINATION_LOCAL_REFERENCE,
1616 DESTINATION_LOCAL_REFERENCE_LENGTH);
1617 offset += dissect_sccp_parameter(tvb, pinfo, sccp_tree, tree,
1618 PARAMETER_SOURCE_LOCAL_REFERENCE,
1619 offset, SOURCE_LOCAL_REFERENCE_LENGTH);
1620 offset += dissect_sccp_parameter(tvb, pinfo, sccp_tree, tree,
1621 PARAMETER_CLASS, offset,
1622 PROTOCOL_CLASS_LENGTH);
1623 OPTIONAL_POINTER(POINTER_LENGTH)
1626 case MESSAGE_TYPE_CREF:
1627 offset += dissect_sccp_parameter(tvb, pinfo, sccp_tree, tree,
1628 PARAMETER_DESTINATION_LOCAL_REFERENCE,
1630 DESTINATION_LOCAL_REFERENCE_LENGTH);
1631 offset += dissect_sccp_parameter(tvb, pinfo, sccp_tree, tree,
1632 PARAMETER_REFUSAL_CAUSE, offset,
1633 REFUSAL_CAUSE_LENGTH);
1634 OPTIONAL_POINTER(POINTER_LENGTH)
1637 case MESSAGE_TYPE_RLSD:
1638 offset += dissect_sccp_parameter(tvb, pinfo, sccp_tree, tree,
1639 PARAMETER_DESTINATION_LOCAL_REFERENCE,
1641 DESTINATION_LOCAL_REFERENCE_LENGTH);
1642 offset += dissect_sccp_parameter(tvb, pinfo, sccp_tree, tree,
1643 PARAMETER_SOURCE_LOCAL_REFERENCE,
1644 offset, SOURCE_LOCAL_REFERENCE_LENGTH);
1645 offset += dissect_sccp_parameter(tvb, pinfo, sccp_tree, tree,
1646 PARAMETER_RELEASE_CAUSE, offset,
1647 RELEASE_CAUSE_LENGTH);
1649 OPTIONAL_POINTER(POINTER_LENGTH)
1652 case MESSAGE_TYPE_RLC:
1653 offset += dissect_sccp_parameter(tvb, pinfo, sccp_tree, tree,
1654 PARAMETER_DESTINATION_LOCAL_REFERENCE,
1656 DESTINATION_LOCAL_REFERENCE_LENGTH);
1657 offset += dissect_sccp_parameter(tvb, pinfo, sccp_tree, tree,
1658 PARAMETER_SOURCE_LOCAL_REFERENCE,
1659 offset, SOURCE_LOCAL_REFERENCE_LENGTH);
1662 case MESSAGE_TYPE_DT1:
1663 offset += dissect_sccp_parameter(tvb, pinfo, sccp_tree, tree,
1664 PARAMETER_DESTINATION_LOCAL_REFERENCE,
1666 DESTINATION_LOCAL_REFERENCE_LENGTH);
1667 offset += dissect_sccp_parameter(tvb, pinfo, sccp_tree, tree,
1668 PARAMETER_SEGMENTING_REASSEMBLING,
1669 offset, SEGMENTING_REASSEMBLING_LENGTH);
1671 VARIABLE_POINTER(variable_pointer1, hf_sccp_variable_pointer1, POINTER_LENGTH)
1672 dissect_sccp_variable_parameter(tvb, pinfo, sccp_tree, tree, PARAMETER_DATA,
1676 case MESSAGE_TYPE_DT2:
1677 offset += dissect_sccp_parameter(tvb, pinfo, sccp_tree, tree,
1678 PARAMETER_DESTINATION_LOCAL_REFERENCE,
1680 DESTINATION_LOCAL_REFERENCE_LENGTH);
1681 offset += dissect_sccp_parameter(tvb, pinfo, sccp_tree, tree,
1682 PARAMETER_SEQUENCING_SEGMENTING, offset,
1683 SEQUENCING_SEGMENTING_LENGTH);
1686 case MESSAGE_TYPE_AK:
1687 offset += dissect_sccp_parameter(tvb, pinfo, sccp_tree, tree,
1688 PARAMETER_DESTINATION_LOCAL_REFERENCE,
1690 DESTINATION_LOCAL_REFERENCE_LENGTH);
1691 offset += dissect_sccp_parameter(tvb, pinfo, sccp_tree, tree,
1692 PARAMETER_RECEIVE_SEQUENCE_NUMBER,
1693 offset, RECEIVE_SEQUENCE_NUMBER_LENGTH);
1694 offset += dissect_sccp_parameter(tvb, pinfo, sccp_tree, tree,
1695 PARAMETER_CREDIT, offset, CREDIT_LENGTH);
1698 case MESSAGE_TYPE_UDT:
1699 offset += dissect_sccp_parameter(tvb, pinfo, sccp_tree, tree,
1700 PARAMETER_CLASS, offset,
1701 PROTOCOL_CLASS_LENGTH);
1702 VARIABLE_POINTER(variable_pointer1, hf_sccp_variable_pointer1, POINTER_LENGTH)
1703 VARIABLE_POINTER(variable_pointer2, hf_sccp_variable_pointer2, POINTER_LENGTH)
1704 VARIABLE_POINTER(variable_pointer3, hf_sccp_variable_pointer3, POINTER_LENGTH)
1706 dissect_sccp_variable_parameter(tvb, pinfo, sccp_tree, tree,
1707 PARAMETER_CALLED_PARTY_ADDRESS,
1709 dissect_sccp_variable_parameter(tvb, pinfo, sccp_tree, tree,
1710 PARAMETER_CALLING_PARTY_ADDRESS,
1712 dissect_sccp_variable_parameter(tvb, pinfo, sccp_tree, tree, PARAMETER_DATA,
1716 case MESSAGE_TYPE_UDTS:
1717 offset += dissect_sccp_parameter(tvb, pinfo, sccp_tree, tree,
1718 PARAMETER_RETURN_CAUSE, offset,
1719 RETURN_CAUSE_LENGTH);
1721 VARIABLE_POINTER(variable_pointer1, hf_sccp_variable_pointer1, POINTER_LENGTH)
1722 VARIABLE_POINTER(variable_pointer2, hf_sccp_variable_pointer2, POINTER_LENGTH)
1723 VARIABLE_POINTER(variable_pointer3, hf_sccp_variable_pointer3, POINTER_LENGTH)
1725 dissect_sccp_variable_parameter(tvb, pinfo, sccp_tree, tree,
1726 PARAMETER_CALLED_PARTY_ADDRESS,
1729 dissect_sccp_variable_parameter(tvb, pinfo, sccp_tree, tree,
1730 PARAMETER_CALLING_PARTY_ADDRESS,
1733 dissect_sccp_variable_parameter(tvb, pinfo, sccp_tree, tree, PARAMETER_DATA,
1737 case MESSAGE_TYPE_ED:
1738 offset += dissect_sccp_parameter(tvb, pinfo, sccp_tree, tree,
1739 PARAMETER_DESTINATION_LOCAL_REFERENCE,
1741 DESTINATION_LOCAL_REFERENCE_LENGTH);
1743 VARIABLE_POINTER(variable_pointer1, hf_sccp_variable_pointer1, POINTER_LENGTH)
1744 dissect_sccp_variable_parameter(tvb, pinfo, sccp_tree, tree, PARAMETER_DATA,
1748 case MESSAGE_TYPE_EA:
1749 offset += dissect_sccp_parameter(tvb, pinfo, sccp_tree, tree,
1750 PARAMETER_DESTINATION_LOCAL_REFERENCE,
1752 DESTINATION_LOCAL_REFERENCE_LENGTH);
1755 case MESSAGE_TYPE_RSR:
1756 offset += dissect_sccp_parameter(tvb, pinfo, sccp_tree, tree,
1757 PARAMETER_DESTINATION_LOCAL_REFERENCE,
1759 DESTINATION_LOCAL_REFERENCE_LENGTH);
1760 offset += dissect_sccp_parameter(tvb, pinfo, sccp_tree, tree,
1761 PARAMETER_SOURCE_LOCAL_REFERENCE,
1762 offset, SOURCE_LOCAL_REFERENCE_LENGTH);
1763 offset += dissect_sccp_parameter(tvb, pinfo, sccp_tree, tree,
1764 PARAMETER_RESET_CAUSE, offset,
1765 RESET_CAUSE_LENGTH);
1768 case MESSAGE_TYPE_RSC:
1769 offset += dissect_sccp_parameter(tvb, pinfo, sccp_tree, tree,
1770 PARAMETER_DESTINATION_LOCAL_REFERENCE,
1772 DESTINATION_LOCAL_REFERENCE_LENGTH);
1773 offset += dissect_sccp_parameter(tvb, pinfo, sccp_tree, tree,
1774 PARAMETER_SOURCE_LOCAL_REFERENCE,
1775 offset, SOURCE_LOCAL_REFERENCE_LENGTH);
1778 case MESSAGE_TYPE_ERR:
1779 offset += dissect_sccp_parameter(tvb, pinfo, sccp_tree, tree,
1780 PARAMETER_DESTINATION_LOCAL_REFERENCE,
1782 DESTINATION_LOCAL_REFERENCE_LENGTH);
1783 offset += dissect_sccp_parameter(tvb, pinfo, sccp_tree, tree,
1784 PARAMETER_ERROR_CAUSE, offset,
1785 ERROR_CAUSE_LENGTH);
1788 case MESSAGE_TYPE_IT:
1789 offset += dissect_sccp_parameter(tvb, pinfo, sccp_tree, tree,
1790 PARAMETER_DESTINATION_LOCAL_REFERENCE,
1792 DESTINATION_LOCAL_REFERENCE_LENGTH);
1793 offset += dissect_sccp_parameter(tvb, pinfo, sccp_tree, tree,
1794 PARAMETER_SOURCE_LOCAL_REFERENCE,
1795 offset, SOURCE_LOCAL_REFERENCE_LENGTH);
1796 offset += dissect_sccp_parameter(tvb, pinfo, sccp_tree, tree,
1797 PARAMETER_CLASS, offset,
1798 PROTOCOL_CLASS_LENGTH);
1799 offset += dissect_sccp_parameter(tvb, pinfo, sccp_tree, tree,
1800 PARAMETER_SEQUENCING_SEGMENTING,
1801 offset, SEQUENCING_SEGMENTING_LENGTH);
1802 offset += dissect_sccp_parameter(tvb, pinfo, sccp_tree, tree,
1803 PARAMETER_CREDIT, offset, CREDIT_LENGTH);
1806 case MESSAGE_TYPE_XUDT:
1807 offset += dissect_sccp_parameter(tvb, pinfo, sccp_tree, tree,
1808 PARAMETER_CLASS, offset,
1809 PROTOCOL_CLASS_LENGTH);
1810 offset += dissect_sccp_parameter(tvb, pinfo, sccp_tree, tree,
1811 PARAMETER_HOP_COUNTER, offset,
1812 HOP_COUNTER_LENGTH);
1814 VARIABLE_POINTER(variable_pointer1, hf_sccp_variable_pointer1, POINTER_LENGTH)
1815 VARIABLE_POINTER(variable_pointer2, hf_sccp_variable_pointer2, POINTER_LENGTH)
1816 VARIABLE_POINTER(variable_pointer3, hf_sccp_variable_pointer3, POINTER_LENGTH)
1817 OPTIONAL_POINTER(POINTER_LENGTH)
1819 dissect_sccp_variable_parameter(tvb, pinfo, sccp_tree, tree,
1820 PARAMETER_CALLED_PARTY_ADDRESS,
1822 dissect_sccp_variable_parameter(tvb, pinfo, sccp_tree, tree,
1823 PARAMETER_CALLING_PARTY_ADDRESS,
1825 dissect_sccp_variable_parameter(tvb, pinfo, sccp_tree, tree, PARAMETER_DATA,
1829 case MESSAGE_TYPE_XUDTS:
1830 offset += dissect_sccp_parameter(tvb, pinfo, sccp_tree, tree,
1831 PARAMETER_RETURN_CAUSE, offset,
1832 RETURN_CAUSE_LENGTH);
1833 offset += dissect_sccp_parameter(tvb, pinfo, sccp_tree, tree,
1834 PARAMETER_HOP_COUNTER, offset,
1835 HOP_COUNTER_LENGTH);
1837 VARIABLE_POINTER(variable_pointer1, hf_sccp_variable_pointer1, POINTER_LENGTH)
1838 VARIABLE_POINTER(variable_pointer2, hf_sccp_variable_pointer2, POINTER_LENGTH)
1839 VARIABLE_POINTER(variable_pointer3, hf_sccp_variable_pointer3, POINTER_LENGTH)
1840 OPTIONAL_POINTER(POINTER_LENGTH)
1842 dissect_sccp_variable_parameter(tvb, pinfo, sccp_tree, tree,
1843 PARAMETER_CALLED_PARTY_ADDRESS,
1845 dissect_sccp_variable_parameter(tvb, pinfo, sccp_tree, tree,
1846 PARAMETER_CALLING_PARTY_ADDRESS,
1848 dissect_sccp_variable_parameter(tvb, pinfo, sccp_tree, tree, PARAMETER_DATA,
1852 case MESSAGE_TYPE_LUDT:
1853 if (mtp3_standard != ANSI_STANDARD)
1855 offset += dissect_sccp_parameter(tvb, pinfo, sccp_tree, tree,
1856 PARAMETER_CLASS, offset,
1857 PROTOCOL_CLASS_LENGTH);
1858 offset += dissect_sccp_parameter(tvb, pinfo, sccp_tree, tree,
1859 PARAMETER_HOP_COUNTER, offset,
1860 HOP_COUNTER_LENGTH);
1862 VARIABLE_POINTER(variable_pointer1, hf_sccp_variable_pointer1, POINTER_LENGTH_LONG)
1863 VARIABLE_POINTER(variable_pointer2, hf_sccp_variable_pointer2, POINTER_LENGTH_LONG)
1864 VARIABLE_POINTER(variable_pointer3, hf_sccp_variable_pointer3, POINTER_LENGTH_LONG)
1865 OPTIONAL_POINTER(POINTER_LENGTH_LONG)
1867 dissect_sccp_variable_parameter(tvb, pinfo, sccp_tree, tree,
1868 PARAMETER_CALLED_PARTY_ADDRESS,
1870 dissect_sccp_variable_parameter(tvb, pinfo, sccp_tree, tree,
1871 PARAMETER_CALLING_PARTY_ADDRESS,
1873 dissect_sccp_variable_parameter(tvb, pinfo, sccp_tree, tree,
1874 PARAMETER_LONG_DATA, variable_pointer3);
1876 dissect_sccp_unknown_message(tvb, sccp_tree);
1879 case MESSAGE_TYPE_LUDTS:
1880 if (mtp3_standard != ANSI_STANDARD)
1882 offset += dissect_sccp_parameter(tvb, pinfo, sccp_tree, tree,
1883 PARAMETER_RETURN_CAUSE, offset,
1884 RETURN_CAUSE_LENGTH);
1885 offset += dissect_sccp_parameter(tvb, pinfo, sccp_tree, tree,
1886 PARAMETER_HOP_COUNTER, offset,
1887 HOP_COUNTER_LENGTH);
1889 VARIABLE_POINTER(variable_pointer1, hf_sccp_variable_pointer1, POINTER_LENGTH_LONG)
1890 VARIABLE_POINTER(variable_pointer2, hf_sccp_variable_pointer2, POINTER_LENGTH_LONG)
1891 VARIABLE_POINTER(variable_pointer3, hf_sccp_variable_pointer3, POINTER_LENGTH_LONG)
1892 OPTIONAL_POINTER(POINTER_LENGTH_LONG)
1894 dissect_sccp_variable_parameter(tvb, pinfo, sccp_tree, tree,
1895 PARAMETER_CALLED_PARTY_ADDRESS,
1897 dissect_sccp_variable_parameter(tvb, pinfo, sccp_tree, tree,
1898 PARAMETER_CALLING_PARTY_ADDRESS,
1900 dissect_sccp_variable_parameter(tvb, pinfo, sccp_tree, tree,
1901 PARAMETER_LONG_DATA, variable_pointer3);
1903 dissect_sccp_unknown_message(tvb, sccp_tree);
1907 dissect_sccp_unknown_message(tvb, sccp_tree);
1910 if (optional_pointer)
1911 dissect_sccp_optional_parameters(tvb, pinfo, sccp_tree, tree,
1917 dissect_sccp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
1919 proto_item *sccp_item;
1920 proto_tree *sccp_tree = NULL;
1921 const mtp3_addr_pc_t *mtp3_addr_p;
1923 /* Make entry in the Protocol column on summary display */
1924 if (check_col(pinfo->cinfo, COL_PROTOCOL))
1925 switch(mtp3_standard) {
1927 col_set_str(pinfo->cinfo, COL_PROTOCOL, "SCCP (Int. ITU)");
1930 col_set_str(pinfo->cinfo, COL_PROTOCOL, "SCCP (ANSI)");
1932 case CHINESE_ITU_STANDARD:
1933 col_set_str(pinfo->cinfo, COL_PROTOCOL, "SCCP (Chin. ITU)");
1937 /* In the interest of speed, if "tree" is NULL, don't do any work not
1938 necessary to generate protocol tree items. */
1940 /* create the sccp protocol tree */
1941 sccp_item = proto_tree_add_item(tree, proto_sccp, tvb, 0, -1, FALSE);
1942 sccp_tree = proto_item_add_subtree(sccp_item, ett_sccp);
1945 /* Set whether message is UPLINK, DOWNLINK, or of UNKNOWN direction */
1947 if (pinfo->net_src.type == AT_SS7PC)
1950 * XXX - we assume that the "data" pointers of the source and destination
1951 * addresses are set to point to "mtp3_addr_pc_t" structures, so that
1952 * we can safely cast them.
1954 mtp3_addr_p = (const mtp3_addr_pc_t *)pinfo->net_src.data;
1956 if (sccp_source_pc_global == mtp3_addr_p->pc)
1958 pinfo->p2p_dir = P2P_DIR_SENT;
1962 /* assuming if net_src was SS7 PC then net_dst will be too */
1963 mtp3_addr_p = (const mtp3_addr_pc_t *)pinfo->net_dst.data;
1965 if (sccp_source_pc_global == mtp3_addr_p->pc)
1967 pinfo->p2p_dir = P2P_DIR_RECV;
1971 pinfo->p2p_dir = P2P_DIR_UNKNOWN;
1976 /* dissect the message */
1977 dissect_sccp_message(tvb, pinfo, sccp_tree, tree);
1980 /* Register the protocol with Ethereal */
1982 proto_register_sccp(void)
1984 /* Setup list of header fields */
1985 static hf_register_info hf[] = {
1986 { &hf_sccp_message_type,
1987 { "Message Type", "sccp.message_type",
1988 FT_UINT8, BASE_HEX, VALS(sccp_message_type_values), 0x0,
1990 { &hf_sccp_variable_pointer1,
1991 { "Pointer to first Mandatory Variable parameter", "sccp.variable_pointer1",
1992 FT_UINT16, BASE_DEC, NULL, 0x0,
1994 { &hf_sccp_variable_pointer2,
1995 { "Pointer to second Mandatory Variable parameter", "sccp.variable_pointer2",
1996 FT_UINT16, BASE_DEC, NULL, 0x0,
1998 { &hf_sccp_variable_pointer3,
1999 { "Pointer to third Mandatory Variable parameter", "sccp.variable_pointer3",
2000 FT_UINT16, BASE_DEC, NULL, 0x0,
2002 { &hf_sccp_optional_pointer,
2003 { "Pointer to Optional parameter", "sccp.optional_pointer",
2004 FT_UINT16, BASE_DEC, NULL, 0x0,
2007 { "Called or Calling SubSystem Number", "sccp.ssn",
2008 FT_UINT8, BASE_DEC, VALS(sccp_ssn_values), 0x0,
2010 { &hf_sccp_gt_digits,
2011 { "Called or Calling GT Digits",
2013 FT_STRING, BASE_NONE, NULL, 0x0,
2016 { &hf_sccp_called_national_indicator,
2017 { "National Indicator", "sccp.called.ni",
2018 FT_UINT8, BASE_HEX, VALS(sccp_national_indicator_values), ANSI_NATIONAL_MASK,
2020 { &hf_sccp_called_routing_indicator,
2021 { "Routing Indicator", "sccp.called.ri",
2022 FT_UINT8, BASE_HEX, VALS(sccp_routing_indicator_values), ROUTING_INDICATOR_MASK,
2024 { &hf_sccp_called_itu_global_title_indicator,
2025 { "Global Title Indicator", "sccp.called.gti",
2026 FT_UINT8, BASE_HEX, VALS(sccp_itu_global_title_indicator_values), GTI_MASK,
2028 { &hf_sccp_called_ansi_global_title_indicator,
2029 { "Global Title Indicator", "sccp.called.gti",
2030 FT_UINT8, BASE_HEX, VALS(sccp_ansi_global_title_indicator_values), GTI_MASK,
2032 { &hf_sccp_called_itu_ssn_indicator,
2033 { "SubSystem Number Indicator", "sccp.called.ssni",
2034 FT_UINT8, BASE_HEX, VALS(sccp_ai_ssni_values), ITU_SSN_INDICATOR_MASK,
2036 { &hf_sccp_called_itu_point_code_indicator,
2037 { "Point Code Indicator", "sccp.called.pci",
2038 FT_UINT8, BASE_HEX, VALS(sccp_ai_pci_values), ITU_PC_INDICATOR_MASK,
2040 { &hf_sccp_called_ansi_ssn_indicator,
2041 { "SubSystem Number Indicator", "sccp.called.ssni",
2042 FT_UINT8, BASE_HEX, VALS(sccp_ai_ssni_values), ANSI_SSN_INDICATOR_MASK,
2044 { &hf_sccp_called_ansi_point_code_indicator,
2045 { "Point Code Indicator", "sccp.called.pci",
2046 FT_UINT8, BASE_HEX, VALS(sccp_ai_pci_values), ANSI_PC_INDICATOR_MASK,
2048 { &hf_sccp_called_ssn,
2049 { "SubSystem Number", "sccp.called.ssn",
2050 FT_UINT8, BASE_DEC, VALS(sccp_ssn_values), 0x0,
2052 { &hf_sccp_called_itu_pc,
2053 { "PC", "sccp.called.pc",
2054 FT_UINT16, BASE_DEC, NULL, ITU_PC_MASK,
2056 { &hf_sccp_called_ansi_pc,
2057 { "PC", "sccp.called.ansi_pc",
2058 FT_STRING, BASE_NONE, NULL, 0x0,
2060 { &hf_sccp_called_chinese_pc,
2061 { "PC", "sccp.called.chinese_pc",
2062 FT_STRING, BASE_NONE, NULL, 0x0,
2064 { &hf_sccp_called_pc_network,
2066 "sccp.called.network",
2067 FT_UINT24, BASE_DEC, NULL, ANSI_NETWORK_MASK,
2069 { &hf_sccp_called_pc_cluster,
2071 "sccp.called.cluster",
2072 FT_UINT24, BASE_DEC, NULL, ANSI_CLUSTER_MASK,
2074 { &hf_sccp_called_pc_member,
2076 "sccp.called.member",
2077 FT_UINT24, BASE_DEC, NULL, ANSI_MEMBER_MASK,
2079 { &hf_sccp_called_gt_nai,
2080 { "Nature of Address Indicator",
2082 FT_UINT8, BASE_HEX, VALS(sccp_nai_values), GT_NAI_MASK,
2084 { &hf_sccp_called_gt_oe,
2085 { "Odd/Even Indicator",
2087 FT_UINT8, BASE_HEX, VALS(sccp_oe_values), GT_OE_MASK,
2089 { &hf_sccp_called_gt_tt,
2090 { "Translation Type",
2092 FT_UINT8, BASE_HEX, NULL, 0x0,
2094 { &hf_sccp_called_gt_np,
2097 FT_UINT8, BASE_HEX, VALS(sccp_np_values), GT_NP_MASK,
2099 { &hf_sccp_called_gt_es,
2100 { "Encoding Scheme",
2102 FT_UINT8, BASE_HEX, VALS(sccp_es_values), GT_ES_MASK,
2104 { &hf_sccp_called_gt_digits,
2106 "sccp.called.digits",
2107 FT_STRING, BASE_NONE, NULL, 0x0,
2110 { &hf_sccp_calling_national_indicator,
2111 { "National Indicator", "sccp.calling.ni",
2112 FT_UINT8, BASE_HEX, VALS(sccp_national_indicator_values), ANSI_NATIONAL_MASK,
2114 { &hf_sccp_calling_routing_indicator,
2115 { "Routing Indicator", "sccp.calling.ri",
2116 FT_UINT8, BASE_HEX, VALS(sccp_routing_indicator_values), ROUTING_INDICATOR_MASK,
2118 { &hf_sccp_calling_itu_global_title_indicator,
2119 { "Global Title Indicator", "sccp.calling.gti",
2120 FT_UINT8, BASE_HEX, VALS(sccp_itu_global_title_indicator_values), GTI_MASK,
2122 { &hf_sccp_calling_ansi_global_title_indicator,
2123 { "Global Title Indicator", "sccp.calling.gti",
2124 FT_UINT8, BASE_HEX, VALS(sccp_ansi_global_title_indicator_values), GTI_MASK,
2126 { &hf_sccp_calling_itu_ssn_indicator,
2127 { "SubSystem Number Indicator", "sccp.calling.ssni",
2128 FT_UINT8, BASE_HEX, VALS(sccp_ai_ssni_values), ITU_SSN_INDICATOR_MASK,
2130 { &hf_sccp_calling_itu_point_code_indicator,
2131 { "Point Code Indicator", "sccp.calling.pci",
2132 FT_UINT8, BASE_HEX, VALS(sccp_ai_pci_values), ITU_PC_INDICATOR_MASK,
2134 { &hf_sccp_calling_ansi_ssn_indicator,
2135 { "SubSystem Number Indicator", "sccp.calling.ssni",
2136 FT_UINT8, BASE_HEX, VALS(sccp_ai_ssni_values), ANSI_SSN_INDICATOR_MASK,
2138 { &hf_sccp_calling_ansi_point_code_indicator,
2139 { "Point Code Indicator", "sccp.calling.pci",
2140 FT_UINT8, BASE_HEX, VALS(sccp_ai_pci_values), ANSI_PC_INDICATOR_MASK,
2142 { &hf_sccp_calling_ssn,
2143 { "SubSystem Number", "sccp.calling.ssn",
2144 FT_UINT8, BASE_DEC, VALS(sccp_ssn_values), 0x0,
2146 { &hf_sccp_calling_itu_pc,
2147 { "PC", "sccp.calling.pc",
2148 FT_UINT16, BASE_DEC, NULL, ITU_PC_MASK,
2150 { &hf_sccp_calling_ansi_pc,
2151 { "PC", "sccp.calling.ansi_pc",
2152 FT_STRING, BASE_NONE, NULL, 0x0,
2154 { &hf_sccp_calling_chinese_pc,
2155 { "PC", "sccp.calling.chinese_pc",
2156 FT_STRING, BASE_NONE, NULL, 0x0,
2158 { &hf_sccp_calling_pc_network,
2160 "sccp.calling.network",
2161 FT_UINT24, BASE_DEC, NULL, ANSI_NETWORK_MASK,
2163 { &hf_sccp_calling_pc_cluster,
2165 "sccp.calling.cluster",
2166 FT_UINT24, BASE_DEC, NULL, ANSI_CLUSTER_MASK,
2168 { &hf_sccp_calling_pc_member,
2170 "sccp.calling.member",
2171 FT_UINT24, BASE_DEC, NULL, ANSI_MEMBER_MASK,
2173 { &hf_sccp_calling_gt_nai,
2174 { "Nature of Address Indicator",
2176 FT_UINT8, BASE_HEX, VALS(sccp_nai_values), GT_NAI_MASK,
2178 { &hf_sccp_calling_gt_oe,
2179 { "Odd/Even Indicator",
2181 FT_UINT8, BASE_HEX, VALS(sccp_oe_values), GT_OE_MASK,
2183 { &hf_sccp_calling_gt_tt,
2184 { "Translation Type",
2186 FT_UINT8, BASE_HEX, NULL, 0x0,
2188 { &hf_sccp_calling_gt_np,
2191 FT_UINT8, BASE_HEX, VALS(sccp_np_values), GT_NP_MASK,
2193 { &hf_sccp_calling_gt_es,
2194 { "Encoding Scheme",
2196 FT_UINT8, BASE_HEX, VALS(sccp_es_values), GT_ES_MASK,
2198 { &hf_sccp_calling_gt_digits,
2200 "sccp.calling.digits",
2201 FT_STRING, BASE_NONE, NULL, 0x0,
2205 { "Destination Local Reference", "sccp.dlr",
2206 FT_UINT24, BASE_HEX, NULL, 0x0,
2209 { "Source Local Reference", "sccp.slr",
2210 FT_UINT24, BASE_HEX, NULL, 0x0,
2213 { "Class", "sccp.class",
2214 FT_UINT8, BASE_HEX, NULL, CLASS_CLASS_MASK,
2216 { &hf_sccp_handling,
2217 { "Message handling", "sccp.handling",
2218 FT_UINT8, BASE_HEX, VALS(sccp_class_handling_values), CLASS_SPARE_HANDLING_MASK,
2221 { "More data", "sccp.more",
2222 FT_UINT8, BASE_HEX, VALS(sccp_segmenting_reassembling_values), SEGMENTING_REASSEMBLING_MASK,
2225 { "Receive Sequence Number", "sccp.rsn",
2226 FT_UINT8, BASE_HEX, NULL, RSN_MASK,
2228 { &hf_sccp_sequencing_segmenting_ssn,
2229 { "Sequencing Segmenting: Send Sequence Number", "sccp.sequencing_segmenting.ssn",
2230 FT_UINT8, BASE_HEX, NULL, SEND_SEQUENCE_NUMBER_MASK,
2232 { &hf_sccp_sequencing_segmenting_rsn,
2233 { "Sequencing Segmenting: Receive Sequence Number", "sccp.sequencing_segmenting.rsn",
2234 FT_UINT8, BASE_HEX, NULL, RECEIVE_SEQUENCE_NUMBER_MASK,
2236 { &hf_sccp_sequencing_segmenting_more,
2237 { "Sequencing Segmenting: More", "sccp.sequencing_segmenting.more",
2238 FT_UINT8, BASE_HEX, VALS(sccp_segmenting_reassembling_values), SEQUENCING_SEGMENTING_MORE_MASK,
2241 { "Credit", "sccp.credit",
2242 FT_UINT8, BASE_HEX, NULL, 0x0,
2244 { &hf_sccp_release_cause,
2245 { "Release Cause", "sccp.release_cause",
2246 FT_UINT8, BASE_HEX, VALS(sccp_release_cause_values), 0x0,
2248 { &hf_sccp_return_cause,
2249 { "Return Cause", "sccp.return_cause",
2250 FT_UINT8, BASE_HEX, VALS(sccp_return_cause_values), 0x0,
2252 { &hf_sccp_reset_cause,
2253 { "Reset Cause", "sccp.reset_cause",
2254 FT_UINT8, BASE_HEX, VALS(sccp_reset_cause_values), 0x0,
2256 { &hf_sccp_error_cause,
2257 { "Error Cause", "sccp.error_cause",
2258 FT_UINT8, BASE_HEX, VALS(sccp_error_cause_values), 0x0,
2260 { &hf_sccp_refusal_cause,
2261 { "Refusal Cause", "sccp.refusal_cause",
2262 FT_UINT8, BASE_HEX, VALS(sccp_refusal_cause_values), 0x0,
2264 { &hf_sccp_segmentation_first,
2265 { "Segmentation: First", "sccp.segmentation.first",
2266 FT_UINT8, BASE_HEX, VALS(sccp_segmentation_first_segment_values), SEGMENTATION_FIRST_SEGMENT_MASK,
2268 { &hf_sccp_segmentation_class,
2269 { "Segmentation: Class", "sccp.segmentation.class",
2270 FT_UINT8, BASE_HEX, VALS(sccp_segmentation_class_values), SEGMENTATION_CLASS_MASK,
2272 { &hf_sccp_segmentation_remaining,
2273 { "Segmentation: Remaining", "sccp.segmentation.remaining",
2274 FT_UINT8, BASE_HEX, NULL, SEGMENTATION_REMAINING_MASK,
2276 { &hf_sccp_segmentation_slr,
2277 { "Segmentation: Source Local Reference", "sccp.segmentation.slr",
2278 FT_UINT24, BASE_HEX, NULL, 0x0,
2280 { &hf_sccp_hop_counter,
2281 { "Hop Counter", "sccp.hops",
2282 FT_UINT8, BASE_HEX, NULL, 0x0,
2284 { &hf_sccp_importance,
2285 { "Importance", "sccp.importance",
2286 FT_UINT8, BASE_HEX, NULL, IMPORTANCE_IMPORTANCE_MASK,
2289 /* ISNI is ANSI only */
2290 { &hf_sccp_ansi_isni_mi,
2291 { "ISNI Mark for Identification Indicator", "sccp.isni.mi",
2292 FT_UINT8, BASE_HEX, VALS(sccp_isni_mark_for_id_values), ANSI_ISNI_MI_MASK,
2294 { &hf_sccp_ansi_isni_iri,
2295 { "ISNI Routing Indicator", "sccp.isni.iri",
2296 FT_UINT8, BASE_HEX, VALS(sccp_isni_iri_values), ANSI_ISNI_IRI_MASK,
2298 { &hf_sccp_ansi_isni_ti,
2299 { "ISNI Type Indicator", "sccp.isni.ti",
2300 FT_UINT8, BASE_HEX, VALS(sccp_isni_ti_values), ANSI_ISNI_TI_MASK,
2302 { &hf_sccp_ansi_isni_netspec,
2303 { "ISNI Network Specific (Type 1)", "sccp.isni.netspec",
2304 FT_UINT8, BASE_HEX, NULL, ANSI_ISNI_NETSPEC_MASK,
2306 { &hf_sccp_ansi_isni_counter,
2307 { "ISNI Counter", "sccp.isni.counter",
2308 FT_UINT8, BASE_HEX, NULL, ANSI_ISNI_COUNTER_MASK,
2312 /* Setup protocol subtree array */
2313 static gint *ett[] = {
2316 &ett_sccp_called_ai,
2317 &ett_sccp_called_pc,
2318 &ett_sccp_called_gt,
2320 &ett_sccp_calling_ai,
2321 &ett_sccp_calling_pc,
2322 &ett_sccp_calling_gt,
2323 &ett_sccp_sequencing_segmenting,
2324 &ett_sccp_segmentation,
2325 &ett_sccp_ansi_isni_routing_control,
2328 /* Register the protocol name and description */
2329 proto_sccp = proto_register_protocol("Signalling Connection Control Part",
2332 register_dissector("sccp", dissect_sccp, proto_sccp);
2334 /* Required function calls to register the header fields and subtrees used */
2335 proto_register_field_array(proto_sccp, hf, array_length(hf));
2336 proto_register_subtree_array(ett, array_length(ett));
2338 sccp_ssn_dissector_table = register_dissector_table("sccp.ssn", "SCCP SSN", FT_UINT8, BASE_DEC);
2340 register_heur_dissector_list("sccp", &heur_subdissector_list);
2342 sccp_module = prefs_register_protocol(proto_sccp, NULL);
2344 prefs_register_uint_preference(sccp_module, "source_pc",
2346 "The source point code (usually MSC) (to determine whether message is uplink or downlink)",
2347 16, &sccp_source_pc_global);
2349 prefs_register_bool_preference(sccp_module, "show_length",
2351 "Show parameter length in the protocol tree",
2356 proto_reg_handoff_sccp(void)
2358 dissector_handle_t sccp_handle;
2360 sccp_handle = find_dissector("sccp");
2362 dissector_add("mtp3.service_indicator", SCCP_SI, sccp_handle);
2363 dissector_add("m3ua.protocol_data_si", SCCP_SI, sccp_handle);
2365 data_handle = find_dissector("data");