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 * Wireshark - Network traffic analyzer
18 * By Gerald Combs <gerald@wireshark.org>
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 <epan/prefs.h>
50 #include <epan/emem.h>
51 #include <epan/reassemble.h>
52 #include <epan/asn1.h>
54 #include <epan/strutil.h>
55 #include <epan/expert.h>
56 #include "packet-mtp3.h"
57 #include "packet-tcap.h"
58 #include "packet-sccp.h"
59 #include "packet-e164.h"
60 #include "packet-e212.h"
61 #include "packet-frame.h"
64 static Standard_Type decode_mtp3_standard;
67 #define SCCP_MSG_TYPE_OFFSET 0
68 #define SCCP_MSG_TYPE_LENGTH 1
69 #define POINTER_LENGTH 1
70 #define POINTER_LENGTH_LONG 2
72 #define INVALID_LR 0xffffff /* a reserved value */
74 /* Same as below but with names typed out */
75 static const value_string sccp_message_type_values[] = {
76 { SCCP_MSG_TYPE_CR, "Connection Request" },
77 { SCCP_MSG_TYPE_CC, "Connection Confirm" },
78 { SCCP_MSG_TYPE_CREF, "Connection Refused" },
79 { SCCP_MSG_TYPE_RLSD, "Released" },
80 { SCCP_MSG_TYPE_RLC, "Release Complete" },
81 { SCCP_MSG_TYPE_DT1, "Data Form 1" },
82 { SCCP_MSG_TYPE_DT2, "Data Form 2" },
83 { SCCP_MSG_TYPE_AK, "Data Acknowledgement" },
84 { SCCP_MSG_TYPE_UDT, "Unitdata" },
85 { SCCP_MSG_TYPE_UDTS, "Unitdata Service" },
86 { SCCP_MSG_TYPE_ED, "Expedited Data" },
87 { SCCP_MSG_TYPE_EA, "Expedited Data Acknowledgement" },
88 { SCCP_MSG_TYPE_RSR, "Reset Request" },
89 { SCCP_MSG_TYPE_RSC, "Reset Confirmation" },
90 { SCCP_MSG_TYPE_ERR, "Error" },
91 { SCCP_MSG_TYPE_IT, "Inactivity Timer" },
92 { SCCP_MSG_TYPE_XUDT, "Extended Unitdata" },
93 { SCCP_MSG_TYPE_XUDTS, "Extended Unitdata Service" },
94 { SCCP_MSG_TYPE_LUDT, "Long Unitdata" },
95 { SCCP_MSG_TYPE_LUDTS, "Long Unitdata Service" },
98 /* Same as above but in acronym form (for the Info column) */
99 const value_string sccp_message_type_acro_values[] = {
100 { SCCP_MSG_TYPE_CR, "CR" },
101 { SCCP_MSG_TYPE_CC, "CC" },
102 { SCCP_MSG_TYPE_CREF, "CREF" },
103 { SCCP_MSG_TYPE_RLSD, "RLSD" },
104 { SCCP_MSG_TYPE_RLC, "RLC" },
105 { SCCP_MSG_TYPE_DT1, "DT1" },
106 { SCCP_MSG_TYPE_DT2, "DT2" },
107 { SCCP_MSG_TYPE_AK, "AK" },
108 { SCCP_MSG_TYPE_UDT, "UDT" },
109 { SCCP_MSG_TYPE_UDTS, "UDTS" },
110 { SCCP_MSG_TYPE_ED, "ED" },
111 { SCCP_MSG_TYPE_EA, "EA" },
112 { SCCP_MSG_TYPE_RSR, "RSR" },
113 { SCCP_MSG_TYPE_RSC, "RSC" },
114 { SCCP_MSG_TYPE_ERR, "ERR" },
115 { SCCP_MSG_TYPE_IT, "IT" },
116 { SCCP_MSG_TYPE_XUDT, "XUDT" },
117 { SCCP_MSG_TYPE_XUDTS, "XUDTS" },
118 { SCCP_MSG_TYPE_LUDT, "LUDT" },
119 { SCCP_MSG_TYPE_LUDTS, "LUDTS" },
122 #define PARAMETER_LENGTH_LENGTH 1
123 #define PARAMETER_LONG_DATA_LENGTH_LENGTH 2
124 #define PARAMETER_TYPE_LENGTH 1
126 #define PARAMETER_END_OF_OPTIONAL_PARAMETERS 0x00
127 #define PARAMETER_DESTINATION_LOCAL_REFERENCE 0x01
128 #define PARAMETER_SOURCE_LOCAL_REFERENCE 0x02
129 #define PARAMETER_CALLED_PARTY_ADDRESS 0x03
130 #define PARAMETER_CALLING_PARTY_ADDRESS 0x04
131 #define PARAMETER_CLASS 0x05
132 #define PARAMETER_SEGMENTING_REASSEMBLING 0x06
133 #define PARAMETER_RECEIVE_SEQUENCE_NUMBER 0x07
134 #define PARAMETER_SEQUENCING_SEGMENTING 0x08
135 #define PARAMETER_CREDIT 0x09
136 #define PARAMETER_RELEASE_CAUSE 0x0a
137 #define PARAMETER_RETURN_CAUSE 0x0b
138 #define PARAMETER_RESET_CAUSE 0x0c
139 #define PARAMETER_ERROR_CAUSE 0x0d
140 #define PARAMETER_REFUSAL_CAUSE 0x0e
141 #define PARAMETER_DATA 0x0f
142 #define PARAMETER_SEGMENTATION 0x10
143 #define PARAMETER_HOP_COUNTER 0x11
144 /* Importance is ITU only */
145 #define PARAMETER_IMPORTANCE 0x12
146 #define PARAMETER_LONG_DATA 0x13
147 /* ISNI is ANSI only */
148 #define PARAMETER_ISNI 0xfa
150 static const value_string sccp_parameter_values[] = {
151 { PARAMETER_END_OF_OPTIONAL_PARAMETERS, "End of Optional Parameters" },
152 { PARAMETER_DESTINATION_LOCAL_REFERENCE, "Destination Local Reference" },
153 { PARAMETER_SOURCE_LOCAL_REFERENCE, "Source Local Reference" },
154 { PARAMETER_CALLED_PARTY_ADDRESS, "Called Party Address" },
155 { PARAMETER_CALLING_PARTY_ADDRESS, "Calling Party Address" },
156 { PARAMETER_CLASS, "Protocol Class" },
157 { PARAMETER_SEGMENTING_REASSEMBLING, "Segmenting/Reassembling" },
158 { PARAMETER_RECEIVE_SEQUENCE_NUMBER, "Receive Sequence Number" },
159 { PARAMETER_SEQUENCING_SEGMENTING, "Sequencing/Segmenting" },
160 { PARAMETER_CREDIT, "Credit" },
161 { PARAMETER_RELEASE_CAUSE, "Release Cause" },
162 { PARAMETER_RETURN_CAUSE, "Return Cause" },
163 { PARAMETER_RESET_CAUSE, "Reset Cause" },
164 { PARAMETER_ERROR_CAUSE, "Error Cause" },
165 { PARAMETER_REFUSAL_CAUSE, "Refusal Cause" },
166 { PARAMETER_DATA, "Data" },
167 { PARAMETER_SEGMENTATION, "Segmentation" },
168 { PARAMETER_HOP_COUNTER, "Hop Counter" },
169 { PARAMETER_IMPORTANCE, "Importance (ITU)" },
170 { PARAMETER_LONG_DATA, "Long Data" },
171 { PARAMETER_ISNI, "Intermediate Signaling Network Identification (ANSI)" },
175 #define END_OF_OPTIONAL_PARAMETERS_LENGTH 1
176 #define DESTINATION_LOCAL_REFERENCE_LENGTH 3
177 #define SOURCE_LOCAL_REFERENCE_LENGTH 3
178 #define PROTOCOL_CLASS_LENGTH 1
179 #define RECEIVE_SEQUENCE_NUMBER_LENGTH 1
180 #define CREDIT_LENGTH 1
181 #define RELEASE_CAUSE_LENGTH 1
182 #define RETURN_CAUSE_LENGTH 1
183 #define RESET_CAUSE_LENGTH 1
184 #define ERROR_CAUSE_LENGTH 1
185 #define REFUSAL_CAUSE_LENGTH 1
186 #define HOP_COUNTER_LENGTH 1
187 #define IMPORTANCE_LENGTH 1
190 /* Parts of the Called and Calling Address parameters */
191 /* Address Indicator */
192 #define ADDRESS_INDICATOR_LENGTH 1
193 #define ITU_RESERVED_MASK 0x80
194 #define ANSI_NATIONAL_MASK 0x80
195 #define ROUTING_INDICATOR_MASK 0x40
196 #define GTI_MASK 0x3C
198 #define ITU_SSN_INDICATOR_MASK 0x02
199 #define ITU_PC_INDICATOR_MASK 0x01
200 #define ANSI_PC_INDICATOR_MASK 0x02
201 #define ANSI_SSN_INDICATOR_MASK 0x01
203 static const value_string sccp_national_indicator_values[] = {
204 { 0x0, "Address coded to International standard" },
205 { 0x1, "Address coded to National standard" },
208 static const value_string sccp_routing_indicator_values[] = {
209 { 0x0, "Route on GT" },
210 { 0x1, "Route on SSN" },
213 #define AI_GTI_NO_GT 0x0
214 #define ITU_AI_GTI_NAI 0x1
215 #define AI_GTI_TT 0x2
216 #define ITU_AI_GTI_TT_NP_ES 0x3
217 #define ITU_AI_GTI_TT_NP_ES_NAI 0x4
218 static const value_string sccp_itu_global_title_indicator_values[] = {
219 { AI_GTI_NO_GT, "No Global Title" },
220 { ITU_AI_GTI_NAI, "Nature of Address Indicator only" },
221 { AI_GTI_TT, "Translation Type only" },
222 { ITU_AI_GTI_TT_NP_ES, "Translation Type, Numbering Plan, and Encoding Scheme included" },
223 { ITU_AI_GTI_TT_NP_ES_NAI, "Translation Type, Numbering Plan, Encoding Scheme, and Nature of Address Indicator included" },
226 /* #define AI_GTI_NO_GT 0x0 */
227 #define ANSI_AI_GTI_TT_NP_ES 0x1
228 /* #define AI_GTI_TT 0x2 */
229 static const value_string sccp_ansi_global_title_indicator_values[] = {
230 { AI_GTI_NO_GT, "No Global Title" },
231 { ANSI_AI_GTI_TT_NP_ES, "Translation Type, Numbering Plan, and Encoding Scheme included" },
232 { AI_GTI_TT, "Translation Type only" },
235 static const value_string sccp_ai_pci_values[] = {
236 { 0x1, "Point Code present" },
237 { 0x0, "Point Code not present" },
240 static const value_string sccp_ai_ssni_values[] = {
241 { 0x1, "SSN present" },
242 { 0x0, "SSN not present" },
245 #define ADDRESS_SSN_LENGTH 1
246 #define INVALID_SSN 0xff
247 /* Some values from 3GPP TS 23.003 */
248 /* Japan TTC and NTT define a lot of SSNs, some of which conflict with
249 * these. They are not added for now.
251 static const value_string sccp_ssn_values[] = {
252 { 0x00, "SSN not known/not used" },
253 { 0x01, "SCCP management" },
254 { 0x02, "Reserved for ITU-T allocation" },
255 { 0x03, "ISDN User Part" },
256 { 0x04, "OMAP (Operation, Maintenance, and Administration Part)" },
257 { 0x05, "MAP (Mobile Application Part)" },
258 { 0x06, "HLR (Home Location Register)" },
259 { 0x07, "VLR (Visitor Location Register)" },
260 { 0x08, "MSC (Mobile Switching Center)" },
261 { 0x09, "EIC/EIR (Equipment Identifier Center/Equipment Identification Register)" },
262 { 0x0a, "AUC/AC (Authentication Center)" },
263 { 0x0b, "ISDN supplementary services (ITU only)" },
264 { 0x0c, "Reserved for international use (ITU only)" },
265 { 0x0d, "Broadband ISDN edge-to-edge applications (ITU only)" },
266 { 0x0e, "TC test responder (ITU only)" },
267 /* The following national network subsystem numbers have been allocated for use within and
268 * between GSM/UMTS networks:
272 { 0x91, "GMLC(MAP)" },
274 { 0x93, "gsmSCF (MAP) or IM-SSF (MAP) or Presence Network Agent" },
275 { 0x94, "SIWF (MAP)" },
276 { 0x95, "SGSN (MAP)" },
277 { 0x96, "GGSN (MAP)" },
278 /* The following national network subsystem numbers have been allocated for use within GSM/UMTS networks:*/
280 { 0xfa, "BSC (BSSAP-LE)" },
281 { 0xfb, "MSC (BSSAP-LE)" },
282 { 0xfc, "IOS or SMLC (BSSAP-LE)" },
283 { 0xfd, "BSS O&M (A interface)" },
284 { 0xfe, "BSSAP/BSAP" },
288 /* * * * * * * * * * * * * * * * *
289 * Global Title: ITU GTI == 0001 *
290 * * * * * * * * * * * * * * * * */
291 #define GT_NAI_MASK 0x7F
292 #define GT_NAI_LENGTH 1
293 #define GT_NAI_UNKNOWN 0x00
294 #define GT_NAI_SUBSCRIBER_NUMBER 0x01
295 #define GT_NAI_RESERVED_NATIONAL 0x02
296 #define GT_NAI_NATIONAL_SIG_NUM 0x03
297 #define GT_NAI_INTERNATIONAL_NUM 0x04
298 static const value_string sccp_nai_values[] = {
299 { GT_NAI_UNKNOWN, "NAI unknown" },
300 { GT_NAI_SUBSCRIBER_NUMBER, "Subscriber Number" },
301 { GT_NAI_RESERVED_NATIONAL, "Reserved for national use" },
302 { GT_NAI_NATIONAL_SIG_NUM, "National significant number" },
303 { GT_NAI_INTERNATIONAL_NUM, "International number" },
307 #define GT_OE_MASK 0x80
310 static const value_string sccp_oe_values[] = {
311 { GT_OE_EVEN, "Even number of address signals" },
312 { GT_OE_ODD, "Odd number of address signals" },
315 const value_string sccp_address_signal_values[] = {
335 /* * * * * * * * * * * * * * * * * * * * *
336 * Global Title: ITU and ANSI GTI == 0010 *
337 * * * * * * * * * * * * * * * * * * * * */
338 #define GT_TT_LENGTH 1
341 /* * * * * * * * * * * * * * * * * * * * * * * * * *
342 * Global Title: ITU GTI == 0011, ANSI GTI == 0001 *
343 * * * * * * * * * * * * * * * * * * * * * * * * * */
344 #define GT_NP_MASK 0xf0
345 #define GT_NP_SHIFT 4
346 #define GT_NP_ES_LENGTH 1
347 #define GT_NP_UNKNOWN 0x00
348 #define GT_NP_ISDN 0x01
349 #define GT_NP_GENERIC_RESERVED 0x02
350 #define GT_NP_DATA 0x03
351 #define GT_NP_TELEX 0x04
352 #define GT_NP_MARITIME_MOBILE 0x05
353 #define GT_NP_LAND_MOBILE 0x06
354 #define GT_NP_ISDN_MOBILE 0x07
355 #define GT_NP_PRIVATE_NETWORK 0x0e
356 #define GT_NP_RESERVED 0x0f
357 static const value_string sccp_np_values[] = {
358 { GT_NP_UNKNOWN, "Unknown" },
359 { GT_NP_ISDN, "ISDN/telephony" },
360 { GT_NP_GENERIC_RESERVED, "Generic (ITU)/Reserved (ANSI)" },
361 { GT_NP_DATA, "Data" },
362 { GT_NP_TELEX, "Telex" },
363 { GT_NP_MARITIME_MOBILE, "Maritime mobile" },
364 { GT_NP_LAND_MOBILE, "Land mobile" },
365 { GT_NP_ISDN_MOBILE, "ISDN/mobile" },
366 { GT_NP_PRIVATE_NETWORK, "Private network or network-specific" },
367 { GT_NP_RESERVED, "Reserved" },
370 #define GT_ES_MASK 0x0f
371 #define GT_ES_UNKNOWN 0x0
372 #define GT_ES_BCD_ODD 0x1
373 #define GT_ES_BCD_EVEN 0x2
374 #define GT_ES_NATIONAL 0x3
375 #define GT_ES_RESERVED 0xf
376 static const value_string sccp_es_values[] = {
377 { GT_ES_UNKNOWN, "Unknown" },
378 { GT_ES_BCD_ODD, "BCD, odd number of digits" },
379 { GT_ES_BCD_EVEN, "BCD, even number of digits" },
380 { GT_ES_NATIONAL, "National specific" },
381 { GT_ES_RESERVED, "Reserved (ITU)/Spare (ANSI)" },
384 /* Address signals above */
387 /* * * * * * * * * * * * * * * * *
388 * Global Title: ITU GTI == 0100 *
389 * * * * * * * * * * * * * * * * */
393 /* Address signals above */
396 #define CLASS_CLASS_MASK 0xf
397 #define CLASS_SPARE_HANDLING_MASK 0xf0
398 static const value_string sccp_class_handling_values [] = {
399 { 0x0, "No special options" },
400 { 0x8, "Return message on error" },
404 #define SEGMENTING_REASSEMBLING_LENGTH 1
405 #define SEGMENTING_REASSEMBLING_MASK 0x01
406 #define NO_MORE_DATA 0
408 /* This is also used by sequencing-segmenting parameter */
409 static const value_string sccp_segmenting_reassembling_values [] = {
410 { NO_MORE_DATA, "No more data" },
411 { MORE_DATA, "More data" },
415 #define RECEIVE_SEQUENCE_NUMBER_LENGTH 1
416 #define RSN_MASK 0xfe
418 #define SEQUENCING_SEGMENTING_LENGTH 2
419 #define SEQUENCING_SEGMENTING_SSN_LENGTH 1
420 #define SEQUENCING_SEGMENTING_RSN_LENGTH 1
421 #define SEND_SEQUENCE_NUMBER_MASK 0xfe
422 #define RECEIVE_SEQUENCE_NUMBER_MASK 0xfe
423 #define SEQUENCING_SEGMENTING_MORE_MASK 0x01
426 #define CREDIT_LENGTH 1
428 #define RELEASE_CAUSE_LENGTH 1
429 const value_string sccp_release_cause_values [] = {
430 { 0x00, "End user originated" },
431 { 0x01, "End user congestion" },
432 { 0x02, "End user failure" },
433 { 0x03, "SCCP user originated" },
434 { 0x04, "Remote procedure error" },
435 { 0x05, "Inconsistent connection data" },
436 { 0x06, "Access failure" },
437 { 0x07, "Access congestion" },
438 { 0x08, "Subsystem failure" },
439 { 0x09, "Subsystem congestion" },
440 { 0x0a, "MTP failure" },
441 { 0x0b, "Network congestion" },
442 { 0x0c, "Expiration of reset timer" },
443 { 0x0d, "Expiration of receive inactivity timer" },
444 { 0x0e, "Reserved" },
445 { 0x0f, "Unqualified" },
446 { 0x10, "SCCP failure (ITU only)" },
450 #define RETURN_CAUSE_LENGTH 1
451 const value_string sccp_return_cause_values [] = {
452 { 0x00, "No translation for an address of such nature" },
453 { 0x01, "No translation for this specific address" },
454 { 0x02, "Subsystem congestion" },
455 { 0x03, "Subsystem failure" },
456 { 0x04, "Unequipped failure" },
457 { 0x05, "MTP failure" },
458 { 0x06, "Network congestion" },
459 { 0x07, "Unqualified" },
460 { 0x08, "Error in message transport" },
461 { 0x09, "Error in local processing" },
462 { 0x0a, "Destination cannot perform reassembly" },
463 { 0x0b, "SCCP failure" },
464 { 0x0c, "Hop counter violation" },
465 { 0x0d, "Segmentation not supported" },
466 { 0x0e, "Segmentation failure" },
467 { 0xf7, "Message change failure (ANSI only)" },
468 { 0xf8, "Invalid INS routing request (ANSI only)" },
469 { 0xf9, "Invalid ISNI routing request (ANSI only)"},
470 { 0xfa, "Unauthorized message (ANSI only)" },
471 { 0xfb, "Message incompatibility (ANSI only)" },
472 { 0xfc, "Cannot perform ISNI constrained routing (ANSI only)" },
473 { 0xfd, "Redundant ISNI constrained routing (ANSI only)" },
474 { 0xfe, "Unable to perform ISNI identification (ANSI only)" },
478 #define RESET_CAUSE_LENGTH 1
479 const value_string sccp_reset_cause_values [] = {
480 { 0x00, "End user originated" },
481 { 0x01, "SCCP user originated" },
482 { 0x02, "Message out of order - incorrect send sequence number" },
483 { 0x03, "Message out of order - incorrect receive sequence number" },
484 { 0x04, "Remote procedure error - message out of window" },
485 { 0x05, "Remote procedure error - incorrect send sequence number after (re)initialization" },
486 { 0x06, "Remote procedure error - general" },
487 { 0x07, "Remote end user operational" },
488 { 0x08, "Network operational" },
489 { 0x09, "Access operational" },
490 { 0x0a, "Network congestion" },
491 { 0x0b, "Reserved (ITU)/Not obtainable (ANSI)" },
492 { 0x0c, "Unqualified" },
496 #define ERROR_CAUSE_LENGTH 1
497 const value_string sccp_error_cause_values [] = {
498 { 0x00, "Local Reference Number (LRN) mismatch - unassigned destination LRN" },
499 { 0x01, "Local Reference Number (LRN) mismatch - inconsistent source LRN" },
500 { 0x02, "Point code mismatch" },
501 { 0x03, "Service class mismatch" },
502 { 0x04, "Unqualified" },
506 #define REFUSAL_CAUSE_LENGTH 1
507 const value_string sccp_refusal_cause_values [] = {
508 { 0x00, "End user originated" },
509 { 0x01, "End user congestion" },
510 { 0x02, "End user failure" },
511 { 0x03, "SCCP user originated" },
512 { 0x04, "Destination address unknown" },
513 { 0x05, "Destination inaccessible" },
514 { 0x06, "Network resource - QOS not available/non-transient" },
515 { 0x07, "Network resource - QOS not available/transient" },
516 { 0x08, "Access failure" },
517 { 0x09, "Access congestion" },
518 { 0x0a, "Subsystem failure" },
519 { 0x0b, "Subsystem congestion" },
520 { 0x0c, "Expiration of connection establishment timer" },
521 { 0x0d, "Incompatible user data" },
522 { 0x0e, "Reserved" },
523 { 0x0f, "Unqualified" },
524 { 0x10, "Hop counter violation" },
525 { 0x11, "SCCP failure (ITU only)" },
526 { 0x12, "No translation for an address of such nature" },
527 { 0x13, "Unequipped user" },
531 #define SEGMENTATION_LENGTH 4
532 #define SEGMENTATION_FIRST_SEGMENT_MASK 0x80
533 #define SEGMENTATION_CLASS_MASK 0x40
534 #define SEGMENTATION_SPARE_MASK 0x30
535 #define SEGMENTATION_REMAINING_MASK 0x0f
536 static const value_string sccp_segmentation_first_segment_values [] = {
537 { 1, "First segment" },
538 { 0, "Not first segment" },
540 static const value_string sccp_segmentation_class_values [] = {
541 { 0, "Class 0 selected" },
542 { 1, "Class 1 selected" },
546 #define HOP_COUNTER_LENGTH 1
548 #define IMPORTANCE_LENGTH 1
549 #define IMPORTANCE_IMPORTANCE_MASK 0x7
552 #define ANSI_ISNI_ROUTING_CONTROL_LENGTH 1
553 #define ANSI_ISNI_MI_MASK 0x01
554 #define ANSI_ISNI_IRI_MASK 0x06
555 #define ANSI_ISNI_RES_MASK 0x08
556 #define ANSI_ISNI_TI_MASK 0x10
557 #define ANSI_ISNI_TI_SHIFT 4
558 #define ANSI_ISNI_COUNTER_MASK 0xe0
559 #define ANSI_ISNI_NETSPEC_MASK 0x03
561 static const value_string sccp_isni_mark_for_id_values [] = {
562 { 0x0, "Do not identify networks" },
563 { 0x1, "Identify networks" },
566 static const value_string sccp_isni_iri_values [] = {
567 { 0x0, "Neither constrained nor suggested ISNI routing" },
568 { 0x1, "Constrained ISNI routing" },
569 { 0x2, "Reserved for suggested ISNI routing" },
573 #define ANSI_ISNI_TYPE_0 0x0
574 #define ANSI_ISNI_TYPE_1 0x1
575 static const value_string sccp_isni_ti_values [] = {
576 { ANSI_ISNI_TYPE_0, "Type zero ISNI parameter format" },
577 { ANSI_ISNI_TYPE_1, "Type one ISNI parameter format" },
581 /* Initialize the protocol and registered fields */
582 static int proto_sccp = -1;
583 static int hf_sccp_message_type = -1;
584 static int hf_sccp_variable_pointer1 = -1;
585 static int hf_sccp_variable_pointer2 = -1;
586 static int hf_sccp_variable_pointer3 = -1;
587 static int hf_sccp_optional_pointer = -1;
588 static int hf_sccp_ssn = -1;
589 static int hf_sccp_gt_digits = -1;
591 /* Called Party address */
592 static int hf_sccp_called_national_indicator = -1;
593 static int hf_sccp_called_routing_indicator = -1;
594 static int hf_sccp_called_itu_global_title_indicator = -1;
595 static int hf_sccp_called_ansi_global_title_indicator = -1;
596 static int hf_sccp_called_itu_ssn_indicator = -1;
597 static int hf_sccp_called_itu_point_code_indicator = -1;
598 static int hf_sccp_called_ansi_ssn_indicator = -1;
599 static int hf_sccp_called_ansi_point_code_indicator = -1;
600 static int hf_sccp_called_ssn = -1;
601 static int hf_sccp_called_pc_member = -1;
602 static int hf_sccp_called_pc_cluster = -1;
603 static int hf_sccp_called_pc_network = -1;
604 static int hf_sccp_called_ansi_pc = -1;
605 static int hf_sccp_called_chinese_pc = -1;
606 static int hf_sccp_called_itu_pc = -1;
607 static int hf_sccp_called_japan_pc = -1;
608 static int hf_sccp_called_gt_nai = -1;
609 static int hf_sccp_called_gt_oe = -1;
610 static int hf_sccp_called_gt_tt = -1;
611 static int hf_sccp_called_gt_np = -1;
612 static int hf_sccp_called_gt_es = -1;
613 static int hf_sccp_called_gt_digits = -1;
615 /* Calling party address */
616 static int hf_sccp_calling_national_indicator = -1;
617 static int hf_sccp_calling_routing_indicator = -1;
618 static int hf_sccp_calling_itu_global_title_indicator = -1;
619 static int hf_sccp_calling_ansi_global_title_indicator = -1;
620 static int hf_sccp_calling_itu_ssn_indicator = -1;
621 static int hf_sccp_calling_itu_point_code_indicator = -1;
622 static int hf_sccp_calling_ansi_ssn_indicator = -1;
623 static int hf_sccp_calling_ansi_point_code_indicator = -1;
624 static int hf_sccp_calling_ssn = -1;
625 static int hf_sccp_calling_pc_member = -1;
626 static int hf_sccp_calling_pc_cluster = -1;
627 static int hf_sccp_calling_pc_network = -1;
628 static int hf_sccp_calling_ansi_pc = -1;
629 static int hf_sccp_calling_chinese_pc = -1;
630 static int hf_sccp_calling_itu_pc = -1;
631 static int hf_sccp_calling_japan_pc = -1;
632 static int hf_sccp_calling_gt_nai = -1;
633 static int hf_sccp_calling_gt_oe = -1;
634 static int hf_sccp_calling_gt_tt = -1;
635 static int hf_sccp_calling_gt_np = -1;
636 static int hf_sccp_calling_gt_es = -1;
637 static int hf_sccp_calling_gt_digits = -1;
639 /* Other parameter values */
640 static int hf_sccp_dlr = -1;
641 static int hf_sccp_slr = -1;
642 static int hf_sccp_lr = -1;
643 static int hf_sccp_class = -1;
644 static int hf_sccp_handling = -1;
645 static int hf_sccp_more = -1;
646 static int hf_sccp_rsn = -1;
647 static int hf_sccp_sequencing_segmenting_ssn = -1;
648 static int hf_sccp_sequencing_segmenting_rsn = -1;
649 static int hf_sccp_sequencing_segmenting_more = -1;
650 static int hf_sccp_credit = -1;
651 static int hf_sccp_release_cause = -1;
652 static int hf_sccp_return_cause = -1;
653 static int hf_sccp_reset_cause = -1;
654 static int hf_sccp_error_cause = -1;
655 static int hf_sccp_refusal_cause = -1;
656 static int hf_sccp_segmentation_first = -1;
657 static int hf_sccp_segmentation_class = -1;
658 static int hf_sccp_segmentation_remaining = -1;
659 static int hf_sccp_segmentation_slr = -1;
660 static int hf_sccp_hop_counter = -1;
661 static int hf_sccp_importance = -1;
662 static int hf_sccp_ansi_isni_mi = -1;
663 static int hf_sccp_ansi_isni_iri = -1;
664 static int hf_sccp_ansi_isni_ti = -1;
665 static int hf_sccp_ansi_isni_netspec = -1;
666 static int hf_sccp_ansi_isni_counter = -1;
667 static int hf_sccp_xudt_msg_fragments = -1;
668 static int hf_sccp_xudt_msg_fragment = -1;
669 static int hf_sccp_xudt_msg_fragment_overlap = -1;
670 static int hf_sccp_xudt_msg_fragment_overlap_conflicts = -1;
671 static int hf_sccp_xudt_msg_fragment_multiple_tails = -1;
672 static int hf_sccp_xudt_msg_fragment_too_long_fragment = -1;
673 static int hf_sccp_xudt_msg_fragment_error = -1;
674 static int hf_sccp_xudt_msg_reassembled_in = -1;
675 static int hf_sccp_xudt_msg_reassembled_length = -1;
676 static int hf_sccp_assoc_msg = -1;
677 static int hf_sccp_assoc_id = -1;
679 /* Initialize the subtree pointers */
680 static gint ett_sccp = -1;
681 static gint ett_sccp_called = -1;
682 static gint ett_sccp_called_ai = -1;
683 static gint ett_sccp_called_pc = -1;
684 static gint ett_sccp_called_gt = -1;
685 static gint ett_sccp_calling = -1;
686 static gint ett_sccp_calling_ai = -1;
687 static gint ett_sccp_calling_pc = -1;
688 static gint ett_sccp_calling_gt = -1;
689 static gint ett_sccp_sequencing_segmenting = -1;
690 static gint ett_sccp_segmentation = -1;
691 static gint ett_sccp_ansi_isni_routing_control = -1;
692 static gint ett_sccp_xudt_msg_fragment = -1;
693 static gint ett_sccp_xudt_msg_fragments = -1;
694 static gint ett_sccp_assoc = -1;
695 static gint ett_sccp_digits = -1;
697 /* Declarations to desegment XUDT Messages */
698 static gboolean sccp_xudt_desegment = TRUE;
700 static gboolean show_key_params = FALSE;
702 static int sccp_tap = -1;
705 static const fragment_items sccp_xudt_msg_frag_items = {
706 /* Fragment subtrees */
707 &ett_sccp_xudt_msg_fragment,
708 &ett_sccp_xudt_msg_fragments,
709 /* Fragment fields */
710 &hf_sccp_xudt_msg_fragments,
711 &hf_sccp_xudt_msg_fragment,
712 &hf_sccp_xudt_msg_fragment_overlap,
713 &hf_sccp_xudt_msg_fragment_overlap_conflicts,
714 &hf_sccp_xudt_msg_fragment_multiple_tails,
715 &hf_sccp_xudt_msg_fragment_too_long_fragment,
716 &hf_sccp_xudt_msg_fragment_error,
717 /* Reassembled in field */
718 &hf_sccp_xudt_msg_reassembled_in,
719 /* Reassembled length field */
720 &hf_sccp_xudt_msg_reassembled_length,
722 "SCCP XUDT Message fragments"
725 static GHashTable *sccp_xudt_msg_fragment_table = NULL;
726 static GHashTable *sccp_xudt_msg_reassembled_table = NULL;
729 #define SCCP_USER_DATA 0
730 #define SCCP_USER_TCAP 1
731 #define SCCP_USER_RANAP 2
732 #define SCCP_USER_BSSAP 3
733 #define SCCP_USER_GSMMAP 4
734 #define SCCP_USER_CAMEL 5
735 #define SCCP_USER_INAP 6
737 typedef struct _sccp_user_t {
743 dissector_handle_t* handlep;
746 static sccp_user_t* sccp_users;
747 static guint num_sccp_users;
749 static dissector_handle_t data_handle;
750 static dissector_handle_t tcap_handle;
751 static dissector_handle_t ranap_handle;
752 static dissector_handle_t bssap_handle;
753 static dissector_handle_t gsmmap_handle;
754 static dissector_handle_t camel_handle;
755 static dissector_handle_t inap_handle;
757 static const value_string sccp_users_vals[] = {
758 { SCCP_USER_DATA, "Data"},
759 { SCCP_USER_TCAP, "TCAP"},
760 { SCCP_USER_RANAP, "RANAP"},
761 { SCCP_USER_BSSAP, "BSSAP"},
762 { SCCP_USER_GSMMAP, "GSM MAP"},
763 { SCCP_USER_CAMEL, "CAMEL"},
764 { SCCP_USER_INAP, "INAP"},
769 * Here are the global variables associated with
770 * the various user definable characteristics of the dissection
772 static guint32 sccp_source_pc_global = 0;
773 static gboolean sccp_show_length = FALSE;
775 static module_t *sccp_module;
776 static heur_dissector_list_t heur_subdissector_list;
778 /* Keep track of SSN value of current message so if/when we get to the data
779 * parameter, we can call appropriate sub-dissector. TODO: can this info
780 * be stored elsewhere?
783 static guint8 message_type = 0;
784 static guint dlr = 0;
785 static guint slr = 0;
787 static dissector_table_t sccp_ssn_dissector_table;
789 static emem_tree_t* assocs = NULL;
790 static sccp_assoc_info_t* assoc;
791 static sccp_msg_info_t* sccp_msg;
792 static sccp_assoc_info_t no_assoc = {0,0,0,0,0,FALSE,FALSE,NULL,NULL,SCCP_PLOAD_NONE,NULL,NULL,NULL};
793 static gboolean trace_sccp = FALSE;
794 static guint32 next_assoc_id = 0;
796 static const value_string assoc_protos[] = {
797 { SCCP_PLOAD_BSSAP, "BSSAP" },
798 { SCCP_PLOAD_RANAP, "RANAP" },
802 static sccp_assoc_info_t* new_assoc(guint32 calling, guint32 called){
803 sccp_assoc_info_t* a = se_alloc0(sizeof(sccp_assoc_info_t));
805 a->id = next_assoc_id++;
806 a->calling_dpc = calling;
807 a->called_dpc = called;
808 a->calling_ssn = INVALID_SSN;
809 a->called_ssn = INVALID_SSN;
812 a->payload = SCCP_PLOAD_NONE;
813 a->calling_party = NULL;
814 a->called_party = NULL;
815 a->extra_info = NULL;
820 void reset_sccp_assoc(void) {
824 sccp_assoc_info_t* get_sccp_assoc(packet_info* pinfo, guint offset, guint32 src_lr, guint32 dst_lr, guint msg_type) {
826 address* opc = &(pinfo->src);
827 address* dpc = &(pinfo->dst);
828 guint framenum = pinfo->fd->num;
833 opck = opc->type == AT_SS7PC ? mtp3_pc_hash((const mtp3_addr_pc_t *)opc->data) : g_str_hash(ep_address_to_str(opc));
834 dpck = dpc->type == AT_SS7PC ? mtp3_pc_hash((const mtp3_addr_pc_t *)dpc->data) : g_str_hash(ep_address_to_str(dpc));
838 case SCCP_MSG_TYPE_CR:
840 /* CR contains the opc,dpc,dlr key of backward messages swapped as dpc,opc,slr */
841 emem_tree_key_t bw_key[] = {
842 {1, &dpck}, {1, &opck}, {1, &src_lr}, {0, NULL}
845 if (! ( assoc = se_tree_lookup32_array(assocs,bw_key) ) && ! pinfo->fd->flags.visited ) {
846 assoc = new_assoc(opck,dpck);
847 se_tree_insert32_array(assocs,bw_key,assoc);
848 assoc->has_bw_key = TRUE;
851 pinfo->p2p_dir = P2P_DIR_SENT;
855 case SCCP_MSG_TYPE_CC:
857 emem_tree_key_t fw_key[] = {
858 {1, &dpck}, {1, &opck}, {1, &src_lr}, {0, NULL}
860 emem_tree_key_t bw_key[] = {
861 {1, &opck}, {1, &dpck}, {1, &dst_lr}, {0, NULL}
864 if ( ( assoc = se_tree_lookup32_array(assocs,bw_key) ) ) {
868 if ( (assoc = se_tree_lookup32_array(assocs,fw_key) ) ) {
872 assoc = new_assoc(dpck,opck);
876 pinfo->p2p_dir = P2P_DIR_RECV;
878 if ( ! pinfo->fd->flags.visited && ! assoc->has_bw_key ) {
879 se_tree_insert32_array(assocs,bw_key,assoc);
880 assoc->has_bw_key = TRUE;
883 if ( ! pinfo->fd->flags.visited && ! assoc->has_fw_key ) {
884 se_tree_insert32_array(assocs,fw_key,assoc);
885 assoc->has_fw_key = TRUE;
890 case SCCP_MSG_TYPE_RLC:
892 emem_tree_key_t bw_key[] = {
893 {1, &dpck}, {1, &opck}, {1, &src_lr}, {0, NULL}
895 emem_tree_key_t fw_key[] = {
896 {1, &opck}, {1, &dpck}, {1, &dst_lr}, {0, NULL}
898 if ( ( assoc = se_tree_lookup32_array(assocs,bw_key) ) ) {
902 if ( (assoc = se_tree_lookup32_array(assocs,fw_key) ) ) {
906 assoc = new_assoc(dpck,opck);
910 pinfo->p2p_dir = P2P_DIR_SENT;
912 if ( ! pinfo->fd->flags.visited && ! assoc->has_bw_key ) {
913 se_tree_insert32_array(assocs,bw_key,assoc);
914 assoc->has_bw_key = TRUE;
917 if ( ! pinfo->fd->flags.visited && ! assoc->has_fw_key ) {
918 se_tree_insert32_array(assocs,fw_key,assoc);
919 assoc->has_fw_key = TRUE;
925 emem_tree_key_t key[] = {
926 {1, &opck}, {1, &dpck}, {1, &dst_lr}, {0, NULL}
929 assoc = se_tree_lookup32_array(assocs,key);
932 if (assoc->calling_dpc == dpck) {
933 pinfo->p2p_dir = P2P_DIR_RECV;
935 pinfo->p2p_dir = P2P_DIR_SENT;
943 if (assoc && trace_sccp) {
944 if ( ! pinfo->fd->flags.visited) {
945 sccp_msg_info_t* msg = se_alloc0(sizeof(sccp_msg_info_t));
946 msg->framenum = framenum;
947 msg->offset = offset;
948 msg->data.co.next = NULL;
949 msg->data.co.assoc = assoc;
950 msg->data.co.label = NULL;
951 msg->data.co.comment = NULL;
952 msg->type = msg_type;
956 for (m = assoc->msgs; m->data.co.next; m = m->data.co.next) ;
957 m->data.co.next = msg;
962 assoc->curr_msg = msg;
968 for (m = assoc->msgs; m; m = m->data.co.next) {
969 if (m->framenum == framenum && m->offset == offset) {
977 return assoc ? assoc : &no_assoc;
982 dissect_sccp_unknown_message(tvbuff_t *message_tvb, proto_tree *sccp_tree)
984 guint32 message_length;
986 message_length = tvb_length(message_tvb);
988 proto_tree_add_text(sccp_tree, message_tvb, 0, message_length,
989 "Unknown message (%u byte%s)",
990 message_length, plurality(message_length, "", "s"));
994 dissect_sccp_unknown_param(tvbuff_t *tvb, proto_tree *tree, guint8 type, guint length)
996 proto_tree_add_text(tree, tvb, 0, length, "Unknown parameter 0x%x (%u byte%s)",
997 type, length, plurality(length, "", "s"));
1001 dissect_sccp_dlr_param(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint length)
1003 proto_item *lr_item, *expert_item;
1006 expert_item = proto_tree_add_text(tree, tvb, 0, length, "Wrong length indicated. Expected 3, got %u", length);
1007 expert_add_info_format(pinfo, expert_item, PI_MALFORMED, PI_ERROR, "Wrong length indicated. Expected 3, got %u", length);
1008 PROTO_ITEM_SET_GENERATED(expert_item);
1012 dlr = tvb_get_letoh24(tvb, 0);
1013 proto_tree_add_uint(tree, hf_sccp_dlr, tvb, 0, length, dlr);
1014 lr_item = proto_tree_add_uint(tree, hf_sccp_lr, tvb, 0, length, dlr);
1015 PROTO_ITEM_SET_HIDDEN(lr_item);
1017 if (show_key_params && check_col(pinfo->cinfo, COL_INFO))
1018 col_append_fstr(pinfo->cinfo, COL_INFO, "DLR=%d ", dlr);
1022 dissect_sccp_slr_param(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint length)
1024 proto_item *lr_item, *expert_item;
1027 expert_item = proto_tree_add_text(tree, tvb, 0, length, "Wrong length indicated. Expected 3, got %u", length);
1028 expert_add_info_format(pinfo, expert_item, PI_MALFORMED, PI_ERROR, "Wrong length indicated. Expected 3, got %u", length);
1029 PROTO_ITEM_SET_GENERATED(expert_item);
1033 slr = tvb_get_letoh24(tvb, 0);
1034 proto_tree_add_uint(tree, hf_sccp_slr, tvb, 0, length, slr);
1035 lr_item = proto_tree_add_uint(tree, hf_sccp_lr, tvb, 0, length, slr);
1036 PROTO_ITEM_SET_HIDDEN(lr_item);
1038 if (show_key_params && check_col(pinfo->cinfo, COL_INFO))
1039 col_append_fstr(pinfo->cinfo, COL_INFO, "SLR=%d ", slr);
1043 #define is_connectionless(m) \
1044 ( m == SCCP_MSG_TYPE_UDT || m == SCCP_MSG_TYPE_UDTS \
1045 || m == SCCP_MSG_TYPE_XUDT|| m == SCCP_MSG_TYPE_XUDTS \
1046 || m == SCCP_MSG_TYPE_LUDT|| m == SCCP_MSG_TYPE_LUDTS)
1049 dissect_sccp_gt_address_information(tvbuff_t *tvb, proto_tree *tree,
1050 guint length, gboolean even_length,
1054 guint8 odd_signal, even_signal;
1055 proto_item *digits_item, *hidden_item;
1056 char gt_digits[GT_MAX_SIGNALS+1] = { 0 };
1058 while(offset < length)
1060 odd_signal = tvb_get_guint8(tvb, offset) & GT_ODD_SIGNAL_MASK;
1061 even_signal = tvb_get_guint8(tvb, offset) & GT_EVEN_SIGNAL_MASK;
1062 even_signal >>= GT_EVEN_SIGNAL_SHIFT;
1064 g_strlcat(gt_digits, val_to_str(odd_signal, sccp_address_signal_values,
1065 "Unknown"), GT_MAX_SIGNALS+1);
1067 /* If the last signal is NOT filler */
1068 if (offset != (length - 1) || even_length == TRUE)
1069 g_strlcat(gt_digits, val_to_str(even_signal, sccp_address_signal_values,
1070 "Unknown"), GT_MAX_SIGNALS+1);
1072 offset += GT_SIGNAL_LENGTH;
1075 if (is_connectionless(message_type) && sccp_msg) {
1076 guint8** gt_ptr = called ? &(sccp_msg->data.ud.called_gt) : &(sccp_msg->data.ud.calling_gt);
1078 *gt_ptr = (guint8 *)ep_strdup(gt_digits);
1081 digits_item = proto_tree_add_string_format(tree,
1082 called ? hf_sccp_called_gt_digits
1083 : hf_sccp_calling_gt_digits,
1084 tvb, 0, length, gt_digits,
1085 "Address information (digits): %s",
1088 hidden_item = proto_tree_add_string(tree, hf_sccp_gt_digits, tvb, 0, length,
1090 PROTO_ITEM_SET_HIDDEN(hidden_item);
1096 dissect_sccp_global_title(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint length,
1097 guint8 gti, gboolean called)
1099 proto_item *gt_item = 0;
1100 proto_item *digits_item = 0;
1101 proto_tree *gt_tree = 0;
1102 proto_tree *digits_tree = 0;
1103 tvbuff_t *signals_tvb;
1105 guint8 odd_even, nai = 0, tt, np = 0, es;
1106 gboolean even = TRUE;
1108 /* Shift GTI to where we can work with it */
1111 gt_item = proto_tree_add_text(tree, tvb, offset, length,
1112 "Global Title 0x%x (%u byte%s)",
1113 gti, length, plurality(length,"", "s"));
1114 gt_tree = proto_item_add_subtree(gt_item, called ? ett_sccp_called_gt
1115 : ett_sccp_calling_gt);
1117 /* Decode Transation Type (if present) */
1118 if ((gti == AI_GTI_TT) ||
1119 (decode_mtp3_standard != ANSI_STANDARD &&
1120 (gti == ITU_AI_GTI_TT_NP_ES || gti == ITU_AI_GTI_TT_NP_ES_NAI)) ||
1121 (decode_mtp3_standard == ANSI_STANDARD && gti == ANSI_AI_GTI_TT_NP_ES)) {
1123 tt = tvb_get_guint8(tvb, offset);
1124 proto_tree_add_uint(gt_tree, called ? hf_sccp_called_gt_tt
1125 : hf_sccp_calling_gt_tt,
1126 tvb, offset, GT_TT_LENGTH, tt);
1127 offset += GT_TT_LENGTH;
1130 if (gti == AI_GTI_TT) {
1131 /* Protocol doesn't tell us, so we ASSUME even... */
1135 /* Decode Numbering Plan and Encoding Scheme (if present) */
1136 if ((decode_mtp3_standard != ANSI_STANDARD &&
1137 (gti == ITU_AI_GTI_TT_NP_ES || gti == ITU_AI_GTI_TT_NP_ES_NAI)) ||
1138 (decode_mtp3_standard == ANSI_STANDARD && gti == ANSI_AI_GTI_TT_NP_ES)) {
1140 np = tvb_get_guint8(tvb, offset) & GT_NP_MASK;
1141 proto_tree_add_uint(gt_tree, called ? hf_sccp_called_gt_np
1142 : hf_sccp_calling_gt_np,
1143 tvb, offset, GT_NP_ES_LENGTH, np);
1145 es = tvb_get_guint8(tvb, offset) & GT_ES_MASK;
1146 proto_tree_add_uint(gt_tree, called ? hf_sccp_called_gt_es
1147 : hf_sccp_calling_gt_es,
1148 tvb, offset, GT_NP_ES_LENGTH, es);
1150 even = (es == GT_ES_BCD_EVEN) ? TRUE : FALSE;
1152 offset += GT_NP_ES_LENGTH;
1155 /* Decode Nature of Address Indicator (if present) */
1156 if (decode_mtp3_standard != ANSI_STANDARD &&
1157 (gti == ITU_AI_GTI_NAI || gti == ITU_AI_GTI_TT_NP_ES_NAI)) {
1159 /* Decode Odd/Even Indicator (if present) */
1160 if (gti == ITU_AI_GTI_NAI) {
1161 odd_even = tvb_get_guint8(tvb, offset) & GT_OE_MASK;
1162 proto_tree_add_uint(gt_tree, called ? hf_sccp_called_gt_oe
1163 : hf_sccp_calling_gt_oe,
1164 tvb, offset, GT_NAI_LENGTH, odd_even);
1165 even = (odd_even == GT_OE_EVEN) ? TRUE : FALSE;
1168 nai = tvb_get_guint8(tvb, offset) & GT_NAI_MASK;
1169 proto_tree_add_uint(gt_tree, called ? hf_sccp_called_gt_nai
1170 : hf_sccp_calling_gt_nai,
1171 tvb, offset, GT_NAI_LENGTH, nai);
1173 offset += GT_NAI_LENGTH;
1176 /* Decode address signal(s) */
1177 if (length < offset)
1180 signals_tvb = tvb_new_subset(tvb, offset, (length - offset),
1183 digits_item = dissect_sccp_gt_address_information(signals_tvb, gt_tree,
1187 /* Display the country code (if we can) */
1188 switch(np >> GT_NP_SHIFT) {
1190 case GT_NP_ISDN_MOBILE:
1191 if(nai == GT_NAI_INTERNATIONAL_NUM) {
1192 digits_tree = proto_item_add_subtree(digits_item,
1194 dissect_e164_cc(signals_tvb, digits_tree, 0, TRUE);
1197 case GT_NP_LAND_MOBILE:
1198 digits_tree = proto_item_add_subtree(digits_item,
1200 dissect_e212_mcc_mnc_in_address(signals_tvb, pinfo, digits_tree, 0);
1208 dissect_sccp_3byte_pc(tvbuff_t *tvb, proto_tree *call_tree, guint offset,
1213 if (decode_mtp3_standard == ANSI_STANDARD)
1216 hf_pc = &hf_sccp_called_ansi_pc;
1218 hf_pc = &hf_sccp_calling_ansi_pc;
1219 } else /* CHINESE_ITU_STANDARD */ {
1221 hf_pc = &hf_sccp_called_chinese_pc;
1223 hf_pc = &hf_sccp_calling_chinese_pc;
1226 /* create and fill the PC tree */
1227 dissect_mtp3_3byte_pc(tvb, offset, call_tree,
1228 called ? ett_sccp_called_pc : ett_sccp_calling_pc,
1230 called ? hf_sccp_called_pc_network : hf_sccp_calling_pc_network,
1231 called ? hf_sccp_called_pc_cluster : hf_sccp_calling_pc_cluster,
1232 called ? hf_sccp_called_pc_member : hf_sccp_calling_pc_member,
1235 return(offset + ANSI_PC_LENGTH);
1238 /* FUNCTION dissect_sccp_called_calling_param():
1239 * Dissect the Calling or Called Party Address parameters.
1241 * The boolean 'called' describes whether this function is decoding a
1242 * called (TRUE) or calling (FALSE) party address. There is simply too
1243 * much code in this function to have 2 copies of it (one for called, one
1246 * NOTE: this function is called even when (!tree) so that we can get
1247 * the SSN and subsequently call subdissectors (if and when there's a data
1248 * parameter). Realistically we should put if (!tree)'s around a lot of the
1249 * code, but I think that would make it unreadable--and the expense of not
1250 * doing so does not appear to be very high.
1253 dissect_sccp_called_calling_param(tvbuff_t *tvb, proto_tree *tree, packet_info *pinfo,
1254 guint length, gboolean called)
1256 proto_item *call_item = 0, *call_ai_item = 0, *item, *hidden_item, *expert_item;
1257 proto_tree *call_tree = 0, *call_ai_tree = 0;
1259 guint8 national = 0xFFU, routing_ind, gti, pci, ssni, ssn;
1261 dissector_handle_t ssn_dissector = NULL, tcap_ssn_dissector = NULL;
1262 const char *ssn_dissector_short_name = NULL;
1263 const char *tcap_ssn_dissector_short_name = NULL;
1265 call_item = proto_tree_add_text(tree, tvb, 0, length,
1266 "%s Party address (%u byte%s)",
1267 called ? "Called" : "Calling", length,
1268 plurality(length, "", "s"));
1269 call_tree = proto_item_add_subtree(call_item, called ? ett_sccp_called
1270 : ett_sccp_calling);
1272 call_ai_item = proto_tree_add_text(call_tree, tvb, 0,
1273 ADDRESS_INDICATOR_LENGTH,
1274 "Address Indicator");
1275 call_ai_tree = proto_item_add_subtree(call_ai_item, called ? ett_sccp_called_ai
1276 : ett_sccp_calling_ai);
1278 if (decode_mtp3_standard == ANSI_STANDARD)
1280 national = tvb_get_guint8(tvb, 0) & ANSI_NATIONAL_MASK;
1281 expert_item = proto_tree_add_uint(call_ai_tree, called ? hf_sccp_called_national_indicator
1282 : hf_sccp_calling_national_indicator,
1283 tvb, 0, ADDRESS_INDICATOR_LENGTH, national);
1285 expert_add_info_format(pinfo, expert_item, PI_MALFORMED, PI_NOTE, "Address is coded to "
1286 "international standards. This doesn't normally happen in ANSI "
1290 routing_ind = tvb_get_guint8(tvb, 0) & ROUTING_INDICATOR_MASK;
1291 proto_tree_add_uint(call_ai_tree, called ? hf_sccp_called_routing_indicator
1292 : hf_sccp_calling_routing_indicator,
1293 tvb, 0, ADDRESS_INDICATOR_LENGTH, routing_ind);
1295 gti = tvb_get_guint8(tvb, 0) & GTI_MASK;
1297 if (decode_mtp3_standard == ITU_STANDARD ||
1298 decode_mtp3_standard == CHINESE_ITU_STANDARD ||
1299 decode_mtp3_standard == JAPAN_STANDARD ||
1302 proto_tree_add_uint(call_ai_tree, called ? hf_sccp_called_itu_global_title_indicator
1303 : hf_sccp_calling_itu_global_title_indicator,
1304 tvb, 0, ADDRESS_INDICATOR_LENGTH, gti);
1306 ssni = tvb_get_guint8(tvb, 0) & ITU_SSN_INDICATOR_MASK;
1307 proto_tree_add_uint(call_ai_tree, called ? hf_sccp_called_itu_ssn_indicator
1308 : hf_sccp_calling_itu_ssn_indicator,
1309 tvb, 0, ADDRESS_INDICATOR_LENGTH, ssni);
1311 pci = tvb_get_guint8(tvb, 0) & ITU_PC_INDICATOR_MASK;
1312 proto_tree_add_uint(call_ai_tree, called ? hf_sccp_called_itu_point_code_indicator
1313 : hf_sccp_calling_itu_point_code_indicator,
1314 tvb, 0, ADDRESS_INDICATOR_LENGTH, pci);
1316 offset = ADDRESS_INDICATOR_LENGTH;
1318 /* Dissect PC (if present) */
1320 if (decode_mtp3_standard == ITU_STANDARD || national == 0) {
1321 if (length < offset + ITU_PC_LENGTH){
1322 expert_item = proto_tree_add_text(call_tree, tvb, 0, -1, "Wrong length indicated (%u) should be at least %u, PC is %u octets", length, offset + ITU_PC_LENGTH, ITU_PC_LENGTH);
1323 expert_add_info_format(pinfo, expert_item, PI_MALFORMED, PI_ERROR, "Wrong length indicated");
1324 PROTO_ITEM_SET_GENERATED(expert_item);
1327 proto_tree_add_item(call_tree, called ? hf_sccp_called_itu_pc
1328 : hf_sccp_calling_itu_pc,
1329 tvb, offset, ITU_PC_LENGTH, TRUE);
1330 offset += ITU_PC_LENGTH;
1332 }else if (decode_mtp3_standard == JAPAN_STANDARD) {
1334 if (length < offset + JAPAN_PC_LENGTH){
1335 expert_item = proto_tree_add_text(call_tree, tvb, 0, -1, "Wrong length indicated (%u) should be at least %u, PC is %u octets", length, offset + JAPAN_PC_LENGTH, JAPAN_PC_LENGTH);
1336 expert_add_info_format(pinfo, expert_item, PI_MALFORMED, PI_ERROR, "Wrong length indicated");
1337 PROTO_ITEM_SET_GENERATED(expert_item);
1340 proto_tree_add_item(call_tree, called ? hf_sccp_called_japan_pc
1341 : hf_sccp_calling_japan_pc,
1342 tvb, offset, JAPAN_PC_LENGTH, TRUE);
1344 offset += JAPAN_PC_LENGTH;
1346 } else /* CHINESE_ITU_STANDARD */ {
1348 if (length < offset + ANSI_PC_LENGTH){
1349 expert_item = proto_tree_add_text(call_tree, tvb, 0, -1, "Wrong length indicated (%u) should be at least %u, PC is %u octets", length, offset + ANSI_PC_LENGTH, ANSI_PC_LENGTH);
1350 expert_add_info_format(pinfo, expert_item, PI_MALFORMED, PI_ERROR, "Wrong length indicated");
1351 PROTO_ITEM_SET_GENERATED(expert_item);
1354 offset = dissect_sccp_3byte_pc(tvb, call_tree, offset, called);
1359 /* Dissect SSN (if present) */
1361 ssn = tvb_get_guint8(tvb, offset);
1363 if (called && assoc)
1364 assoc->called_ssn = ssn;
1366 assoc->calling_ssn = ssn;
1368 if (is_connectionless(message_type) && sccp_msg) {
1369 guint* ssn_ptr = called ? &(sccp_msg->data.ud.called_ssn) : &(sccp_msg->data.ud.calling_ssn);
1374 proto_tree_add_uint(call_tree, called ? hf_sccp_called_ssn
1375 : hf_sccp_calling_ssn,
1376 tvb, offset, ADDRESS_SSN_LENGTH, ssn);
1377 hidden_item = proto_tree_add_uint(call_tree, hf_sccp_ssn, tvb, offset,
1378 ADDRESS_SSN_LENGTH, ssn);
1379 PROTO_ITEM_SET_HIDDEN(hidden_item);
1381 offset += ADDRESS_SSN_LENGTH;
1383 /* Get the dissector handle of the dissector registered for this ssn
1384 * And print it's name.
1386 ssn_dissector = dissector_get_port_handle(sccp_ssn_dissector_table, ssn);
1388 if (ssn_dissector) {
1389 ssn_dissector_short_name = dissector_handle_get_short_name(ssn_dissector);
1391 if(ssn_dissector_short_name) {
1392 item = proto_tree_add_text(call_tree, tvb, offset - 1, ADDRESS_SSN_LENGTH, "Linked to %s", ssn_dissector_short_name);
1393 PROTO_ITEM_SET_GENERATED(item);
1395 if (g_ascii_strncasecmp("TCAP", ssn_dissector_short_name, 4)== 0) {
1396 tcap_ssn_dissector = get_itu_tcap_subdissector(ssn);
1398 if(tcap_ssn_dissector){
1399 tcap_ssn_dissector_short_name = dissector_handle_get_short_name(tcap_ssn_dissector);
1400 proto_item_append_text(item,", TCAP SSN linked to %s", tcap_ssn_dissector_short_name);
1404 } /* ssn_dissector */
1408 return; /* got SSN, that's all we need here... */
1410 /* Dissect GT (if present) */
1411 if (gti != AI_GTI_NO_GT) {
1412 if (length < offset)
1415 gt_tvb = tvb_new_subset(tvb, offset, (length - offset),
1417 dissect_sccp_global_title(gt_tvb, pinfo, call_tree, (length - offset), gti,
1421 } else if (decode_mtp3_standard == ANSI_STANDARD) {
1423 proto_tree_add_uint(call_ai_tree, called ? hf_sccp_called_ansi_global_title_indicator
1424 : hf_sccp_calling_ansi_global_title_indicator,
1425 tvb, 0, ADDRESS_INDICATOR_LENGTH, gti);
1427 pci = tvb_get_guint8(tvb, 0) & ANSI_PC_INDICATOR_MASK;
1428 proto_tree_add_uint(call_ai_tree, called ? hf_sccp_called_ansi_point_code_indicator
1429 : hf_sccp_calling_ansi_point_code_indicator,
1430 tvb, 0, ADDRESS_INDICATOR_LENGTH, pci);
1432 ssni = tvb_get_guint8(tvb, 0) & ANSI_SSN_INDICATOR_MASK;
1433 proto_tree_add_uint(call_ai_tree, called ? hf_sccp_called_ansi_ssn_indicator
1434 : hf_sccp_calling_ansi_ssn_indicator,
1435 tvb, 0, ADDRESS_INDICATOR_LENGTH, ssni);
1437 offset = ADDRESS_INDICATOR_LENGTH;
1439 /* Dissect SSN (if present) */
1441 ssn = tvb_get_guint8(tvb, offset);
1443 if (called && assoc){
1444 assoc->called_ssn = ssn;
1446 assoc->calling_ssn = ssn;
1449 if (is_connectionless(message_type) && sccp_msg) {
1450 guint* ssn_ptr = called ? &(sccp_msg->data.ud.called_ssn) : &(sccp_msg->data.ud.calling_ssn);
1455 proto_tree_add_uint(call_tree, called ? hf_sccp_called_ssn
1456 : hf_sccp_calling_ssn,
1457 tvb, offset, ADDRESS_SSN_LENGTH, ssn);
1458 hidden_item = proto_tree_add_uint(call_tree, hf_sccp_ssn, tvb, offset,
1459 ADDRESS_SSN_LENGTH, ssn);
1460 PROTO_ITEM_SET_HIDDEN(hidden_item);
1462 offset += ADDRESS_SSN_LENGTH;
1466 return; /* got SSN, that's all we need here... */
1468 /* Dissect PC (if present) */
1470 offset = dissect_sccp_3byte_pc(tvb, call_tree, offset, called);
1473 /* Dissect GT (if present) */
1474 if (gti != AI_GTI_NO_GT) {
1475 if (length < offset)
1477 gt_tvb = tvb_new_subset(tvb, offset, (length - offset),
1479 dissect_sccp_global_title(gt_tvb, pinfo, call_tree, (length - offset), gti,
1488 dissect_sccp_called_param(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint length)
1490 dissect_sccp_called_calling_param(tvb, tree, pinfo, length, TRUE);
1494 dissect_sccp_calling_param(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint length)
1496 dissect_sccp_called_calling_param(tvb, tree, pinfo, length, FALSE);
1500 dissect_sccp_class_param(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint length)
1502 guint8 class, handling;
1505 proto_item *expert_item;
1506 expert_item = proto_tree_add_text(tree, tvb, 0, length, "Wrong length indicated. Expected 1, got %u", length);
1507 expert_add_info_format(pinfo, expert_item, PI_MALFORMED, PI_ERROR, "Wrong length indicated. Expected 1, got %u", length);
1508 PROTO_ITEM_SET_GENERATED(expert_item);
1512 class = tvb_get_guint8(tvb, 0) & CLASS_CLASS_MASK;
1513 handling = tvb_get_guint8(tvb, 0) & CLASS_SPARE_HANDLING_MASK;
1515 proto_tree_add_uint(tree, hf_sccp_class, tvb, 0, length, class);
1517 if (class == 0 || class == 1)
1518 proto_tree_add_uint(tree, hf_sccp_handling, tvb, 0, length, handling);
1522 dissect_sccp_segmenting_reassembling_param(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint length)
1525 proto_item *expert_item;
1526 expert_item = proto_tree_add_text(tree, tvb, 0, length, "Wrong length indicated. Expected 1, got %u", length);
1527 expert_add_info_format(pinfo, expert_item, PI_MALFORMED, PI_ERROR, "Wrong length indicated. Expected 1, got %u", length);
1528 PROTO_ITEM_SET_GENERATED(expert_item);
1532 proto_tree_add_item(tree, hf_sccp_more, tvb, 0, length, FALSE);
1536 dissect_sccp_receive_sequence_number_param(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint length)
1541 proto_item *expert_item;
1542 expert_item = proto_tree_add_text(tree, tvb, 0, length, "Wrong length indicated. Expected 1, got %u", length);
1543 expert_add_info_format(pinfo, expert_item, PI_MALFORMED, PI_ERROR, "Wrong length indicated. Expected 1, got %u", length);
1544 PROTO_ITEM_SET_GENERATED(expert_item);
1548 rsn = tvb_get_guint8(tvb, 0) >> 1;
1549 proto_tree_add_uint(tree, hf_sccp_rsn, tvb, 0, length, rsn);
1553 dissect_sccp_sequencing_segmenting_param(tvbuff_t *tvb, proto_tree *tree, guint length)
1555 guint8 rsn, ssn, more;
1556 proto_item *param_item;
1557 proto_tree *param_tree;
1559 ssn = tvb_get_guint8(tvb, 0) >> 1;
1560 rsn = tvb_get_guint8(tvb, SEQUENCING_SEGMENTING_SSN_LENGTH) >> 1;
1561 more = tvb_get_guint8(tvb, SEQUENCING_SEGMENTING_SSN_LENGTH) & SEQUENCING_SEGMENTING_MORE_MASK;
1563 param_item = proto_tree_add_text(tree, tvb, 0, length, "%s",
1564 val_to_str(PARAMETER_SEQUENCING_SEGMENTING,
1565 sccp_parameter_values, "Unknown"));
1566 param_tree = proto_item_add_subtree(param_item,
1567 ett_sccp_sequencing_segmenting);
1569 proto_tree_add_uint(param_tree, hf_sccp_sequencing_segmenting_ssn, tvb, 0,
1570 SEQUENCING_SEGMENTING_SSN_LENGTH, ssn);
1571 proto_tree_add_uint(param_tree, hf_sccp_sequencing_segmenting_rsn, tvb,
1572 SEQUENCING_SEGMENTING_SSN_LENGTH,
1573 SEQUENCING_SEGMENTING_RSN_LENGTH, rsn);
1574 proto_tree_add_uint(param_tree, hf_sccp_sequencing_segmenting_more, tvb,
1575 SEQUENCING_SEGMENTING_SSN_LENGTH,
1576 SEQUENCING_SEGMENTING_RSN_LENGTH, more);
1580 dissect_sccp_credit_param(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint length)
1585 proto_item *expert_item;
1586 expert_item = proto_tree_add_text(tree, tvb, 0, length, "Wrong length indicated. Expected 1, got %u", length);
1587 expert_add_info_format(pinfo, expert_item, PI_MALFORMED, PI_ERROR, "Wrong length indicated. Expected 1, got %u", length);
1588 PROTO_ITEM_SET_GENERATED(expert_item);
1592 credit = tvb_get_guint8(tvb, 0);
1593 proto_tree_add_uint(tree, hf_sccp_credit, tvb, 0, length, credit);
1597 dissect_sccp_release_cause_param(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint length)
1602 proto_item *expert_item;
1603 expert_item = proto_tree_add_text(tree, tvb, 0, length, "Wrong length indicated. Expected 1, got %u", length);
1604 expert_add_info_format(pinfo, expert_item, PI_MALFORMED, PI_ERROR, "Wrong length indicated. Expected 1, got %u", length);
1605 PROTO_ITEM_SET_GENERATED(expert_item);
1609 cause = tvb_get_guint8(tvb, 0);
1610 proto_tree_add_uint(tree, hf_sccp_release_cause, tvb, 0, length, cause);
1612 if (show_key_params && check_col(pinfo->cinfo, COL_INFO))
1613 col_append_fstr(pinfo->cinfo, COL_INFO, "Cause=%d ", cause);
1617 dissect_sccp_return_cause_param(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint length)
1622 proto_item *expert_item;
1623 expert_item = proto_tree_add_text(tree, tvb, 0, length, "Wrong length indicated. Expected 1, got %u", length);
1624 expert_add_info_format(pinfo, expert_item, PI_MALFORMED, PI_ERROR, "Wrong length indicated. Expected 1, got %u", length);
1625 PROTO_ITEM_SET_GENERATED(expert_item);
1629 cause = tvb_get_guint8(tvb, 0);
1630 proto_tree_add_uint(tree, hf_sccp_return_cause, tvb, 0, length, cause);
1632 if (show_key_params && check_col(pinfo->cinfo, COL_INFO))
1633 col_append_fstr(pinfo->cinfo, COL_INFO, "Cause=%d ", cause);
1637 dissect_sccp_reset_cause_param(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint length)
1642 proto_item *expert_item;
1643 expert_item = proto_tree_add_text(tree, tvb, 0, length, "Wrong length indicated. Expected 1, got %u", length);
1644 expert_add_info_format(pinfo, expert_item, PI_MALFORMED, PI_ERROR, "Wrong length indicated. Expected 1, got %u", length);
1645 PROTO_ITEM_SET_GENERATED(expert_item);
1649 cause = tvb_get_guint8(tvb, 0);
1650 proto_tree_add_uint(tree, hf_sccp_reset_cause, tvb, 0, length, cause);
1652 if (show_key_params && check_col(pinfo->cinfo, COL_INFO))
1653 col_append_fstr(pinfo->cinfo, COL_INFO, "Cause=%d ", cause);
1657 dissect_sccp_error_cause_param(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint length)
1662 proto_item *expert_item;
1663 expert_item = proto_tree_add_text(tree, tvb, 0, length, "Wrong length indicated. Expected 1, got %u", length);
1664 expert_add_info_format(pinfo, expert_item, PI_MALFORMED, PI_ERROR, "Wrong length indicated. Expected 1, got %u", length);
1665 PROTO_ITEM_SET_GENERATED(expert_item);
1669 cause = tvb_get_guint8(tvb, 0);
1670 proto_tree_add_uint(tree, hf_sccp_error_cause, tvb, 0, length, cause);
1672 if (show_key_params && check_col(pinfo->cinfo, COL_INFO))
1673 col_append_fstr(pinfo->cinfo, COL_INFO, "Cause=%d ", cause);
1677 dissect_sccp_refusal_cause_param(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint length)
1682 proto_item *expert_item;
1683 expert_item = proto_tree_add_text(tree, tvb, 0, length, "Wrong length indicated. Expected 1, got %u", length);
1684 expert_add_info_format(pinfo, expert_item, PI_MALFORMED, PI_ERROR, "Wrong length indicated. Expected 1, got %u", length);
1685 PROTO_ITEM_SET_GENERATED(expert_item);
1689 cause = tvb_get_guint8(tvb, 0);
1690 proto_tree_add_uint(tree, hf_sccp_refusal_cause, tvb, 0, length, cause);
1692 if (show_key_params && check_col(pinfo->cinfo, COL_INFO))
1693 col_append_fstr(pinfo->cinfo, COL_INFO, "Cause=%d ", cause);
1697 /* This function is used for both data and long data (ITU only) parameters */
1699 dissect_sccp_data_param(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
1701 guint8 ssn = INVALID_SSN;
1702 guint8 other_ssn = INVALID_SSN;
1703 const mtp3_addr_pc_t* dpc = NULL;
1704 const mtp3_addr_pc_t* opc = NULL;
1706 if (trace_sccp && assoc && assoc != &no_assoc) {
1707 pinfo->sccp_info = assoc->curr_msg;
1709 pinfo->sccp_info = NULL;
1713 switch (pinfo->p2p_dir) {
1715 ssn = assoc->calling_ssn;
1716 other_ssn = assoc->called_ssn;
1717 dpc = (const mtp3_addr_pc_t*)pinfo->dst.data;
1718 opc = (const mtp3_addr_pc_t*)pinfo->src.data;
1721 ssn = assoc->called_ssn;
1722 other_ssn = assoc->calling_ssn;
1723 dpc = (const mtp3_addr_pc_t*)pinfo->src.data;
1724 opc = (const mtp3_addr_pc_t*)pinfo->dst.data;
1727 ssn = assoc->called_ssn;
1728 other_ssn = assoc->calling_ssn;
1729 dpc = (const mtp3_addr_pc_t*)pinfo->dst.data;
1730 opc = (const mtp3_addr_pc_t*)pinfo->src.data;
1736 if (num_sccp_users && pinfo->src.type == AT_SS7PC) {
1738 dissector_handle_t handle = NULL;
1739 gboolean uses_tcap = FALSE;
1741 for (i=0; i < num_sccp_users; i++) {
1742 sccp_user_t* u = &(sccp_users[i]);
1744 if (!dpc || dpc->ni != u->ni) continue;
1746 if (value_is_in_range(u->called_ssn, ssn) && value_is_in_range(u->called_pc, dpc->pc) ) {
1747 handle = *(u->handlep);
1748 uses_tcap = u->uses_tcap;
1750 } else if (value_is_in_range(u->called_ssn, other_ssn) && opc && value_is_in_range(u->called_pc, opc->pc) ) {
1751 handle = *(u->handlep);
1752 uses_tcap = u->uses_tcap;
1759 call_tcap_dissector(handle, tvb, pinfo, tree);
1761 call_dissector(handle, tvb, pinfo, tree);
1768 if (ssn != INVALID_SSN && dissector_try_port(sccp_ssn_dissector_table, ssn, tvb, pinfo, tree)) {
1772 if (other_ssn != INVALID_SSN && dissector_try_port(sccp_ssn_dissector_table, other_ssn, tvb, pinfo, tree)) {
1776 /* try heuristic subdissector list to see if there are any takers */
1777 if (dissector_try_heuristic(heur_subdissector_list, tvb, pinfo, tree)) {
1781 /* No sub-dissection occured, treat it as raw data */
1782 call_dissector(data_handle, tvb, pinfo, tree);
1787 dissect_sccp_segmentation_param(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint length)
1789 guint8 first, class, remaining;
1791 proto_item *param_item;
1792 proto_tree *param_tree;
1794 first = tvb_get_guint8(tvb, 0) & SEGMENTATION_FIRST_SEGMENT_MASK;
1795 class = tvb_get_guint8(tvb, 0) & SEGMENTATION_CLASS_MASK;
1796 remaining = tvb_get_guint8(tvb, 0) & SEGMENTATION_REMAINING_MASK;
1798 slrx = tvb_get_letoh24(tvb, 1);
1800 param_item = proto_tree_add_text(tree, tvb, 0, length, "%s",
1801 val_to_str(PARAMETER_SEGMENTATION,
1802 sccp_parameter_values, "Unknown"));
1803 param_tree = proto_item_add_subtree(param_item, ett_sccp_segmentation);
1805 proto_tree_add_uint(param_tree, hf_sccp_segmentation_first, tvb, 0, 1, first);
1806 proto_tree_add_uint(param_tree, hf_sccp_segmentation_class, tvb, 0, 1, class);
1807 proto_tree_add_uint(param_tree, hf_sccp_segmentation_remaining, tvb, 0, 1,
1810 if (length-1 != 3) {
1811 proto_item *expert_item;
1812 expert_item = proto_tree_add_text(tree, tvb, 0, length-1, "Wrong length indicated. Expected 3, got %u", length-1);
1813 expert_add_info_format(pinfo, expert_item, PI_MALFORMED, PI_ERROR, "Wrong length indicated. Expected 3, got %u", length-1);
1814 PROTO_ITEM_SET_GENERATED(expert_item);
1818 proto_tree_add_uint(param_tree, hf_sccp_segmentation_slr, tvb, 1, length-1,
1823 dissect_sccp_hop_counter_param(tvbuff_t *tvb, proto_tree *tree, guint length)
1827 hops = tvb_get_guint8(tvb, 0);
1828 proto_tree_add_uint(tree, hf_sccp_hop_counter, tvb, 0, length, hops);
1832 dissect_sccp_importance_param(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint length)
1837 proto_item *expert_item;
1838 expert_item = proto_tree_add_text(tree, tvb, 0, length, "Wrong length indicated. Expected 1, got %u", length);
1839 expert_add_info_format(pinfo, expert_item, PI_MALFORMED, PI_ERROR, "Wrong length indicated. Expected 1, got %u", length);
1840 PROTO_ITEM_SET_GENERATED(expert_item);
1844 importance = tvb_get_guint8(tvb, 0) & IMPORTANCE_IMPORTANCE_MASK;
1845 proto_tree_add_uint(tree, hf_sccp_importance, tvb, 0, length, importance);
1849 dissect_sccp_isni_param(tvbuff_t *tvb, proto_tree *tree, guint length)
1851 guint8 mi, iri, ti, network;
1853 proto_item *param_item;
1854 proto_tree *param_tree;
1856 /* Create a subtree for ISNI Routing Control */
1857 param_item = proto_tree_add_text(tree, tvb, offset, ANSI_ISNI_ROUTING_CONTROL_LENGTH,
1858 "ISNI Routing Control");
1859 param_tree = proto_item_add_subtree(param_item,
1860 ett_sccp_ansi_isni_routing_control);
1862 mi = tvb_get_guint8(tvb, offset) & ANSI_ISNI_MI_MASK;
1863 proto_tree_add_uint(param_tree, hf_sccp_ansi_isni_mi, tvb, offset,
1864 ANSI_ISNI_ROUTING_CONTROL_LENGTH, mi);
1866 iri = tvb_get_guint8(tvb, offset) & ANSI_ISNI_IRI_MASK;
1867 proto_tree_add_uint(param_tree, hf_sccp_ansi_isni_iri, tvb, offset,
1868 ANSI_ISNI_ROUTING_CONTROL_LENGTH, iri);
1870 ti = tvb_get_guint8(tvb, offset) & ANSI_ISNI_TI_MASK;
1871 proto_tree_add_uint(param_tree, hf_sccp_ansi_isni_ti, tvb, offset,
1872 ANSI_ISNI_ROUTING_CONTROL_LENGTH, ti);
1874 proto_tree_add_item(param_tree, hf_sccp_ansi_isni_counter, tvb, offset,
1875 ANSI_ISNI_ROUTING_CONTROL_LENGTH, TRUE);
1877 offset += ANSI_ISNI_ROUTING_CONTROL_LENGTH;
1879 if ((ti >> ANSI_ISNI_TI_SHIFT) == ANSI_ISNI_TYPE_1) {
1880 proto_tree_add_uint(param_tree, hf_sccp_ansi_isni_netspec, tvb, offset,
1881 ANSI_ISNI_ROUTING_CONTROL_LENGTH, ti);
1882 offset += ANSI_ISNI_ROUTING_CONTROL_LENGTH;
1885 while (offset < length) {
1887 network = tvb_get_guint8(tvb, offset);
1888 proto_tree_add_text(tree, tvb, offset, ANSI_NCM_LENGTH,
1889 "Network ID network: %d", network);
1892 network = tvb_get_guint8(tvb, offset);
1893 proto_tree_add_text(tree, tvb, offset, ANSI_NCM_LENGTH,
1894 "Network ID cluster: %d", network);
1900 /* FUNCTION dissect_sccp_parameter():
1901 * Dissect a parameter given its type, offset into tvb, and length.
1904 dissect_sccp_parameter(tvbuff_t *tvb, packet_info *pinfo, proto_tree *sccp_tree,
1905 proto_tree *tree, guint8 parameter_type, guint16 offset,
1906 guint16 parameter_length)
1908 tvbuff_t *parameter_tvb;
1910 switch (parameter_type) {
1911 case PARAMETER_CALLED_PARTY_ADDRESS:
1912 case PARAMETER_CALLING_PARTY_ADDRESS:
1913 case PARAMETER_DATA:
1914 case PARAMETER_LONG_DATA:
1915 case PARAMETER_SOURCE_LOCAL_REFERENCE:
1916 case PARAMETER_DESTINATION_LOCAL_REFERENCE:
1917 case PARAMETER_RELEASE_CAUSE:
1918 case PARAMETER_RETURN_CAUSE:
1919 case PARAMETER_RESET_CAUSE:
1920 case PARAMETER_ERROR_CAUSE:
1921 case PARAMETER_REFUSAL_CAUSE:
1923 /* These parameters must be dissected even if !sccp_tree (so that
1924 * assoc information can be created).
1929 if (!sccp_tree) return(parameter_length);
1933 parameter_tvb = tvb_new_subset(tvb, offset, parameter_length, parameter_length);
1935 switch (parameter_type) {
1937 case PARAMETER_END_OF_OPTIONAL_PARAMETERS:
1938 proto_tree_add_text(sccp_tree, tvb, offset, parameter_length,
1942 case PARAMETER_DESTINATION_LOCAL_REFERENCE:
1943 dissect_sccp_dlr_param(parameter_tvb, pinfo, sccp_tree, parameter_length);
1946 case PARAMETER_SOURCE_LOCAL_REFERENCE:
1947 dissect_sccp_slr_param(parameter_tvb, pinfo, sccp_tree, parameter_length);
1950 case PARAMETER_CALLED_PARTY_ADDRESS:
1951 dissect_sccp_called_param(parameter_tvb, pinfo, sccp_tree, parameter_length);
1954 case PARAMETER_CALLING_PARTY_ADDRESS:
1955 dissect_sccp_calling_param(parameter_tvb, pinfo, sccp_tree, parameter_length);
1958 case PARAMETER_CLASS:
1959 dissect_sccp_class_param(parameter_tvb, pinfo, sccp_tree, parameter_length);
1962 case PARAMETER_SEGMENTING_REASSEMBLING:
1963 dissect_sccp_segmenting_reassembling_param(parameter_tvb, pinfo, sccp_tree,
1967 case PARAMETER_RECEIVE_SEQUENCE_NUMBER:
1968 dissect_sccp_receive_sequence_number_param(parameter_tvb, pinfo, sccp_tree,
1972 case PARAMETER_SEQUENCING_SEGMENTING:
1973 dissect_sccp_sequencing_segmenting_param(parameter_tvb, sccp_tree,
1977 case PARAMETER_CREDIT:
1978 dissect_sccp_credit_param(parameter_tvb, pinfo, sccp_tree, parameter_length);
1981 case PARAMETER_RELEASE_CAUSE:
1982 dissect_sccp_release_cause_param(parameter_tvb, pinfo, sccp_tree, parameter_length);
1985 case PARAMETER_RETURN_CAUSE:
1986 dissect_sccp_return_cause_param(parameter_tvb, pinfo, sccp_tree, parameter_length);
1989 case PARAMETER_RESET_CAUSE:
1990 dissect_sccp_reset_cause_param(parameter_tvb, pinfo, sccp_tree, parameter_length);
1993 case PARAMETER_ERROR_CAUSE:
1994 dissect_sccp_error_cause_param(parameter_tvb, pinfo, sccp_tree, parameter_length);
1997 case PARAMETER_REFUSAL_CAUSE:
1998 dissect_sccp_refusal_cause_param(parameter_tvb, pinfo, sccp_tree, parameter_length);
2001 case PARAMETER_DATA:
2002 dissect_sccp_data_param(parameter_tvb, pinfo, tree);
2004 /* TODO? Re-adjust length of SCCP item since it may be sub-dissected */
2005 /* sccp_length = proto_item_get_len(sccp_item);
2006 * sccp_length -= parameter_length;
2007 * proto_item_set_len(sccp_item, sccp_length);
2011 case PARAMETER_SEGMENTATION:
2012 dissect_sccp_segmentation_param(parameter_tvb, pinfo, sccp_tree, parameter_length);
2015 case PARAMETER_HOP_COUNTER:
2016 dissect_sccp_hop_counter_param(parameter_tvb, sccp_tree, parameter_length);
2019 case PARAMETER_IMPORTANCE:
2020 if (decode_mtp3_standard != ANSI_STANDARD)
2021 dissect_sccp_importance_param(parameter_tvb, pinfo, sccp_tree, parameter_length);
2023 dissect_sccp_unknown_param(parameter_tvb, sccp_tree, parameter_type,
2027 case PARAMETER_LONG_DATA:
2028 dissect_sccp_data_param(parameter_tvb, pinfo, tree);
2031 case PARAMETER_ISNI:
2032 if (decode_mtp3_standard != ANSI_STANDARD)
2033 dissect_sccp_unknown_param(parameter_tvb, sccp_tree, parameter_type,
2036 dissect_sccp_isni_param(parameter_tvb, sccp_tree, parameter_length);
2040 dissect_sccp_unknown_param(parameter_tvb, sccp_tree, parameter_type,
2045 return(parameter_length);
2048 /* FUNCTION dissect_sccp_variable_parameter():
2049 * Dissect a variable parameter given its type and offset into tvb. Length
2050 * of the parameter is gotten from tvb[0].
2051 * Length returned is sum of (length + parameter).
2054 dissect_sccp_variable_parameter(tvbuff_t *tvb, packet_info *pinfo,
2055 proto_tree *sccp_tree, proto_tree *tree,
2056 guint8 parameter_type, guint16 offset)
2058 guint16 parameter_length;
2059 guint8 length_length;
2061 if (parameter_type != PARAMETER_LONG_DATA)
2063 parameter_length = tvb_get_guint8(tvb, offset);
2064 length_length = PARAMETER_LENGTH_LENGTH;
2068 /* Long data parameter has 16 bit length */
2069 parameter_length = tvb_get_letohs(tvb, offset);
2070 length_length = PARAMETER_LONG_DATA_LENGTH_LENGTH;
2073 if (sccp_tree && sccp_show_length)
2075 proto_tree_add_text(sccp_tree, tvb, offset, length_length,
2077 val_to_str(parameter_type, sccp_parameter_values,
2082 offset += length_length;
2084 dissect_sccp_parameter(tvb, pinfo, sccp_tree, tree, parameter_type, offset,
2087 return(parameter_length + length_length);
2090 /* FUNCTION dissect_sccp_optional_parameters():
2091 * Dissect all the optional parameters given the start of the optional
2092 * parameters into tvb. Parameter types and lengths are read from tvb.
2095 dissect_sccp_optional_parameters(tvbuff_t *tvb, packet_info *pinfo,
2096 proto_tree *sccp_tree, proto_tree *tree,
2099 guint8 parameter_type;
2101 while ((parameter_type = tvb_get_guint8(tvb, offset)) !=
2102 PARAMETER_END_OF_OPTIONAL_PARAMETERS) {
2104 offset += PARAMETER_TYPE_LENGTH;
2105 offset += dissect_sccp_variable_parameter(tvb, pinfo, sccp_tree, tree,
2106 parameter_type, offset);
2109 /* Process end of optional parameters */
2110 dissect_sccp_parameter(tvb, pinfo, sccp_tree, tree, parameter_type, offset,
2111 END_OF_OPTIONAL_PARAMETERS_LENGTH);
2115 static sccp_msg_info_t* new_ud_msg(packet_info* pinfo, guint32 msg_type _U_) {
2116 sccp_msg_info_t* m = ep_alloc0(sizeof(sccp_msg_info_t));
2117 m->framenum = pinfo->fd->num;
2118 m->data.ud.calling_gt = NULL;
2119 m->data.ud.called_gt = NULL;
2121 register_frame_end_routine(reset_sccp_assoc);
2126 dissect_sccp_message(tvbuff_t *tvb, packet_info *pinfo, proto_tree *sccp_tree,
2129 guint16 variable_pointer1 = 0, variable_pointer2 = 0, variable_pointer3 = 0;
2130 guint16 optional_pointer = 0, orig_opt_ptr = 0;
2132 gboolean save_fragmented;
2133 tvbuff_t *new_tvb = NULL;
2134 fragment_data *frag_msg = NULL;
2135 guint32 source_local_ref=0;
2137 guint msg_offset = tvb_offset_from_real_beginning(tvb);
2139 /* Macro for getting pointer to mandatory variable parameters */
2140 #define VARIABLE_POINTER(var, hf_var, ptr_size) \
2141 if (ptr_size == POINTER_LENGTH) \
2142 var = tvb_get_guint8(tvb, offset); \
2144 var = tvb_get_letohs(tvb, offset); \
2145 proto_tree_add_uint(sccp_tree, hf_var, tvb, \
2146 offset, ptr_size, var); \
2148 if (ptr_size == POINTER_LENGTH_LONG) \
2152 /* Macro for getting pointer to optional parameters */
2153 #define OPTIONAL_POINTER(ptr_size) \
2154 if (ptr_size == POINTER_LENGTH) \
2155 orig_opt_ptr = optional_pointer = tvb_get_guint8(tvb, offset); \
2157 orig_opt_ptr = optional_pointer = tvb_get_letohs(tvb, offset); \
2158 proto_tree_add_uint(sccp_tree, hf_sccp_optional_pointer, tvb, \
2159 offset, ptr_size, optional_pointer); \
2160 optional_pointer += offset; \
2161 if (ptr_size == POINTER_LENGTH_LONG) \
2162 optional_pointer += 1; \
2166 /* Extract the message type; all other processing is based on this */
2167 message_type = tvb_get_guint8(tvb, SCCP_MSG_TYPE_OFFSET);
2168 offset = SCCP_MSG_TYPE_LENGTH;
2170 if (check_col(pinfo->cinfo, COL_INFO)) {
2171 /* Do not change col_add_fstr() to col_append_fstr() here: we _want_
2172 * this call to overwrite whatever's currently in the INFO column (e.g.,
2173 * "DATA" from the SCTP dissector).
2175 * If there's something there that should not be overwritten, whoever
2176 * put that info there should call col_set_fence() to protect it.
2178 col_add_fstr(pinfo->cinfo, COL_INFO, "%s ",
2179 val_to_str(message_type, sccp_message_type_acro_values, "Unknown"));
2183 /* add the message type to the protocol tree */
2184 proto_tree_add_uint(sccp_tree, hf_sccp_message_type, tvb,
2185 SCCP_MSG_TYPE_OFFSET, SCCP_MSG_TYPE_LENGTH, message_type);
2189 /* Starting a new message dissection; clear the global assoc, SLR, and DLR values */
2194 no_assoc.calling_dpc = 0;
2195 no_assoc.called_dpc = 0;
2196 no_assoc.calling_ssn = INVALID_SSN;
2197 no_assoc.called_ssn = INVALID_SSN;
2198 no_assoc.has_fw_key = FALSE;
2199 no_assoc.has_bw_key = FALSE;
2200 no_assoc.payload = SCCP_PLOAD_NONE;
2201 no_assoc.called_party = NULL;
2202 no_assoc.calling_party = NULL;
2203 no_assoc.extra_info = NULL;
2205 switch(message_type) {
2206 case SCCP_MSG_TYPE_CR:
2207 /* TTC and NTT (Japan) say that the connection-oriented messages are
2208 * deleted (not standardized), but they appear to be used anyway, so
2209 * we'll dissect it...
2211 offset += dissect_sccp_parameter(tvb, pinfo, sccp_tree, tree,
2212 PARAMETER_SOURCE_LOCAL_REFERENCE,
2213 offset, SOURCE_LOCAL_REFERENCE_LENGTH);
2214 offset += dissect_sccp_parameter(tvb, pinfo, sccp_tree, tree,
2215 PARAMETER_CLASS, offset,
2216 PROTOCOL_CLASS_LENGTH);
2217 assoc = get_sccp_assoc(pinfo, msg_offset, slr, dlr, message_type);
2219 VARIABLE_POINTER(variable_pointer1, hf_sccp_variable_pointer1, POINTER_LENGTH)
2220 OPTIONAL_POINTER(POINTER_LENGTH)
2222 dissect_sccp_variable_parameter(tvb, pinfo, sccp_tree, tree,
2223 PARAMETER_CALLED_PARTY_ADDRESS,
2227 case SCCP_MSG_TYPE_CC:
2228 /* TODO: connection has been established; theoretically we could keep
2229 * keep track of the SLR/DLR with the called/calling from the CR and
2230 * track the connection (e.g., on subsequent messages regarding this
2231 * SLR we could set the global vars "call*_ssn" so data could get
2234 offset += dissect_sccp_parameter(tvb, pinfo, sccp_tree, tree,
2235 PARAMETER_DESTINATION_LOCAL_REFERENCE,
2237 DESTINATION_LOCAL_REFERENCE_LENGTH);
2238 offset += dissect_sccp_parameter(tvb, pinfo, sccp_tree, tree,
2239 PARAMETER_SOURCE_LOCAL_REFERENCE,
2240 offset, SOURCE_LOCAL_REFERENCE_LENGTH);
2242 assoc = get_sccp_assoc(pinfo, msg_offset, slr, dlr, message_type);
2244 offset += dissect_sccp_parameter(tvb, pinfo, sccp_tree, tree,
2245 PARAMETER_CLASS, offset,
2246 PROTOCOL_CLASS_LENGTH);
2247 OPTIONAL_POINTER(POINTER_LENGTH);
2250 case SCCP_MSG_TYPE_CREF:
2251 offset += dissect_sccp_parameter(tvb, pinfo, sccp_tree, tree,
2252 PARAMETER_DESTINATION_LOCAL_REFERENCE,
2254 DESTINATION_LOCAL_REFERENCE_LENGTH);
2256 assoc = get_sccp_assoc(pinfo, msg_offset, slr, dlr, message_type);
2258 offset += dissect_sccp_parameter(tvb, pinfo, sccp_tree, tree,
2259 PARAMETER_REFUSAL_CAUSE, offset,
2260 REFUSAL_CAUSE_LENGTH);
2261 OPTIONAL_POINTER(POINTER_LENGTH);
2264 case SCCP_MSG_TYPE_RLSD:
2265 offset += dissect_sccp_parameter(tvb, pinfo, sccp_tree, tree,
2266 PARAMETER_DESTINATION_LOCAL_REFERENCE,
2268 DESTINATION_LOCAL_REFERENCE_LENGTH);
2269 offset += dissect_sccp_parameter(tvb, pinfo, sccp_tree, tree,
2270 PARAMETER_SOURCE_LOCAL_REFERENCE,
2271 offset, SOURCE_LOCAL_REFERENCE_LENGTH);
2273 assoc = get_sccp_assoc(pinfo, msg_offset, slr, dlr, message_type);
2275 offset += dissect_sccp_parameter(tvb, pinfo, sccp_tree, tree,
2276 PARAMETER_RELEASE_CAUSE, offset,
2277 RELEASE_CAUSE_LENGTH);
2279 OPTIONAL_POINTER(POINTER_LENGTH);
2280 assoc = get_sccp_assoc(pinfo, msg_offset, slr, dlr, message_type);
2283 case SCCP_MSG_TYPE_RLC:
2284 offset += dissect_sccp_parameter(tvb, pinfo, sccp_tree, tree,
2285 PARAMETER_DESTINATION_LOCAL_REFERENCE,
2287 DESTINATION_LOCAL_REFERENCE_LENGTH);
2288 offset += dissect_sccp_parameter(tvb, pinfo, sccp_tree, tree,
2289 PARAMETER_SOURCE_LOCAL_REFERENCE,
2290 offset, SOURCE_LOCAL_REFERENCE_LENGTH);
2292 assoc = get_sccp_assoc(pinfo, msg_offset, slr, dlr, message_type);
2295 case SCCP_MSG_TYPE_DT1:
2296 source_local_ref = tvb_get_letoh24(tvb, offset);
2297 offset += dissect_sccp_parameter(tvb, pinfo, sccp_tree, tree,
2298 PARAMETER_DESTINATION_LOCAL_REFERENCE,
2300 DESTINATION_LOCAL_REFERENCE_LENGTH);
2302 assoc = get_sccp_assoc(pinfo, msg_offset, slr, dlr, message_type);
2304 more = tvb_get_guint8(tvb, offset) & SEGMENTING_REASSEMBLING_MASK;
2306 offset += dissect_sccp_parameter(tvb, pinfo, sccp_tree, tree,
2307 PARAMETER_SEGMENTING_REASSEMBLING,
2308 offset, SEGMENTING_REASSEMBLING_LENGTH);
2309 VARIABLE_POINTER(variable_pointer1, hf_sccp_variable_pointer1, POINTER_LENGTH)
2312 if (!sccp_xudt_desegment) {
2313 proto_tree_add_text(sccp_tree, tvb, variable_pointer1,
2314 tvb_get_guint8(tvb, variable_pointer1)+1,
2316 dissect_sccp_variable_parameter(tvb, pinfo, sccp_tree, tree,
2317 PARAMETER_DATA, variable_pointer1);
2320 save_fragmented = pinfo->fragmented;
2321 pinfo->fragmented = TRUE;
2322 frag_msg = fragment_add_seq_next(tvb, variable_pointer1 + 1, pinfo,
2323 source_local_ref, /* ID for fragments belonging together */
2324 sccp_xudt_msg_fragment_table, /* list of message fragments */
2325 sccp_xudt_msg_reassembled_table, /* list of reassembled messages */
2326 tvb_get_guint8(tvb,variable_pointer1), /* fragment length - to the end */
2327 more); /* More fragments? */
2329 new_tvb = process_reassembled_data(tvb, variable_pointer1 + 1, pinfo,
2330 "Reassembled SCCP", frag_msg,
2331 &sccp_xudt_msg_frag_items, NULL,
2334 if (frag_msg && frag_msg->next) { /* Reassembled */
2335 col_append_str(pinfo->cinfo, COL_INFO,
2336 "(Message reassembled) ");
2337 } else if (more) { /* Not last packet of reassembled message */
2338 col_append_str(pinfo->cinfo, COL_INFO, "(Message fragment) ");
2341 pinfo->fragmented = save_fragmented;
2344 dissect_sccp_data_param(new_tvb, pinfo, tree);
2347 /* End reassemble */
2350 case SCCP_MSG_TYPE_DT2:
2351 offset += dissect_sccp_parameter(tvb, pinfo, sccp_tree, tree,
2352 PARAMETER_DESTINATION_LOCAL_REFERENCE,
2354 DESTINATION_LOCAL_REFERENCE_LENGTH);
2356 assoc = get_sccp_assoc(pinfo, msg_offset, slr, dlr, message_type);
2358 offset += dissect_sccp_parameter(tvb, pinfo, sccp_tree, tree,
2359 PARAMETER_SEQUENCING_SEGMENTING, offset,
2360 SEQUENCING_SEGMENTING_LENGTH);
2363 case SCCP_MSG_TYPE_AK:
2364 offset += dissect_sccp_parameter(tvb, pinfo, sccp_tree, tree,
2365 PARAMETER_DESTINATION_LOCAL_REFERENCE,
2367 DESTINATION_LOCAL_REFERENCE_LENGTH);
2369 assoc = get_sccp_assoc(pinfo, msg_offset, slr, dlr, message_type);
2371 offset += dissect_sccp_parameter(tvb, pinfo, sccp_tree, tree,
2372 PARAMETER_RECEIVE_SEQUENCE_NUMBER,
2373 offset, RECEIVE_SEQUENCE_NUMBER_LENGTH);
2374 offset += dissect_sccp_parameter(tvb, pinfo, sccp_tree, tree,
2375 PARAMETER_CREDIT, offset, CREDIT_LENGTH);
2378 case SCCP_MSG_TYPE_UDT:
2379 pinfo->sccp_info = sccp_msg = new_ud_msg(pinfo,message_type);
2381 offset += dissect_sccp_parameter(tvb, pinfo, sccp_tree, tree,
2382 PARAMETER_CLASS, offset,
2383 PROTOCOL_CLASS_LENGTH);
2384 VARIABLE_POINTER(variable_pointer1, hf_sccp_variable_pointer1, POINTER_LENGTH)
2385 VARIABLE_POINTER(variable_pointer2, hf_sccp_variable_pointer2, POINTER_LENGTH)
2386 VARIABLE_POINTER(variable_pointer3, hf_sccp_variable_pointer3, POINTER_LENGTH)
2388 assoc = get_sccp_assoc(pinfo, msg_offset, slr, dlr, message_type);
2390 dissect_sccp_variable_parameter(tvb, pinfo, sccp_tree, tree,
2391 PARAMETER_CALLED_PARTY_ADDRESS,
2393 dissect_sccp_variable_parameter(tvb, pinfo, sccp_tree, tree,
2394 PARAMETER_CALLING_PARTY_ADDRESS,
2397 dissect_sccp_variable_parameter(tvb, pinfo, sccp_tree, tree, PARAMETER_DATA,
2401 case SCCP_MSG_TYPE_UDTS:
2402 pinfo->sccp_info = sccp_msg = new_ud_msg(pinfo,message_type);
2404 offset += dissect_sccp_parameter(tvb, pinfo, sccp_tree, tree,
2405 PARAMETER_RETURN_CAUSE, offset,
2406 RETURN_CAUSE_LENGTH);
2408 VARIABLE_POINTER(variable_pointer1, hf_sccp_variable_pointer1, POINTER_LENGTH)
2409 VARIABLE_POINTER(variable_pointer2, hf_sccp_variable_pointer2, POINTER_LENGTH)
2410 VARIABLE_POINTER(variable_pointer3, hf_sccp_variable_pointer3, POINTER_LENGTH)
2412 assoc = get_sccp_assoc(pinfo, msg_offset, slr, dlr, message_type);
2414 dissect_sccp_variable_parameter(tvb, pinfo, sccp_tree, tree,
2415 PARAMETER_CALLED_PARTY_ADDRESS,
2418 dissect_sccp_variable_parameter(tvb, pinfo, sccp_tree, tree,
2419 PARAMETER_CALLING_PARTY_ADDRESS,
2422 dissect_sccp_variable_parameter(tvb, pinfo, sccp_tree, tree, PARAMETER_DATA,
2426 case SCCP_MSG_TYPE_ED:
2427 offset += dissect_sccp_parameter(tvb, pinfo, sccp_tree, tree,
2428 PARAMETER_DESTINATION_LOCAL_REFERENCE,
2430 DESTINATION_LOCAL_REFERENCE_LENGTH);
2432 assoc = get_sccp_assoc(pinfo, msg_offset, slr, dlr, message_type);
2434 VARIABLE_POINTER(variable_pointer1, hf_sccp_variable_pointer1, POINTER_LENGTH);
2436 dissect_sccp_variable_parameter(tvb, pinfo, sccp_tree, tree, PARAMETER_DATA,
2440 case SCCP_MSG_TYPE_EA:
2441 offset += dissect_sccp_parameter(tvb, pinfo, sccp_tree, tree,
2442 PARAMETER_DESTINATION_LOCAL_REFERENCE,
2444 DESTINATION_LOCAL_REFERENCE_LENGTH);
2445 assoc = get_sccp_assoc(pinfo, msg_offset, slr, dlr, message_type);
2448 case SCCP_MSG_TYPE_RSR:
2449 offset += dissect_sccp_parameter(tvb, pinfo, sccp_tree, tree,
2450 PARAMETER_DESTINATION_LOCAL_REFERENCE,
2452 DESTINATION_LOCAL_REFERENCE_LENGTH);
2453 offset += dissect_sccp_parameter(tvb, pinfo, sccp_tree, tree,
2454 PARAMETER_SOURCE_LOCAL_REFERENCE,
2455 offset, SOURCE_LOCAL_REFERENCE_LENGTH);
2456 offset += dissect_sccp_parameter(tvb, pinfo, sccp_tree, tree,
2457 PARAMETER_RESET_CAUSE, offset,
2458 RESET_CAUSE_LENGTH);
2459 assoc = get_sccp_assoc(pinfo, msg_offset, slr, dlr, message_type);
2462 case SCCP_MSG_TYPE_RSC:
2463 offset += dissect_sccp_parameter(tvb, pinfo, sccp_tree, tree,
2464 PARAMETER_DESTINATION_LOCAL_REFERENCE,
2466 DESTINATION_LOCAL_REFERENCE_LENGTH);
2467 offset += dissect_sccp_parameter(tvb, pinfo, sccp_tree, tree,
2468 PARAMETER_SOURCE_LOCAL_REFERENCE,
2469 offset, SOURCE_LOCAL_REFERENCE_LENGTH);
2470 assoc = get_sccp_assoc(pinfo, msg_offset, slr, dlr, message_type);
2473 case SCCP_MSG_TYPE_ERR:
2474 offset += dissect_sccp_parameter(tvb, pinfo, sccp_tree, tree,
2475 PARAMETER_DESTINATION_LOCAL_REFERENCE,
2477 DESTINATION_LOCAL_REFERENCE_LENGTH);
2478 offset += dissect_sccp_parameter(tvb, pinfo, sccp_tree, tree,
2479 PARAMETER_ERROR_CAUSE, offset,
2480 ERROR_CAUSE_LENGTH);
2481 assoc = get_sccp_assoc(pinfo, msg_offset, slr, dlr, message_type);
2484 case SCCP_MSG_TYPE_IT:
2485 offset += dissect_sccp_parameter(tvb, pinfo, sccp_tree, tree,
2486 PARAMETER_DESTINATION_LOCAL_REFERENCE,
2488 DESTINATION_LOCAL_REFERENCE_LENGTH);
2489 offset += dissect_sccp_parameter(tvb, pinfo, sccp_tree, tree,
2490 PARAMETER_SOURCE_LOCAL_REFERENCE,
2491 offset, SOURCE_LOCAL_REFERENCE_LENGTH);
2492 assoc = get_sccp_assoc(pinfo, msg_offset, slr, dlr, message_type);
2493 offset += dissect_sccp_parameter(tvb, pinfo, sccp_tree, tree,
2494 PARAMETER_CLASS, offset,
2495 PROTOCOL_CLASS_LENGTH);
2496 offset += dissect_sccp_parameter(tvb, pinfo, sccp_tree, tree,
2497 PARAMETER_SEQUENCING_SEGMENTING,
2498 offset, SEQUENCING_SEGMENTING_LENGTH);
2499 offset += dissect_sccp_parameter(tvb, pinfo, sccp_tree, tree,
2500 PARAMETER_CREDIT, offset, CREDIT_LENGTH);
2503 case SCCP_MSG_TYPE_XUDT:
2504 pinfo->sccp_info = sccp_msg = new_ud_msg(pinfo,message_type);
2505 offset += dissect_sccp_parameter(tvb, pinfo, sccp_tree, tree,
2506 PARAMETER_CLASS, offset,
2507 PROTOCOL_CLASS_LENGTH);
2508 offset += dissect_sccp_parameter(tvb, pinfo, sccp_tree, tree,
2509 PARAMETER_HOP_COUNTER, offset,
2510 HOP_COUNTER_LENGTH);
2512 VARIABLE_POINTER(variable_pointer1, hf_sccp_variable_pointer1, POINTER_LENGTH)
2513 VARIABLE_POINTER(variable_pointer2, hf_sccp_variable_pointer2, POINTER_LENGTH)
2514 VARIABLE_POINTER(variable_pointer3, hf_sccp_variable_pointer3, POINTER_LENGTH)
2515 OPTIONAL_POINTER(POINTER_LENGTH)
2517 /* Optional parameters are Segmentation and Importance
2518 * NOTE 2 - Segmentation Should not be present in case of a single XUDT
2522 assoc = get_sccp_assoc(pinfo, msg_offset, slr, dlr, message_type);
2524 dissect_sccp_variable_parameter(tvb, pinfo, sccp_tree, tree,
2525 PARAMETER_CALLED_PARTY_ADDRESS,
2527 dissect_sccp_variable_parameter(tvb, pinfo, sccp_tree, tree,
2528 PARAMETER_CALLING_PARTY_ADDRESS,
2531 if (tvb_get_guint8(tvb, optional_pointer) == PARAMETER_SEGMENTATION){
2532 if (!sccp_xudt_desegment){
2533 proto_tree_add_text(sccp_tree, tvb, variable_pointer3, tvb_get_guint8(tvb, variable_pointer3)+1, "Segmented Data");
2536 gboolean more_frag = TRUE;
2539 /* Get the first octet of parameter Segmentation, Ch 3.17 in Q.713
2540 * Bit 8 of octet 1 is used for First segment indication
2541 * Bit 7 of octet 1 is used to keep in the message in sequence
2542 * delivery option required by the SCCP user
2543 * Bits 6 and 5 in octet 1 are spare bits.
2544 * Bits 4-1 of octet 1 are used to indicate the number of
2545 * remaining segments.
2546 * The values 0000 to 1111 are possible; the value 0000 indicates
2549 octet = tvb_get_guint8(tvb,optional_pointer+2);
2550 source_local_ref = tvb_get_letoh24(tvb, optional_pointer+3);
2552 if ((octet&0x0f) == 0)
2555 save_fragmented = pinfo->fragmented;
2556 pinfo->fragmented = TRUE;
2557 frag_msg = fragment_add_seq_next(tvb, variable_pointer3 + 1, pinfo,
2558 source_local_ref, /* ID for fragments belonging together */
2559 sccp_xudt_msg_fragment_table, /* list of message fragments */
2560 sccp_xudt_msg_reassembled_table, /* list of reassembled messages */
2561 tvb_get_guint8(tvb,variable_pointer3), /* fragment length - to the end */
2562 more_frag); /* More fragments? */
2564 if ((octet&0x80) == 0x80) /*First segment, set number of segments*/
2565 fragment_set_tot_len(pinfo, source_local_ref, sccp_xudt_msg_fragment_table,(octet & 0xf));
2567 new_tvb = process_reassembled_data(tvb, variable_pointer3 + 1,
2568 pinfo, "Reassembled SCCP",
2570 &sccp_xudt_msg_frag_items,
2573 if (frag_msg) { /* Reassembled */
2574 col_append_str(pinfo->cinfo, COL_INFO,"(Message reassembled) ");
2575 } else { /* Not last packet of reassembled message */
2576 col_append_str(pinfo->cinfo, COL_INFO,"(Message fragment) ");
2579 pinfo->fragmented = save_fragmented;
2582 dissect_sccp_data_param(new_tvb, pinfo, tree);
2585 dissect_sccp_variable_parameter(tvb, pinfo, sccp_tree, tree,
2586 PARAMETER_DATA, variable_pointer3);
2590 case SCCP_MSG_TYPE_XUDTS:
2591 pinfo->sccp_info = sccp_msg = new_ud_msg(pinfo,message_type);
2592 offset += dissect_sccp_parameter(tvb, pinfo, sccp_tree, tree,
2593 PARAMETER_RETURN_CAUSE, offset,
2594 RETURN_CAUSE_LENGTH);
2595 offset += dissect_sccp_parameter(tvb, pinfo, sccp_tree, tree,
2596 PARAMETER_HOP_COUNTER, offset,
2597 HOP_COUNTER_LENGTH);
2599 VARIABLE_POINTER(variable_pointer1, hf_sccp_variable_pointer1, POINTER_LENGTH)
2600 VARIABLE_POINTER(variable_pointer2, hf_sccp_variable_pointer2, POINTER_LENGTH)
2601 VARIABLE_POINTER(variable_pointer3, hf_sccp_variable_pointer3, POINTER_LENGTH)
2602 OPTIONAL_POINTER(POINTER_LENGTH)
2604 assoc = get_sccp_assoc(pinfo, msg_offset, slr, dlr, message_type);
2606 dissect_sccp_variable_parameter(tvb, pinfo, sccp_tree, tree,
2607 PARAMETER_CALLED_PARTY_ADDRESS,
2609 dissect_sccp_variable_parameter(tvb, pinfo, sccp_tree, tree,
2610 PARAMETER_CALLING_PARTY_ADDRESS,
2613 if (tvb_get_guint8(tvb, optional_pointer) == PARAMETER_SEGMENTATION){
2614 if (!sccp_xudt_desegment){
2615 proto_tree_add_text(sccp_tree, tvb, variable_pointer3, tvb_get_guint8(tvb, variable_pointer3)+1, "Segmented Data");
2619 gboolean more_frag = TRUE;
2622 /* Get the first octet of parameter Segmentation, Ch 3.17 in Q.713
2623 * Bit 8 of octet 1 is used for First segment indication
2624 * Bit 7 of octet 1 is used to keep in the message in sequence
2625 * delivery option required by the SCCP user
2626 * Bits 6 and 5 in octet 1 are spare bits.
2627 * Bits 4-1 of octet 1 are used to indicate the number of
2628 * remaining segments.
2629 * The values 0000 to 1111 are possible; the value 0000 indicates
2632 octet = tvb_get_guint8(tvb,optional_pointer+2);
2633 source_local_ref = tvb_get_letoh24(tvb, optional_pointer+3);
2635 if ((octet&0x0f) == 0)
2638 save_fragmented = pinfo->fragmented;
2639 pinfo->fragmented = TRUE;
2640 frag_msg = fragment_add_seq_next(tvb, variable_pointer3 + 1, pinfo,
2641 source_local_ref, /* ID for fragments belonging together */
2642 sccp_xudt_msg_fragment_table, /* list of message fragments */
2643 sccp_xudt_msg_reassembled_table, /* list of reassembled messages */
2644 tvb_get_guint8(tvb,variable_pointer3), /* fragment length - to the end */
2645 more_frag); /* More fragments? */
2647 if ((octet&0x80) == 0x80) /*First segment, set number of segments*/
2648 fragment_set_tot_len(pinfo, source_local_ref, sccp_xudt_msg_fragment_table,(octet & 0xf));
2650 new_tvb = process_reassembled_data(tvb, variable_pointer3 + 1,
2651 pinfo, "Reassembled SCCP",
2653 &sccp_xudt_msg_frag_items,
2656 if (frag_msg) { /* Reassembled */
2657 col_append_str(pinfo->cinfo, COL_INFO,
2658 "(Message reassembled) ");
2659 } else { /* Not last packet of reassembled message */
2660 col_append_str(pinfo->cinfo, COL_INFO,
2661 "(Message fragment) ");
2664 pinfo->fragmented = save_fragmented;
2667 dissect_sccp_data_param(new_tvb, pinfo, tree);
2670 dissect_sccp_variable_parameter(tvb, pinfo, sccp_tree, tree,
2671 PARAMETER_DATA, variable_pointer3);
2675 case SCCP_MSG_TYPE_LUDT:
2676 pinfo->sccp_info = sccp_msg = new_ud_msg(pinfo,message_type);
2678 offset += dissect_sccp_parameter(tvb, pinfo, sccp_tree, tree,
2679 PARAMETER_CLASS, offset,
2680 PROTOCOL_CLASS_LENGTH);
2681 offset += dissect_sccp_parameter(tvb, pinfo, sccp_tree, tree,
2682 PARAMETER_HOP_COUNTER, offset,
2683 HOP_COUNTER_LENGTH);
2685 VARIABLE_POINTER(variable_pointer1, hf_sccp_variable_pointer1, POINTER_LENGTH_LONG)
2686 VARIABLE_POINTER(variable_pointer2, hf_sccp_variable_pointer2, POINTER_LENGTH_LONG)
2687 VARIABLE_POINTER(variable_pointer3, hf_sccp_variable_pointer3, POINTER_LENGTH_LONG)
2688 OPTIONAL_POINTER(POINTER_LENGTH_LONG)
2690 assoc = get_sccp_assoc(pinfo, msg_offset, slr, dlr, message_type);
2692 dissect_sccp_variable_parameter(tvb, pinfo, sccp_tree, tree,
2693 PARAMETER_CALLED_PARTY_ADDRESS,
2695 dissect_sccp_variable_parameter(tvb, pinfo, sccp_tree, tree,
2696 PARAMETER_CALLING_PARTY_ADDRESS,
2698 dissect_sccp_variable_parameter(tvb, pinfo, sccp_tree, tree,
2699 PARAMETER_LONG_DATA, variable_pointer3);
2702 case SCCP_MSG_TYPE_LUDTS:
2703 pinfo->sccp_info = sccp_msg = new_ud_msg(pinfo,message_type);
2704 offset += dissect_sccp_parameter(tvb, pinfo, sccp_tree, tree,
2705 PARAMETER_RETURN_CAUSE, offset,
2706 RETURN_CAUSE_LENGTH);
2707 offset += dissect_sccp_parameter(tvb, pinfo, sccp_tree, tree,
2708 PARAMETER_HOP_COUNTER, offset,
2709 HOP_COUNTER_LENGTH);
2711 VARIABLE_POINTER(variable_pointer1, hf_sccp_variable_pointer1, POINTER_LENGTH_LONG)
2712 VARIABLE_POINTER(variable_pointer2, hf_sccp_variable_pointer2, POINTER_LENGTH_LONG)
2713 VARIABLE_POINTER(variable_pointer3, hf_sccp_variable_pointer3, POINTER_LENGTH_LONG)
2714 OPTIONAL_POINTER(POINTER_LENGTH_LONG)
2716 assoc = get_sccp_assoc(pinfo, msg_offset, slr, dlr, message_type);
2718 dissect_sccp_variable_parameter(tvb, pinfo, sccp_tree, tree,
2719 PARAMETER_CALLED_PARTY_ADDRESS,
2721 dissect_sccp_variable_parameter(tvb, pinfo, sccp_tree, tree,
2722 PARAMETER_CALLING_PARTY_ADDRESS,
2724 dissect_sccp_variable_parameter(tvb, pinfo, sccp_tree, tree,
2725 PARAMETER_LONG_DATA, variable_pointer3);
2729 dissect_sccp_unknown_message(tvb, sccp_tree);
2733 dissect_sccp_optional_parameters(tvb, pinfo, sccp_tree, tree,
2736 if (trace_sccp && assoc && assoc != &no_assoc) {
2737 proto_item* pi = proto_tree_add_uint(sccp_tree,hf_sccp_assoc_id,tvb,0,0,assoc->id);
2738 proto_tree* pt = proto_item_add_subtree(pi,ett_sccp_assoc);
2739 PROTO_ITEM_SET_GENERATED(pi);
2742 for(m = assoc->msgs; m ; m = m->data.co.next) {
2743 pi = proto_tree_add_uint( pt,hf_sccp_assoc_msg,tvb,0,0,m->framenum);
2745 if (assoc->payload != SCCP_PLOAD_NONE)
2746 proto_item_append_text(pi," %s", val_to_str(assoc->payload, assoc_protos, "Unknown"));
2748 if (m->data.co.label)
2749 proto_item_append_text(pi," %s", m->data.co.label);
2751 if (m->framenum == pinfo->fd->num && m->offset == msg_offset ) {
2752 tap_queue_packet(sccp_tap, pinfo, m);
2753 proto_item_append_text(pi," (current)");
2755 PROTO_ITEM_SET_GENERATED(pi);
2763 dissect_sccp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
2765 proto_item *sccp_item = NULL;
2766 proto_tree *sccp_tree = NULL;
2767 const mtp3_addr_pc_t *mtp3_addr_p;
2769 if ((pinfo->src.type == AT_SS7PC) &&
2770 ((mtp3_addr_p = (const mtp3_addr_pc_t *)pinfo->src.data)->type <= CHINESE_ITU_STANDARD))
2773 * Allow a protocol beneath to specify how the SCCP layer should be
2776 * It is possible to have multiple sets of SCCP traffic some of which is
2777 * ITU and some of which is ANSI.
2778 * An example is A-interface traffic having ANSI MTP3/ANSI SCCP/3GPP2 IOS
2779 * and at the same time ITU MTP3/ITU SCCP/ANSI TCAP/ANSI MAP.
2781 decode_mtp3_standard = mtp3_addr_p->type;
2785 decode_mtp3_standard = mtp3_standard;
2788 /* Make entry in the Protocol column on summary display */
2789 if (check_col(pinfo->cinfo, COL_PROTOCOL))
2790 switch(decode_mtp3_standard) {
2792 col_set_str(pinfo->cinfo, COL_PROTOCOL, "SCCP (Int. ITU)");
2795 col_set_str(pinfo->cinfo, COL_PROTOCOL, "SCCP (ANSI)");
2797 case CHINESE_ITU_STANDARD:
2798 col_set_str(pinfo->cinfo, COL_PROTOCOL, "SCCP (Chin. ITU)");
2800 case JAPAN_STANDARD:
2801 col_set_str(pinfo->cinfo, COL_PROTOCOL, "SCCP (Japan)");
2805 /* In the interest of speed, if "tree" is NULL, don't do any work not
2806 necessary to generate protocol tree items. */
2808 /* create the sccp protocol tree */
2809 sccp_item = proto_tree_add_item(tree, proto_sccp, tvb, 0, -1, FALSE);
2810 sccp_tree = proto_item_add_subtree(sccp_item, ett_sccp);
2813 /* Set whether message is UPLINK, DOWNLINK, or of UNKNOWN direction */
2815 if (pinfo->src.type == AT_SS7PC)
2818 * XXX - we assume that the "data" pointers of the source and destination
2819 * addresses are set to point to "mtp3_addr_pc_t" structures, so that
2820 * we can safely cast them.
2822 mtp3_addr_p = (const mtp3_addr_pc_t *)pinfo->src.data;
2824 if (sccp_source_pc_global == mtp3_addr_p->pc)
2826 pinfo->p2p_dir = P2P_DIR_SENT;
2830 /* assuming if src was SS7 PC then dst will be too */
2831 mtp3_addr_p = (const mtp3_addr_pc_t *)pinfo->dst.data;
2833 if (sccp_source_pc_global == mtp3_addr_p->pc)
2835 pinfo->p2p_dir = P2P_DIR_RECV;
2839 pinfo->p2p_dir = P2P_DIR_UNKNOWN;
2844 /* dissect the message */
2845 dissect_sccp_message(tvb, pinfo, sccp_tree, tree);
2849 /*** SccpUsers Table **/
2851 static struct _sccp_ul {
2854 dissector_handle_t* handlep;
2856 {SCCP_USER_DATA,FALSE,&data_handle},
2857 {SCCP_USER_TCAP,FALSE,&tcap_handle},
2858 {SCCP_USER_RANAP,FALSE,&ranap_handle},
2859 {SCCP_USER_BSSAP,FALSE,&bssap_handle},
2860 {SCCP_USER_GSMMAP,TRUE,&gsmmap_handle},
2861 {SCCP_USER_CAMEL,TRUE,&camel_handle},
2862 {SCCP_USER_INAP,TRUE,&inap_handle},
2866 static void sccp_users_update_cb(void* r, const char** err _U_) {
2870 for (c=user_list; c->handlep; c++) {
2871 if (c->id == u->user) {
2872 u->uses_tcap = c->uses_tcap;
2873 u->handlep = c->handlep;
2878 u->uses_tcap = FALSE;
2879 u->handlep = &data_handle;
2882 static void* sccp_users_copy_cb(void* n, const void* o, unsigned siz _U_) {
2883 const sccp_user_t* u = o;
2884 sccp_user_t* un = n;
2888 un->uses_tcap = u->uses_tcap;
2889 un->handlep = u->handlep;
2890 if (u->called_pc) un->called_pc = range_copy(u->called_pc);
2891 if (u->called_ssn) un->called_ssn = range_copy(u->called_ssn);
2896 static void sccp_users_free_cb(void*r) {
2898 if (u->called_pc) g_free(u->called_pc);
2899 if (u->called_ssn) g_free(u->called_ssn);
2903 UAT_DEC_CB_DEF(sccp_users, ni, sccp_user_t)
2904 UAT_RANGE_CB_DEF(sccp_users,called_pc,sccp_user_t)
2905 UAT_RANGE_CB_DEF(sccp_users,called_ssn,sccp_user_t)
2906 UAT_VS_DEF(sccp_users, user, sccp_user_t, SCCP_USER_DATA, "Data")
2908 /** End SccpUsersTable **/
2911 static void init_sccp(void) {
2913 fragment_table_init (&sccp_xudt_msg_fragment_table);
2914 reassembled_table_init(&sccp_xudt_msg_reassembled_table);
2918 /* Register the protocol with Wireshark */
2920 proto_register_sccp(void)
2922 /* Setup list of header fields */
2923 static hf_register_info hf[] = {
2924 { &hf_sccp_message_type,
2925 { "Message Type", "sccp.message_type",
2926 FT_UINT8, BASE_HEX, VALS(sccp_message_type_values), 0x0,
2928 { &hf_sccp_variable_pointer1,
2929 { "Pointer to first Mandatory Variable parameter", "sccp.variable_pointer1",
2930 FT_UINT16, BASE_DEC, NULL, 0x0,
2932 { &hf_sccp_variable_pointer2,
2933 { "Pointer to second Mandatory Variable parameter", "sccp.variable_pointer2",
2934 FT_UINT16, BASE_DEC, NULL, 0x0,
2936 { &hf_sccp_variable_pointer3,
2937 { "Pointer to third Mandatory Variable parameter", "sccp.variable_pointer3",
2938 FT_UINT16, BASE_DEC, NULL, 0x0,
2940 { &hf_sccp_optional_pointer,
2941 { "Pointer to Optional parameter", "sccp.optional_pointer",
2942 FT_UINT16, BASE_DEC, NULL, 0x0,
2945 { "Called or Calling SubSystem Number", "sccp.ssn",
2946 FT_UINT8, BASE_DEC, VALS(sccp_ssn_values), 0x0,
2948 { &hf_sccp_gt_digits,
2949 { "Called or Calling GT Digits",
2951 FT_STRING, BASE_NONE, NULL, 0x0,
2953 { &hf_sccp_called_national_indicator,
2954 { "National Indicator", "sccp.called.ni",
2955 FT_UINT8, BASE_HEX, VALS(sccp_national_indicator_values), ANSI_NATIONAL_MASK,
2957 { &hf_sccp_called_routing_indicator,
2958 { "Routing Indicator", "sccp.called.ri",
2959 FT_UINT8, BASE_HEX, VALS(sccp_routing_indicator_values), ROUTING_INDICATOR_MASK,
2961 { &hf_sccp_called_itu_global_title_indicator,
2962 { "Global Title Indicator", "sccp.called.gti",
2963 FT_UINT8, BASE_HEX, VALS(sccp_itu_global_title_indicator_values), GTI_MASK,
2965 { &hf_sccp_called_ansi_global_title_indicator,
2966 { "Global Title Indicator", "sccp.called.gti",
2967 FT_UINT8, BASE_HEX, VALS(sccp_ansi_global_title_indicator_values), GTI_MASK,
2969 { &hf_sccp_called_itu_ssn_indicator,
2970 { "SubSystem Number Indicator", "sccp.called.ssni",
2971 FT_UINT8, BASE_HEX, VALS(sccp_ai_ssni_values), ITU_SSN_INDICATOR_MASK,
2973 { &hf_sccp_called_itu_point_code_indicator,
2974 { "Point Code Indicator", "sccp.called.pci",
2975 FT_UINT8, BASE_HEX, VALS(sccp_ai_pci_values), ITU_PC_INDICATOR_MASK,
2977 { &hf_sccp_called_ansi_ssn_indicator,
2978 { "SubSystem Number Indicator", "sccp.called.ssni",
2979 FT_UINT8, BASE_HEX, VALS(sccp_ai_ssni_values), ANSI_SSN_INDICATOR_MASK,
2981 { &hf_sccp_called_ansi_point_code_indicator,
2982 { "Point Code Indicator", "sccp.called.pci",
2983 FT_UINT8, BASE_HEX, VALS(sccp_ai_pci_values), ANSI_PC_INDICATOR_MASK,
2985 { &hf_sccp_called_ssn,
2986 { "SubSystem Number", "sccp.called.ssn",
2987 FT_UINT8, BASE_DEC, VALS(sccp_ssn_values), 0x0,
2989 { &hf_sccp_called_itu_pc,
2990 { "PC", "sccp.called.pc",
2991 FT_UINT16, BASE_DEC, NULL, ITU_PC_MASK,
2993 { &hf_sccp_called_ansi_pc,
2994 { "PC", "sccp.called.ansi_pc",
2995 FT_STRING, BASE_NONE, NULL, 0x0,
2997 { &hf_sccp_called_chinese_pc,
2998 { "PC", "sccp.called.chinese_pc",
2999 FT_STRING, BASE_NONE, NULL, 0x0,
3001 { &hf_sccp_called_japan_pc,
3002 { "PC", "sccp.called.pc",
3003 FT_UINT16, BASE_DEC, NULL, 0x0,
3005 { &hf_sccp_called_pc_network,
3007 "sccp.called.network",
3008 FT_UINT24, BASE_DEC, NULL, ANSI_NETWORK_MASK,
3010 { &hf_sccp_called_pc_cluster,
3012 "sccp.called.cluster",
3013 FT_UINT24, BASE_DEC, NULL, ANSI_CLUSTER_MASK,
3015 { &hf_sccp_called_pc_member,
3017 "sccp.called.member",
3018 FT_UINT24, BASE_DEC, NULL, ANSI_MEMBER_MASK,
3020 { &hf_sccp_called_gt_nai,
3021 { "Nature of Address Indicator",
3023 FT_UINT8, BASE_HEX, VALS(sccp_nai_values), GT_NAI_MASK,
3025 { &hf_sccp_called_gt_oe,
3026 { "Odd/Even Indicator",
3028 FT_UINT8, BASE_HEX, VALS(sccp_oe_values), GT_OE_MASK,
3030 { &hf_sccp_called_gt_tt,
3031 { "Translation Type",
3033 FT_UINT8, BASE_HEX, NULL, 0x0,
3035 { &hf_sccp_called_gt_np,
3038 FT_UINT8, BASE_HEX, VALS(sccp_np_values), GT_NP_MASK,
3040 { &hf_sccp_called_gt_es,
3041 { "Encoding Scheme",
3043 FT_UINT8, BASE_HEX, VALS(sccp_es_values), GT_ES_MASK,
3045 { &hf_sccp_called_gt_digits,
3047 "sccp.called.digits",
3048 FT_STRING, BASE_NONE, NULL, 0x0,
3050 { &hf_sccp_calling_national_indicator,
3051 { "National Indicator", "sccp.calling.ni",
3052 FT_UINT8, BASE_HEX, VALS(sccp_national_indicator_values), ANSI_NATIONAL_MASK,
3054 { &hf_sccp_calling_routing_indicator,
3055 { "Routing Indicator", "sccp.calling.ri",
3056 FT_UINT8, BASE_HEX, VALS(sccp_routing_indicator_values), ROUTING_INDICATOR_MASK,
3058 { &hf_sccp_calling_itu_global_title_indicator,
3059 { "Global Title Indicator", "sccp.calling.gti",
3060 FT_UINT8, BASE_HEX, VALS(sccp_itu_global_title_indicator_values), GTI_MASK,
3062 { &hf_sccp_calling_ansi_global_title_indicator,
3063 { "Global Title Indicator", "sccp.calling.gti",
3064 FT_UINT8, BASE_HEX, VALS(sccp_ansi_global_title_indicator_values), GTI_MASK,
3066 { &hf_sccp_calling_itu_ssn_indicator,
3067 { "SubSystem Number Indicator", "sccp.calling.ssni",
3068 FT_UINT8, BASE_HEX, VALS(sccp_ai_ssni_values), ITU_SSN_INDICATOR_MASK,
3070 { &hf_sccp_calling_itu_point_code_indicator,
3071 { "Point Code Indicator", "sccp.calling.pci",
3072 FT_UINT8, BASE_HEX, VALS(sccp_ai_pci_values), ITU_PC_INDICATOR_MASK,
3074 { &hf_sccp_calling_ansi_ssn_indicator,
3075 { "SubSystem Number Indicator", "sccp.calling.ssni",
3076 FT_UINT8, BASE_HEX, VALS(sccp_ai_ssni_values), ANSI_SSN_INDICATOR_MASK,
3078 { &hf_sccp_calling_ansi_point_code_indicator,
3079 { "Point Code Indicator", "sccp.calling.pci",
3080 FT_UINT8, BASE_HEX, VALS(sccp_ai_pci_values), ANSI_PC_INDICATOR_MASK,
3082 { &hf_sccp_calling_ssn,
3083 { "SubSystem Number", "sccp.calling.ssn",
3084 FT_UINT8, BASE_DEC, VALS(sccp_ssn_values), 0x0,
3086 { &hf_sccp_calling_itu_pc,
3087 { "PC", "sccp.calling.pc",
3088 FT_UINT16, BASE_DEC, NULL, ITU_PC_MASK,
3090 { &hf_sccp_calling_ansi_pc,
3091 { "PC", "sccp.calling.ansi_pc",
3092 FT_STRING, BASE_NONE, NULL, 0x0,
3094 { &hf_sccp_calling_chinese_pc,
3095 { "PC", "sccp.calling.chinese_pc",
3096 FT_STRING, BASE_NONE, NULL, 0x0,
3098 { &hf_sccp_calling_japan_pc,
3099 { "PC", "sccp.calling.pc",
3100 FT_UINT16, BASE_DEC, NULL, 0x0,
3102 { &hf_sccp_calling_pc_network,
3104 "sccp.calling.network",
3105 FT_UINT24, BASE_DEC, NULL, ANSI_NETWORK_MASK,
3107 { &hf_sccp_calling_pc_cluster,
3109 "sccp.calling.cluster",
3110 FT_UINT24, BASE_DEC, NULL, ANSI_CLUSTER_MASK,
3112 { &hf_sccp_calling_pc_member,
3114 "sccp.calling.member",
3115 FT_UINT24, BASE_DEC, NULL, ANSI_MEMBER_MASK,
3117 { &hf_sccp_calling_gt_nai,
3118 { "Nature of Address Indicator",
3120 FT_UINT8, BASE_HEX, VALS(sccp_nai_values), GT_NAI_MASK,
3122 { &hf_sccp_calling_gt_oe,
3123 { "Odd/Even Indicator",
3125 FT_UINT8, BASE_HEX, VALS(sccp_oe_values), GT_OE_MASK,
3127 { &hf_sccp_calling_gt_tt,
3128 { "Translation Type",
3130 FT_UINT8, BASE_HEX, NULL, 0x0,
3132 { &hf_sccp_calling_gt_np,
3135 FT_UINT8, BASE_HEX, VALS(sccp_np_values), GT_NP_MASK,
3137 { &hf_sccp_calling_gt_es,
3138 { "Encoding Scheme",
3140 FT_UINT8, BASE_HEX, VALS(sccp_es_values), GT_ES_MASK,
3142 { &hf_sccp_calling_gt_digits,
3144 "sccp.calling.digits",
3145 FT_STRING, BASE_NONE, NULL, 0x0,
3148 { "Destination Local Reference", "sccp.dlr",
3149 FT_UINT24, BASE_HEX, NULL, 0x0,
3152 { "Source Local Reference", "sccp.slr",
3153 FT_UINT24, BASE_HEX, NULL, 0x0,
3156 { "Local Reference", "sccp.lr",
3157 FT_UINT24, BASE_HEX, NULL, 0x0,
3160 { "Class", "sccp.class",
3161 FT_UINT8, BASE_HEX, NULL, CLASS_CLASS_MASK,
3163 { &hf_sccp_handling,
3164 { "Message handling", "sccp.handling",
3165 FT_UINT8, BASE_HEX, VALS(sccp_class_handling_values), CLASS_SPARE_HANDLING_MASK,
3168 { "More data", "sccp.more",
3169 FT_UINT8, BASE_HEX, VALS(sccp_segmenting_reassembling_values), SEGMENTING_REASSEMBLING_MASK,
3172 { "Receive Sequence Number", "sccp.rsn",
3173 FT_UINT8, BASE_HEX, NULL, RSN_MASK,
3175 { &hf_sccp_sequencing_segmenting_ssn,
3176 { "Sequencing Segmenting: Send Sequence Number", "sccp.sequencing_segmenting.ssn",
3177 FT_UINT8, BASE_HEX, NULL, SEND_SEQUENCE_NUMBER_MASK,
3179 { &hf_sccp_sequencing_segmenting_rsn,
3180 { "Sequencing Segmenting: Receive Sequence Number", "sccp.sequencing_segmenting.rsn",
3181 FT_UINT8, BASE_HEX, NULL, RECEIVE_SEQUENCE_NUMBER_MASK,
3183 { &hf_sccp_sequencing_segmenting_more,
3184 { "Sequencing Segmenting: More", "sccp.sequencing_segmenting.more",
3185 FT_UINT8, BASE_HEX, VALS(sccp_segmenting_reassembling_values), SEQUENCING_SEGMENTING_MORE_MASK,
3188 { "Credit", "sccp.credit",
3189 FT_UINT8, BASE_HEX, NULL, 0x0,
3191 { &hf_sccp_release_cause,
3192 { "Release Cause", "sccp.release_cause",
3193 FT_UINT8, BASE_HEX, VALS(sccp_release_cause_values), 0x0,
3195 { &hf_sccp_return_cause,
3196 { "Return Cause", "sccp.return_cause",
3197 FT_UINT8, BASE_HEX, VALS(sccp_return_cause_values), 0x0,
3199 { &hf_sccp_reset_cause,
3200 { "Reset Cause", "sccp.reset_cause",
3201 FT_UINT8, BASE_HEX, VALS(sccp_reset_cause_values), 0x0,
3203 { &hf_sccp_error_cause,
3204 { "Error Cause", "sccp.error_cause",
3205 FT_UINT8, BASE_HEX, VALS(sccp_error_cause_values), 0x0,
3207 { &hf_sccp_refusal_cause,
3208 { "Refusal Cause", "sccp.refusal_cause",
3209 FT_UINT8, BASE_HEX, VALS(sccp_refusal_cause_values), 0x0,
3211 { &hf_sccp_segmentation_first,
3212 { "Segmentation: First", "sccp.segmentation.first",
3213 FT_UINT8, BASE_HEX, VALS(sccp_segmentation_first_segment_values), SEGMENTATION_FIRST_SEGMENT_MASK,
3215 { &hf_sccp_segmentation_class,
3216 { "Segmentation: Class", "sccp.segmentation.class",
3217 FT_UINT8, BASE_HEX, VALS(sccp_segmentation_class_values), SEGMENTATION_CLASS_MASK,
3219 { &hf_sccp_segmentation_remaining,
3220 { "Segmentation: Remaining", "sccp.segmentation.remaining",
3221 FT_UINT8, BASE_HEX, NULL, SEGMENTATION_REMAINING_MASK,
3223 { &hf_sccp_segmentation_slr,
3224 { "Segmentation: Source Local Reference", "sccp.segmentation.slr",
3225 FT_UINT24, BASE_HEX, NULL, 0x0,
3227 { &hf_sccp_hop_counter,
3228 { "Hop Counter", "sccp.hops",
3229 FT_UINT8, BASE_HEX, NULL, 0x0,
3231 { &hf_sccp_importance,
3232 { "Importance", "sccp.importance",
3233 FT_UINT8, BASE_HEX, NULL, IMPORTANCE_IMPORTANCE_MASK,
3235 /* ISNI is ANSI only */
3236 { &hf_sccp_ansi_isni_mi,
3237 { "ISNI Mark for Identification Indicator", "sccp.isni.mi",
3238 FT_UINT8, BASE_HEX, VALS(sccp_isni_mark_for_id_values), ANSI_ISNI_MI_MASK,
3240 { &hf_sccp_ansi_isni_iri,
3241 { "ISNI Routing Indicator", "sccp.isni.iri",
3242 FT_UINT8, BASE_HEX, VALS(sccp_isni_iri_values), ANSI_ISNI_IRI_MASK,
3244 { &hf_sccp_ansi_isni_ti,
3245 { "ISNI Type Indicator", "sccp.isni.ti",
3246 FT_UINT8, BASE_HEX, VALS(sccp_isni_ti_values), ANSI_ISNI_TI_MASK,
3248 { &hf_sccp_ansi_isni_netspec,
3249 { "ISNI Network Specific (Type 1)", "sccp.isni.netspec",
3250 FT_UINT8, BASE_HEX, NULL, ANSI_ISNI_NETSPEC_MASK,
3252 { &hf_sccp_ansi_isni_counter,
3253 { "ISNI Counter", "sccp.isni.counter",
3254 FT_UINT8, BASE_DEC, NULL, ANSI_ISNI_COUNTER_MASK,
3256 {&hf_sccp_xudt_msg_fragments,
3257 {"Message fragments", "sccp.msg.fragments",
3258 FT_NONE, BASE_NONE, NULL, 0x00, NULL, HFILL }
3260 {&hf_sccp_xudt_msg_fragment,
3261 {"Message fragment", "sccp.msg.fragment",
3262 FT_FRAMENUM, BASE_NONE, NULL, 0x00, NULL, HFILL }
3264 {&hf_sccp_xudt_msg_fragment_overlap,
3265 {"Message fragment overlap", "sccp.msg.fragment.overlap",
3266 FT_BOOLEAN, BASE_NONE, NULL, 0x0, NULL, HFILL }
3268 {&hf_sccp_xudt_msg_fragment_overlap_conflicts,
3269 {"Message fragment overlapping with conflicting data", "sccp.msg.fragment.overlap.conflicts",
3270 FT_BOOLEAN, BASE_NONE, NULL, 0x0, NULL, HFILL }
3272 {&hf_sccp_xudt_msg_fragment_multiple_tails,
3273 {"Message has multiple tail fragments", "sccp.msg.fragment.multiple_tails",
3274 FT_BOOLEAN, BASE_NONE, NULL, 0x0, NULL, HFILL }
3276 {&hf_sccp_xudt_msg_fragment_too_long_fragment,
3277 {"Message fragment too long", "sccp.msg.fragment.too_long_fragment",
3278 FT_BOOLEAN, BASE_NONE, NULL, 0x0, NULL, HFILL }
3280 {&hf_sccp_xudt_msg_fragment_error,
3281 {"Message defragmentation error", "sccp.msg.fragment.error",
3282 FT_FRAMENUM, BASE_NONE, NULL, 0x00, NULL, HFILL }
3284 {&hf_sccp_xudt_msg_reassembled_in,
3285 {"Reassembled in", "sccp.msg.reassembled.in",
3286 FT_FRAMENUM, BASE_NONE, NULL, 0x00, NULL, HFILL }
3288 {&hf_sccp_xudt_msg_reassembled_length,
3289 {"Reassembled SCCP length", "sccp.msg.reassembled.length",
3290 FT_UINT32, BASE_DEC, NULL, 0x00, NULL, HFILL }
3292 { &hf_sccp_assoc_id,
3293 { "Association ID", "sccp.assoc.id",
3294 FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL}},
3295 {&hf_sccp_assoc_msg,
3296 {"Message in frame", "sccp.assoc.msg",
3297 FT_FRAMENUM, BASE_NONE, NULL, 0x00, NULL, HFILL }
3302 /* Setup protocol subtree array */
3303 static gint *ett[] = {
3306 &ett_sccp_called_ai,
3307 &ett_sccp_called_pc,
3308 &ett_sccp_called_gt,
3310 &ett_sccp_calling_ai,
3311 &ett_sccp_calling_pc,
3312 &ett_sccp_calling_gt,
3313 &ett_sccp_sequencing_segmenting,
3314 &ett_sccp_segmentation,
3315 &ett_sccp_ansi_isni_routing_control,
3316 &ett_sccp_xudt_msg_fragment,
3317 &ett_sccp_xudt_msg_fragments,
3323 static uat_field_t users_flds[] = {
3324 UAT_FLD_DEC(sccp_users,ni,"Network Indicator","Network Indicator"),
3325 UAT_FLD_RANGE(sccp_users,called_pc,"Called DPCs",65535,"DPCs for which this protocol is to be used"),
3326 UAT_FLD_RANGE(sccp_users,called_ssn,"Called SSNs",65535,"Called SSNs for which this protocol is to be used"),
3327 UAT_FLD_VS(sccp_users,user,"User protocol",sccp_users_vals,"The User Protocol"),
3332 uat_t* users_uat = uat_new("SCCP Users Table",
3333 sizeof(sccp_user_t),
3336 (void*) &sccp_users,
3341 sccp_users_update_cb,
3346 /* Register the protocol name and description */
3347 proto_sccp = proto_register_protocol("Signalling Connection Control Part",
3350 register_dissector("sccp", dissect_sccp, proto_sccp);
3352 /* Required function calls to register the header fields and subtrees used */
3353 proto_register_field_array(proto_sccp, hf, array_length(hf));
3354 proto_register_subtree_array(ett, array_length(ett));
3357 sccp_ssn_dissector_table = register_dissector_table("sccp.ssn", "SCCP SSN", FT_UINT8, BASE_DEC);
3359 register_heur_dissector_list("sccp", &heur_subdissector_list);
3361 sccp_module = prefs_register_protocol(proto_sccp, NULL);
3363 prefs_register_uint_preference(sccp_module, "source_pc",
3364 "Source PC (in hex)",
3365 "The source point code (usually MSC) (to determine whether message is uplink or downlink)",
3366 16, &sccp_source_pc_global);
3368 prefs_register_bool_preference(sccp_module, "show_length", "Show length",
3369 "Show parameter length in the protocol tree",
3372 prefs_register_bool_preference(sccp_module, "defragment_xudt",
3373 "Reassemble XUDT messages",
3374 "Whether XUDT messages should be reassembled",
3375 &sccp_xudt_desegment);
3377 prefs_register_bool_preference(sccp_module, "trace_sccp",
3378 "Trace Associations",
3379 "Whether to keep information about messages and their associations",
3383 prefs_register_bool_preference(sccp_module, "show_more_info",
3384 "Show key parameters in Info Column",
3385 "Show SLR, DLR, and CAUSE Parameters in the Information Column of the Summary",
3389 prefs_register_uat_preference(sccp_module, "users_table", "Users Table",
3390 "A table that enumerates user protocols to be used against specific PCs and SSNs",
3393 register_init_routine(&init_sccp);
3395 assocs = se_tree_create(EMEM_TREE_TYPE_RED_BLACK, "sccp_associations");
3397 sccp_tap = register_tap("sccp");
3402 proto_reg_handoff_sccp(void)
3404 dissector_handle_t sccp_handle;
3406 sccp_handle = find_dissector("sccp");
3408 dissector_add("wtap_encap", WTAP_ENCAP_SCCP, sccp_handle);
3409 dissector_add("mtp3.service_indicator", SCCP_SI, sccp_handle);
3410 dissector_add_string("tali.opcode", "sccp", sccp_handle);
3412 data_handle = find_dissector("data");
3413 tcap_handle = find_dissector("tcap");
3414 ranap_handle = find_dissector("ranap");
3415 bssap_handle = find_dissector("bssap");
3416 gsmmap_handle = find_dissector("gsm_map");
3417 camel_handle = find_dissector("camel");
3418 inap_handle = find_dissector("inap");