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 "packet-mtp3.h"
50 #include <epan/prefs.h>
51 #include <epan/emem.h>
52 #include <epan/reassemble.h>
53 #include <epan/asn1.h>
54 #include "packet-tcap.h"
55 #include "packet-sccp.h"
59 static Standard_Type decode_mtp3_standard;
62 #define SCCP_MSG_TYPE_OFFSET 0
63 #define SCCP_MSG_TYPE_LENGTH 1
64 #define POINTER_LENGTH 1
65 #define POINTER_LENGTH_LONG 2
68 /* Same as below but with names typed out */
69 static const value_string sccp_message_type_values[] = {
70 { SCCP_MSG_TYPE_CR, "Connection Request" },
71 { SCCP_MSG_TYPE_CC, "Connection Confirm" },
72 { SCCP_MSG_TYPE_CREF, "Connection Refused" },
73 { SCCP_MSG_TYPE_RLSD, "Released" },
74 { SCCP_MSG_TYPE_RLC, "Release Complete" },
75 { SCCP_MSG_TYPE_DT1, "Data Form 1" },
76 { SCCP_MSG_TYPE_DT2, "Data Form 2" },
77 { SCCP_MSG_TYPE_AK, "Data Acknowledgement" },
78 { SCCP_MSG_TYPE_UDT, "Unitdata" },
79 { SCCP_MSG_TYPE_UDTS, "Unitdata Service" },
80 { SCCP_MSG_TYPE_ED, "Expedited Data" },
81 { SCCP_MSG_TYPE_EA, "Expedited Data Acknowledgement" },
82 { SCCP_MSG_TYPE_RSR, "Reset Request" },
83 { SCCP_MSG_TYPE_RSC, "Reset Confirmation" },
84 { SCCP_MSG_TYPE_ERR, "Error" },
85 { SCCP_MSG_TYPE_IT, "Inactivity Timer" },
86 { SCCP_MSG_TYPE_XUDT, "Extended Unitdata" },
87 { SCCP_MSG_TYPE_XUDTS, "Extended Unitdata Service" },
88 { SCCP_MSG_TYPE_LUDT, "Long Unitdata (ITU)" },
89 { SCCP_MSG_TYPE_LUDTS, "Long Unitdata Service (ITU)" },
92 /* Same as above but in acronym form (for the Info column) */
93 const value_string sccp_message_type_acro_values[] = {
94 { SCCP_MSG_TYPE_CR, "CR" },
95 { SCCP_MSG_TYPE_CC, "CC" },
96 { SCCP_MSG_TYPE_CREF, "CREF" },
97 { SCCP_MSG_TYPE_RLSD, "RLSD" },
98 { SCCP_MSG_TYPE_RLC, "RLC" },
99 { SCCP_MSG_TYPE_DT1, "DT1" },
100 { SCCP_MSG_TYPE_DT2, "DT2" },
101 { SCCP_MSG_TYPE_AK, "AK" },
102 { SCCP_MSG_TYPE_UDT, "UDT" },
103 { SCCP_MSG_TYPE_UDTS, "UDTS" },
104 { SCCP_MSG_TYPE_ED, "ED" },
105 { SCCP_MSG_TYPE_EA, "EA" },
106 { SCCP_MSG_TYPE_RSR, "RSR" },
107 { SCCP_MSG_TYPE_RSC, "RSC" },
108 { SCCP_MSG_TYPE_ERR, "ERR" },
109 { SCCP_MSG_TYPE_IT, "IT" },
110 { SCCP_MSG_TYPE_XUDT, "XUDT" },
111 { SCCP_MSG_TYPE_XUDTS, "XUDTS" },
112 { SCCP_MSG_TYPE_LUDT, "LUDT" },
113 { SCCP_MSG_TYPE_LUDTS, "LUDTS" },
116 #define PARAMETER_LENGTH_LENGTH 1
117 #define PARAMETER_LONG_DATA_LENGTH_LENGTH 2
118 #define PARAMETER_TYPE_LENGTH 1
120 #define PARAMETER_END_OF_OPTIONAL_PARAMETERS 0x00
121 #define PARAMETER_DESTINATION_LOCAL_REFERENCE 0x01
122 #define PARAMETER_SOURCE_LOCAL_REFERENCE 0x02
123 #define PARAMETER_CALLED_PARTY_ADDRESS 0x03
124 #define PARAMETER_CALLING_PARTY_ADDRESS 0x04
125 #define PARAMETER_CLASS 0x05
126 #define PARAMETER_SEGMENTING_REASSEMBLING 0x06
127 #define PARAMETER_RECEIVE_SEQUENCE_NUMBER 0x07
128 #define PARAMETER_SEQUENCING_SEGMENTING 0x08
129 #define PARAMETER_CREDIT 0x09
130 #define PARAMETER_RELEASE_CAUSE 0x0a
131 #define PARAMETER_RETURN_CAUSE 0x0b
132 #define PARAMETER_RESET_CAUSE 0x0c
133 #define PARAMETER_ERROR_CAUSE 0x0d
134 #define PARAMETER_REFUSAL_CAUSE 0x0e
135 #define PARAMETER_DATA 0x0f
136 #define PARAMETER_SEGMENTATION 0x10
137 #define PARAMETER_HOP_COUNTER 0x11
138 /* The below 2 are ITU only */
139 #define PARAMETER_IMPORTANCE 0x12
140 #define PARAMETER_LONG_DATA 0x13
141 /* ISNI is ANSI only */
142 #define PARAMETER_ISNI 0xfa
144 static const value_string sccp_parameter_values[] = {
145 { PARAMETER_END_OF_OPTIONAL_PARAMETERS, "End of Optional Parameters" },
146 { PARAMETER_DESTINATION_LOCAL_REFERENCE, "Destination Local Reference" },
147 { PARAMETER_SOURCE_LOCAL_REFERENCE, "Source Local Reference" },
148 { PARAMETER_CALLED_PARTY_ADDRESS, "Called Party Address" },
149 { PARAMETER_CALLING_PARTY_ADDRESS, "Calling Party Address" },
150 { PARAMETER_CLASS, "Protocol Class" },
151 { PARAMETER_SEGMENTING_REASSEMBLING, "Segmenting/Reassembling" },
152 { PARAMETER_RECEIVE_SEQUENCE_NUMBER, "Receive Sequence Number" },
153 { PARAMETER_SEQUENCING_SEGMENTING, "Sequencing/Segmenting" },
154 { PARAMETER_CREDIT, "Credit" },
155 { PARAMETER_RELEASE_CAUSE, "Release Cause" },
156 { PARAMETER_RETURN_CAUSE, "Return Cause" },
157 { PARAMETER_RESET_CAUSE, "Reset Cause" },
158 { PARAMETER_ERROR_CAUSE, "Error Cause" },
159 { PARAMETER_REFUSAL_CAUSE, "Refusal Cause" },
160 { PARAMETER_DATA, "Data" },
161 { PARAMETER_SEGMENTATION, "Segmentation" },
162 { PARAMETER_HOP_COUNTER, "Hop Counter" },
163 { PARAMETER_IMPORTANCE, "Importance (ITU)" },
164 { PARAMETER_LONG_DATA, "Long Data (ITU)" },
165 { PARAMETER_ISNI, "Intermediate Signaling Network Identification (ANSI)" },
169 #define END_OF_OPTIONAL_PARAMETERS_LENGTH 1
170 #define DESTINATION_LOCAL_REFERENCE_LENGTH 3
171 #define SOURCE_LOCAL_REFERENCE_LENGTH 3
172 #define PROTOCOL_CLASS_LENGTH 1
173 #define RECEIVE_SEQUENCE_NUMBER_LENGTH 1
174 #define CREDIT_LENGTH 1
175 #define RELEASE_CAUSE_LENGTH 1
176 #define RETURN_CAUSE_LENGTH 1
177 #define RESET_CAUSE_LENGTH 1
178 #define ERROR_CAUSE_LENGTH 1
179 #define REFUSAL_CAUSE_LENGTH 1
180 #define HOP_COUNTER_LENGTH 1
181 #define IMPORTANCE_LENGTH 1
184 /* Parts of the Called and Calling Address parameters */
185 /* Address Indicator */
186 #define ADDRESS_INDICATOR_LENGTH 1
187 #define ITU_RESERVED_MASK 0x80
188 #define ANSI_NATIONAL_MASK 0x80
189 #define ROUTING_INDICATOR_MASK 0x40
190 #define GTI_MASK 0x3C
192 #define ITU_SSN_INDICATOR_MASK 0x02
193 #define ITU_PC_INDICATOR_MASK 0x01
194 #define ANSI_PC_INDICATOR_MASK 0x02
195 #define ANSI_SSN_INDICATOR_MASK 0x01
197 static const value_string sccp_national_indicator_values[] = {
198 { 0x0, "Address coded to International standard" },
199 { 0x1, "Address coded to National standard" },
202 static const value_string sccp_routing_indicator_values[] = {
203 { 0x0, "Route on GT" },
204 { 0x1, "Route on SSN" },
207 #define AI_GTI_NO_GT 0x0
208 #define ITU_AI_GTI_NAI 0x1
209 #define AI_GTI_TT 0x2
210 #define ITU_AI_GTI_TT_NP_ES 0x3
211 #define ITU_AI_GTI_TT_NP_ES_NAI 0x4
212 static const value_string sccp_itu_global_title_indicator_values[] = {
213 { AI_GTI_NO_GT, "No Global Title" },
214 { ITU_AI_GTI_NAI, "Nature of Address Indicator only" },
215 { AI_GTI_TT, "Translation Type only" },
216 { ITU_AI_GTI_TT_NP_ES, "Translation Type, Numbering Plan, and Encoding Scheme included" },
217 { ITU_AI_GTI_TT_NP_ES_NAI, "Translation Type, Numbering Plan, Encoding Scheme, and Nature of Address Indicator included" },
220 /* #define AI_GTI_NO_GT 0x0 */
221 #define ANSI_AI_GTI_TT_NP_ES 0x1
222 /* #define AI_GTI_TT 0x2 */
223 static const value_string sccp_ansi_global_title_indicator_values[] = {
224 { AI_GTI_NO_GT, "No Global Title" },
225 { ANSI_AI_GTI_TT_NP_ES, "Translation Type, Numbering Plan, and Encoding Scheme included" },
226 { AI_GTI_TT, "Translation Type only" },
229 static const value_string sccp_ai_pci_values[] = {
230 { 0x1, "Point Code present" },
231 { 0x0, "Point Code not present" },
234 static const value_string sccp_ai_ssni_values[] = {
235 { 0x1, "SSN present" },
236 { 0x0, "SSN not present" },
239 #define ADDRESS_SSN_LENGTH 1
240 #define INVALID_SSN 0xff
241 /* Some values from 3GPP TS 23.003 */
242 /* Japan TTC and NTT define a lot of SSNs, some of which conflict with
243 * these. They are not added for now.
245 static const value_string sccp_ssn_values[] = {
246 { 0x00, "SSN not known/not used" },
247 { 0x01, "SCCP management" },
248 { 0x02, "Reserved for ITU-T allocation" },
249 { 0x03, "ISDN User Part" },
250 { 0x04, "OMAP (Operation, Maintenance, and Administration Part)" },
251 { 0x05, "MAP (Mobile Application Part)" },
252 { 0x06, "HLR (Home Location Register)" },
253 { 0x07, "VLR (Visitor Location Register)" },
254 { 0x08, "MSC (Mobile Switching Center)" },
255 { 0x09, "EIC/EIR (Equipment Identifier Center/Equipment Identification Register)" },
256 { 0x0a, "AUC/AC (Authentication Center)" },
257 { 0x0b, "ISDN supplementary services (ITU only)" },
258 { 0x0c, "Reserved for international use (ITU only)" },
259 { 0x0d, "Broadband ISDN edge-to-edge applications (ITU only)" },
260 { 0x0e, "TC test responder (ITU only)" },
261 /* The following national network subsystem numbers have been allocated for use within and
262 * between GSM/UMTS networks:
266 { 0x91, "GMLC(MAP)" },
268 { 0x93, "gsmSCF (MAP) or IM-SSF (MAP) or Presence Network Agent" },
269 { 0x94, "SIWF (MAP)" },
270 { 0x95, "SGSN (MAP)" },
271 { 0x96, "GGSN (MAP)" },
272 /* The following national network subsystem numbers have been allocated for use within GSM/UMTS networks:*/
274 { 0xfa, "BSC (BSSAP-LE)" },
275 { 0xfb, "MSC (BSSAP-LE)" },
276 { 0xfc, "IOS or SMLC (BSSAP-LE)" },
277 { 0xfd, "BSS O&M (A interface)" },
278 { 0xfe, "BSSAP/BSAP" },
282 /* * * * * * * * * * * * * * * * *
283 * Global Title: ITU GTI == 0001 *
284 * * * * * * * * * * * * * * * * */
285 #define GT_NAI_MASK 0x7F
286 #define GT_NAI_LENGTH 1
287 static const value_string sccp_nai_values[] = {
288 { 0x00, "NAI unknown" },
289 { 0x01, "Subscriber Number" },
290 { 0x02, "Reserved for national use" },
291 { 0x03, "National significant number" },
292 { 0x04, "International number" },
296 #define GT_OE_MASK 0x80
299 static const value_string sccp_oe_values[] = {
300 { GT_OE_EVEN, "Even number of address signals" },
301 { GT_OE_ODD, "Odd number of address signals" },
304 #define GT_SIGNAL_LENGTH 1
305 #define GT_ODD_SIGNAL_MASK 0x0f
306 #define GT_EVEN_SIGNAL_MASK 0xf0
307 #define GT_EVEN_SIGNAL_SHIFT 4
308 #define GT_MAX_SIGNALS (32*7) /* its a bit big, but it allows for adding a lot of "(spare)" and "Unknown" values (7 chars) if there are errors - e.g. ANSI vs ITU wrongly selected */
309 static const value_string sccp_address_signal_values[] = {
329 /* * * * * * * * * * * * * * * * * * * * *
330 * Global Title: ITU and ANSI GTI == 0010 *
331 * * * * * * * * * * * * * * * * * * * * */
332 #define GT_TT_LENGTH 1
335 /* * * * * * * * * * * * * * * * * * * * * * * * * *
336 * Global Title: ITU GTI == 0011, ANSI GTI == 0001 *
337 * * * * * * * * * * * * * * * * * * * * * * * * * */
338 #define GT_NP_MASK 0xf0
339 #define GT_NP_ES_LENGTH 1
340 static const value_string sccp_np_values[] = {
342 { 0x1, "ISDN/telephony" },
343 { 0x2, "Generic (ITU)/Reserved (ANSI)" },
346 { 0x5, "Maritime mobile" },
347 { 0x6, "Land mobile" },
348 { 0x7, "ISDN/mobile" },
349 { 0xe, "Private network or network-specific" },
353 #define GT_ES_MASK 0x0f
354 #define GT_ES_UNKNOWN 0x0
355 #define GT_ES_BCD_ODD 0x1
356 #define GT_ES_BCD_EVEN 0x2
357 #define GT_ES_NATIONAL 0x3
358 #define GT_ES_RESERVED 0xf
359 static const value_string sccp_es_values[] = {
360 { GT_ES_UNKNOWN, "Unknown" },
361 { GT_ES_BCD_ODD, "BCD, odd number of digits" },
362 { GT_ES_BCD_EVEN, "BCD, even number of digits" },
363 { GT_ES_NATIONAL, "National specific" },
364 { GT_ES_RESERVED, "Reserved (ITU)/Spare (ANSI)" },
367 /* Address signals above */
370 /* * * * * * * * * * * * * * * * *
371 * Global Title: ITU GTI == 0100 *
372 * * * * * * * * * * * * * * * * */
376 /* Address signals above */
379 #define CLASS_CLASS_MASK 0xf
380 #define CLASS_SPARE_HANDLING_MASK 0xf0
381 static const value_string sccp_class_handling_values [] = {
382 { 0x0, "No special options" },
383 { 0x8, "Return message on error" },
387 #define SEGMENTING_REASSEMBLING_LENGTH 1
388 #define SEGMENTING_REASSEMBLING_MASK 0x01
389 #define NO_MORE_DATA 0
391 /* This is also used by sequencing-segmenting parameter */
392 static const value_string sccp_segmenting_reassembling_values [] = {
393 { NO_MORE_DATA, "No more data" },
394 { MORE_DATA, "More data" },
398 #define RECEIVE_SEQUENCE_NUMBER_LENGTH 1
399 #define RSN_MASK 0xfe
401 #define SEQUENCING_SEGMENTING_LENGTH 2
402 #define SEQUENCING_SEGMENTING_SSN_LENGTH 1
403 #define SEQUENCING_SEGMENTING_RSN_LENGTH 1
404 #define SEND_SEQUENCE_NUMBER_MASK 0xfe
405 #define RECEIVE_SEQUENCE_NUMBER_MASK 0xfe
406 #define SEQUENCING_SEGMENTING_MORE_MASK 0x01
409 #define CREDIT_LENGTH 1
411 #define RELEASE_CAUSE_LENGTH 1
412 static const value_string sccp_release_cause_values [] = {
413 { 0x00, "End user originated" },
414 { 0x01, "End user congestion" },
415 { 0x02, "End user failure" },
416 { 0x03, "SCCP user originated" },
417 { 0x04, "Remote procedure error" },
418 { 0x05, "Inconsistent connection data" },
419 { 0x06, "Access failure" },
420 { 0x07, "Access congestion" },
421 { 0x08, "Subsystem failure" },
422 { 0x09, "Subsystem congestion" },
423 { 0x0a, "MTP failure" },
424 { 0x0b, "Netowrk congestion" },
425 { 0x0c, "Expiration of reset timer" },
426 { 0x0d, "Expiration of receive inactivity timer" },
427 { 0x0e, "Reserved" },
428 { 0x0f, "Unqualified" },
429 { 0x10, "SCCP failure (ITU only)" },
433 #define RETURN_CAUSE_LENGTH 1
434 static const value_string sccp_return_cause_values [] = {
435 { 0x00, "No translation for an address of such nature" },
436 { 0x01, "No translation for this specific address" },
437 { 0x02, "Subsystem congestion" },
438 { 0x03, "Subsystem failure" },
439 { 0x04, "Unequipped failure" },
440 { 0x05, "MTP failure" },
441 { 0x06, "Network congestion" },
442 { 0x07, "Unqualified" },
443 { 0x08, "Error in message transport" },
444 { 0x09, "Error in local processing" },
445 { 0x0a, "Destination cannot perform reassembly" },
446 { 0x0b, "SCCP failure" },
447 { 0x0c, "Hop counter violation" },
448 { 0x0d, "Segmentation not supported (ITU only)" },
449 { 0x0e, "Segmentation failure (ITU only)" },
450 { 0xf9, "Invalid ISNI routing request (ANSI only)"},
451 { 0xfa, "Unauthorized message (ANSI only)" },
452 { 0xfb, "Message incompatibility (ANSI only)" },
453 { 0xfc, "Cannot perform ISNI constrained routing (ANSI only)" },
454 { 0xfd, "Unable to perform ISNI identification (ANSI only)" },
458 #define RESET_CAUSE_LENGTH 1
459 static const value_string sccp_reset_cause_values [] = {
460 { 0x00, "End user originated" },
461 { 0x01, "SCCP user originated" },
462 { 0x02, "Message out of order - incorrect send sequence number" },
463 { 0x03, "Message out of order - incorrect receive sequence number" },
464 { 0x04, "Remote procedure error - message out of window" },
465 { 0x05, "Remote procedure error - incorrect send sequence number after (re)initialization" },
466 { 0x06, "Remote procedure error - general" },
467 { 0x07, "Remote end user operational" },
468 { 0x08, "Network operational" },
469 { 0x09, "Access operational" },
470 { 0x0a, "Network congestion" },
471 { 0x0b, "Reserved (ITU)/Not obtainable (ANSI)" },
472 { 0x0c, "Unqualified" },
476 #define ERROR_CAUSE_LENGTH 1
477 static const value_string sccp_error_cause_values [] = {
478 { 0x00, "Local Reference Number (LRN) mismatch - unassigned destination LRN" },
479 { 0x01, "Local Reference Number (LRN) mismatch - inconsistent source LRN" },
480 { 0x02, "Point code mismatch" },
481 { 0x03, "Service class mismatch" },
482 { 0x04, "Unqualified" },
486 #define REFUSAL_CAUSE_LENGTH 1
487 static const value_string sccp_refusal_cause_values [] = {
488 { 0x00, "End user originated" },
489 { 0x01, "End user congestion" },
490 { 0x02, "End user failure" },
491 { 0x03, "SCCP user originated" },
492 { 0x04, "Destination address unknown" },
493 { 0x05, "Destination inaccessible" },
494 { 0x06, "Network resource - QOS not available/non-transient" },
495 { 0x07, "Network resource - QOS not available/transient" },
496 { 0x08, "Access failure" },
497 { 0x09, "Access congestion" },
498 { 0x0a, "Subsystem failure" },
499 { 0x0b, "Subsystem congestion" },
500 { 0x0c, "Expiration of connection establishment timer" },
501 { 0x0d, "Incompatible user data" },
502 { 0x0e, "Reserved" },
503 { 0x0f, "Unqualified" },
504 { 0x10, "Hop counter violation" },
505 { 0x11, "SCCP failure (ITU only)" },
506 { 0x12, "No translation for an address of such nature" },
507 { 0x13, "Unequipped user" },
511 #define SEGMENTATION_LENGTH 4
512 #define SEGMENTATION_FIRST_SEGMENT_MASK 0x80
513 #define SEGMENTATION_CLASS_MASK 0x40
514 #define SEGMENTATION_SPARE_MASK 0x30
515 #define SEGMENTATION_REMAINING_MASK 0x0f
516 static const value_string sccp_segmentation_first_segment_values [] = {
517 { 1, "First segment" },
518 { 0, "Not first segment" },
520 static const value_string sccp_segmentation_class_values [] = {
521 { 0, "Class 0 selected" },
522 { 1, "Class 1 selected" },
526 #define HOP_COUNTER_LENGTH 1
528 #define IMPORTANCE_LENGTH 1
529 #define IMPORTANCE_IMPORTANCE_MASK 0x7
532 #define ANSI_ISNI_ROUTING_CONTROL_LENGTH 1
533 #define ANSI_ISNI_MI_MASK 0x01
534 #define ANSI_ISNI_IRI_MASK 0x06
535 #define ANSI_ISNI_RES_MASK 0x08
536 #define ANSI_ISNI_TI_MASK 0x10
537 #define ANSI_ISNI_TI_SHIFT 4
538 #define ANSI_ISNI_COUNTER_MASK 0xe0
539 #define ANSI_ISNI_NETSPEC_MASK 0x03
541 static const value_string sccp_isni_mark_for_id_values [] = {
542 { 0x0, "Do not identify networks" },
543 { 0x1, "Identify networks" },
546 static const value_string sccp_isni_iri_values [] = {
547 { 0x0, "Neither constrained nor suggested ISNI routing" },
548 { 0x1, "Constrained ISNI routing" },
549 { 0x2, "Reserved for suggested ISNI routing" },
553 #define ANSI_ISNI_TYPE_0 0x0
554 #define ANSI_ISNI_TYPE_1 0x1
555 static const value_string sccp_isni_ti_values [] = {
556 { ANSI_ISNI_TYPE_0, "Type zero ISNI parameter format" },
557 { ANSI_ISNI_TYPE_1, "Type one ISNI parameter format" },
561 /* Initialize the protocol and registered fields */
562 static int proto_sccp = -1;
563 static int hf_sccp_message_type = -1;
564 static int hf_sccp_variable_pointer1 = -1;
565 static int hf_sccp_variable_pointer2 = -1;
566 static int hf_sccp_variable_pointer3 = -1;
567 static int hf_sccp_optional_pointer = -1;
568 static int hf_sccp_ssn = -1;
569 static int hf_sccp_gt_digits = -1;
571 /* Called Party address */
572 static int hf_sccp_called_national_indicator = -1;
573 static int hf_sccp_called_routing_indicator = -1;
574 static int hf_sccp_called_itu_global_title_indicator = -1;
575 static int hf_sccp_called_ansi_global_title_indicator = -1;
576 static int hf_sccp_called_itu_ssn_indicator = -1;
577 static int hf_sccp_called_itu_point_code_indicator = -1;
578 static int hf_sccp_called_ansi_ssn_indicator = -1;
579 static int hf_sccp_called_ansi_point_code_indicator = -1;
580 static int hf_sccp_called_ssn = -1;
581 static int hf_sccp_called_pc_member = -1;
582 static int hf_sccp_called_pc_cluster = -1;
583 static int hf_sccp_called_pc_network = -1;
584 static int hf_sccp_called_ansi_pc = -1;
585 static int hf_sccp_called_chinese_pc = -1;
586 static int hf_sccp_called_itu_pc = -1;
587 static int hf_sccp_called_japan_pc = -1;
588 static int hf_sccp_called_gt_nai = -1;
589 static int hf_sccp_called_gt_oe = -1;
590 static int hf_sccp_called_gt_tt = -1;
591 static int hf_sccp_called_gt_np = -1;
592 static int hf_sccp_called_gt_es = -1;
593 static int hf_sccp_called_gt_digits = -1;
595 /* Calling party address */
596 static int hf_sccp_calling_national_indicator = -1;
597 static int hf_sccp_calling_routing_indicator = -1;
598 static int hf_sccp_calling_itu_global_title_indicator = -1;
599 static int hf_sccp_calling_ansi_global_title_indicator = -1;
600 static int hf_sccp_calling_itu_ssn_indicator = -1;
601 static int hf_sccp_calling_itu_point_code_indicator = -1;
602 static int hf_sccp_calling_ansi_ssn_indicator = -1;
603 static int hf_sccp_calling_ansi_point_code_indicator = -1;
604 static int hf_sccp_calling_ssn = -1;
605 static int hf_sccp_calling_pc_member = -1;
606 static int hf_sccp_calling_pc_cluster = -1;
607 static int hf_sccp_calling_pc_network = -1;
608 static int hf_sccp_calling_ansi_pc = -1;
609 static int hf_sccp_calling_chinese_pc = -1;
610 static int hf_sccp_calling_itu_pc = -1;
611 static int hf_sccp_calling_japan_pc = -1;
612 static int hf_sccp_calling_gt_nai = -1;
613 static int hf_sccp_calling_gt_oe = -1;
614 static int hf_sccp_calling_gt_tt = -1;
615 static int hf_sccp_calling_gt_np = -1;
616 static int hf_sccp_calling_gt_es = -1;
617 static int hf_sccp_calling_gt_digits = -1;
619 /* Other parameter values */
620 static int hf_sccp_dlr = -1;
621 static int hf_sccp_slr = -1;
622 static int hf_sccp_lr = -1;
623 static int hf_sccp_class = -1;
624 static int hf_sccp_handling = -1;
625 static int hf_sccp_more = -1;
626 static int hf_sccp_rsn = -1;
627 static int hf_sccp_sequencing_segmenting_ssn = -1;
628 static int hf_sccp_sequencing_segmenting_rsn = -1;
629 static int hf_sccp_sequencing_segmenting_more = -1;
630 static int hf_sccp_credit = -1;
631 static int hf_sccp_release_cause = -1;
632 static int hf_sccp_return_cause = -1;
633 static int hf_sccp_reset_cause = -1;
634 static int hf_sccp_error_cause = -1;
635 static int hf_sccp_refusal_cause = -1;
636 static int hf_sccp_segmentation_first = -1;
637 static int hf_sccp_segmentation_class = -1;
638 static int hf_sccp_segmentation_remaining = -1;
639 static int hf_sccp_segmentation_slr = -1;
640 static int hf_sccp_hop_counter = -1;
641 static int hf_sccp_importance = -1;
642 static int hf_sccp_ansi_isni_mi = -1;
643 static int hf_sccp_ansi_isni_iri = -1;
644 static int hf_sccp_ansi_isni_ti = -1;
645 static int hf_sccp_ansi_isni_netspec = -1;
646 static int hf_sccp_ansi_isni_counter = -1;
647 static int hf_sccp_xudt_msg_fragments = -1;
648 static int hf_sccp_xudt_msg_fragment = -1;
649 static int hf_sccp_xudt_msg_fragment_overlap = -1;
650 static int hf_sccp_xudt_msg_fragment_overlap_conflicts = -1;
651 static int hf_sccp_xudt_msg_fragment_multiple_tails = -1;
652 static int hf_sccp_xudt_msg_fragment_too_long_fragment = -1;
653 static int hf_sccp_xudt_msg_fragment_error = -1;
654 static int hf_sccp_xudt_msg_reassembled_in = -1;
655 static int hf_sccp_assoc_msg = -1;
656 static int hf_sccp_assoc_id = -1;
658 /* Initialize the subtree pointers */
659 static gint ett_sccp = -1;
660 static gint ett_sccp_called = -1;
661 static gint ett_sccp_called_ai = -1;
662 static gint ett_sccp_called_pc = -1;
663 static gint ett_sccp_called_gt = -1;
664 static gint ett_sccp_calling = -1;
665 static gint ett_sccp_calling_ai = -1;
666 static gint ett_sccp_calling_pc = -1;
667 static gint ett_sccp_calling_gt = -1;
668 static gint ett_sccp_sequencing_segmenting = -1;
669 static gint ett_sccp_segmentation = -1;
670 static gint ett_sccp_ansi_isni_routing_control = -1;
671 static gint ett_sccp_xudt_msg_fragment = -1;
672 static gint ett_sccp_xudt_msg_fragments = -1;
673 static gint ett_sccp_assoc = -1;
675 /* Declarations to desegment XUDT Messages */
676 static gboolean sccp_xudt_desegment = TRUE;
678 static gboolean show_key_params = FALSE;
680 static int sccp_tap = -1;
683 static const fragment_items sccp_xudt_msg_frag_items = {
684 /* Fragment subtrees */
685 &ett_sccp_xudt_msg_fragment,
686 &ett_sccp_xudt_msg_fragments,
687 /* Fragment fields */
688 &hf_sccp_xudt_msg_fragments,
689 &hf_sccp_xudt_msg_fragment,
690 &hf_sccp_xudt_msg_fragment_overlap,
691 &hf_sccp_xudt_msg_fragment_overlap_conflicts,
692 &hf_sccp_xudt_msg_fragment_multiple_tails,
693 &hf_sccp_xudt_msg_fragment_too_long_fragment,
694 &hf_sccp_xudt_msg_fragment_error,
695 /* Reassembled in field */
696 &hf_sccp_xudt_msg_reassembled_in,
698 "SCCP XUDT Message fragments"
701 static GHashTable *sccp_xudt_msg_fragment_table = NULL;
702 static GHashTable *sccp_xudt_msg_reassembled_table = NULL;
705 #define SCCP_USER_DATA 0
706 #define SCCP_USER_TCAP 1
707 #define SCCP_USER_RANAP 2
708 #define SCCP_USER_BSSAP 3
709 #define SCCP_USER_GSMMAP 4
710 #define SCCP_USER_CAMEL 5
711 #define SCCP_USER_INAP 6
713 typedef struct _sccp_user_t {
719 dissector_handle_t* handlep;
722 static sccp_user_t* sccp_users;
723 static guint num_sccp_users;
725 static dissector_handle_t data_handle;
726 static dissector_handle_t tcap_handle;
727 static dissector_handle_t ranap_handle;
728 static dissector_handle_t bssap_handle;
729 static dissector_handle_t gsmmap_handle;
730 static dissector_handle_t camel_handle;
731 static dissector_handle_t inap_handle;
733 static value_string sccp_users_vals[] = {
734 { SCCP_USER_DATA, "Data"},
735 { SCCP_USER_TCAP, "TCAP"},
736 { SCCP_USER_RANAP, "RANAP"},
737 { SCCP_USER_BSSAP, "BSSAP"},
738 { SCCP_USER_GSMMAP, "GSM MAP"},
739 { SCCP_USER_CAMEL, "CAMEL"},
740 { SCCP_USER_INAP, "INAP"},
745 * Here are the global variables associated with
746 * the various user definable characteristics of the dissection
748 static guint32 sccp_source_pc_global = 0;
749 static gboolean sccp_show_length = FALSE;
751 static module_t *sccp_module;
752 static heur_dissector_list_t heur_subdissector_list;
754 /* Keep track of SSN value of current message so if/when we get to the data
755 * parameter, we can call appropriate sub-dissector. TODO: can this info
756 * be stored elsewhere?
759 static guint8 message_type = 0;
760 static guint dlr = 0;
761 static guint slr = 0;
763 static dissector_table_t sccp_ssn_dissector_table;
765 static emem_tree_t* assocs = NULL;
766 static sccp_assoc_info_t* assoc;
767 static sccp_msg_info_t* sccp_msg;
768 static sccp_assoc_info_t no_assoc = {0,0,0,0,0,FALSE,FALSE,NULL,NULL,SCCP_PLOAD_NONE,NULL,NULL,NULL};
769 static gboolean trace_sccp = FALSE;
770 static guint32 next_assoc_id = 0;
772 static const value_string assoc_protos[] = {
773 { SCCP_PLOAD_BSSAP, "BSSAP" },
774 { SCCP_PLOAD_RANAP, "RANAP" },
778 static sccp_assoc_info_t* new_assoc(guint32 calling, guint32 called){
779 sccp_assoc_info_t* a = se_alloc(sizeof(sccp_assoc_info_t));
781 a->id = next_assoc_id++;
782 a->calling_dpc = calling;
783 a->called_dpc = called;
784 a->calling_ssn = INVALID_SSN;
785 a->called_ssn = INVALID_SSN;
786 a->has_fw_key = FALSE;
787 a->has_bw_key = FALSE;
788 a->payload = SCCP_PLOAD_NONE;
789 a->calling_party = NULL;
790 a->called_party = NULL;
791 a->extra_info = NULL;
797 void reset_sccp_assoc(void) {
801 sccp_assoc_info_t* get_sccp_assoc(packet_info* pinfo, guint offset, guint32 src_lr, guint32 dst_lr, guint msg_type) {
803 address* opc = &(pinfo->src);
804 address* dpc = &(pinfo->dst);
805 guint framenum = pinfo->fd->num;
810 opck = opc->type == AT_SS7PC ? mtp3_pc_hash((const mtp3_addr_pc_t *)opc->data) : g_str_hash(address_to_str(opc));
811 dpck = dpc->type == AT_SS7PC ? mtp3_pc_hash((const mtp3_addr_pc_t *)dpc->data) : g_str_hash(address_to_str(dpc));
815 case SCCP_MSG_TYPE_CR:
817 /* CR contains the opc,dpc,dlr key of backward messages swapped as dpc,opc,slr */
818 emem_tree_key_t bw_key[] = {
819 {1, &dpck}, {1, &opck}, {1, &src_lr}, {0, NULL}
822 if (! ( assoc = se_tree_lookup32_array(assocs,bw_key) ) && ! pinfo->fd->flags.visited ) {
823 assoc = new_assoc(opck,dpck);
824 se_tree_insert32_array(assocs,bw_key,assoc);
825 assoc->has_bw_key = TRUE;
828 pinfo->p2p_dir = P2P_DIR_SENT;
832 case SCCP_MSG_TYPE_CC:
834 emem_tree_key_t fw_key[] = {
835 {1, &dpck}, {1, &opck}, {1, &src_lr}, {0, NULL}
837 emem_tree_key_t bw_key[] = {
838 {1, &opck}, {1, &dpck}, {1, &dst_lr}, {0, NULL}
841 if ( ( assoc = se_tree_lookup32_array(assocs,bw_key) ) ) {
845 if ( (assoc = se_tree_lookup32_array(assocs,fw_key) ) ) {
849 assoc = new_assoc(dpck,opck);
853 pinfo->p2p_dir = P2P_DIR_RECV;
855 if ( ! pinfo->fd->flags.visited && ! assoc->has_bw_key ) {
856 se_tree_insert32_array(assocs,bw_key,assoc);
857 assoc->has_bw_key = TRUE;
860 if ( ! pinfo->fd->flags.visited && ! assoc->has_fw_key ) {
861 se_tree_insert32_array(assocs,fw_key,assoc);
862 assoc->has_fw_key = TRUE;
869 emem_tree_key_t key[] = {
870 {1, &opck}, {1, &dpck}, {1, &dst_lr}, {0, NULL}
873 assoc = se_tree_lookup32_array(assocs,key);
876 if (assoc->calling_dpc == dpck) {
877 pinfo->p2p_dir = P2P_DIR_RECV;
879 pinfo->p2p_dir = P2P_DIR_SENT;
887 if (assoc && trace_sccp) {
888 if ( ! pinfo->fd->flags.visited) {
889 sccp_msg_info_t* msg = se_alloc(sizeof(sccp_msg_info_t));
890 msg->framenum = framenum;
891 msg->offset = offset;
892 msg->data.co.next = NULL;
893 msg->data.co.assoc = assoc;
894 msg->data.co.label = NULL;
895 msg->data.co.comment = NULL;
896 msg->type = msg_type;
900 for (m = assoc->msgs; m->data.co.next; m = m->data.co.next) ;
901 m->data.co.next = msg;
906 assoc->curr_msg = msg;
912 for (m = assoc->msgs; m; m = m->data.co.next) {
913 if (m->framenum == framenum && m->offset == offset) {
921 return assoc ? assoc : &no_assoc;
926 dissect_sccp_unknown_message(tvbuff_t *message_tvb, proto_tree *sccp_tree)
928 guint32 message_length;
930 message_length = tvb_length(message_tvb);
932 proto_tree_add_text(sccp_tree, message_tvb, 0, message_length,
933 "Unknown message (%u byte%s)",
934 message_length, plurality(message_length, "", "s"));
938 dissect_sccp_unknown_param(tvbuff_t *tvb, proto_tree *tree, guint8 type, guint length)
940 proto_tree_add_text(tree, tvb, 0, length, "Unknown parameter 0x%x (%u byte%s)",
941 type, length, plurality(length, "", "s"));
945 dissect_sccp_dlr_param(tvbuff_t *tvb, proto_tree *tree, guint length, packet_info *pinfo)
949 dlr = tvb_get_letoh24(tvb, 0);
950 proto_tree_add_uint(tree, hf_sccp_dlr, tvb, 0, length, dlr);
951 lr_item = proto_tree_add_uint(tree, hf_sccp_lr, tvb, 0, length, dlr);
952 PROTO_ITEM_SET_HIDDEN(lr_item);
954 if (show_key_params && check_col(pinfo->cinfo, COL_INFO))
955 col_append_fstr(pinfo->cinfo, COL_INFO, "DLR=%d ", dlr);
959 dissect_sccp_slr_param(tvbuff_t *tvb, proto_tree *tree, guint length, packet_info *pinfo)
963 slr = tvb_get_letoh24(tvb, 0);
964 proto_tree_add_uint(tree, hf_sccp_slr, tvb, 0, length, slr);
965 lr_item = proto_tree_add_uint(tree, hf_sccp_lr, tvb, 0, length, slr);
966 PROTO_ITEM_SET_HIDDEN(lr_item);
968 if (show_key_params && check_col(pinfo->cinfo, COL_INFO))
969 col_append_fstr(pinfo->cinfo, COL_INFO, "SLR=%d ", slr);
973 #define is_connectionless(m) \
974 ( m == SCCP_MSG_TYPE_UDT || m == SCCP_MSG_TYPE_UDTS \
975 || m == SCCP_MSG_TYPE_XUDT|| m == SCCP_MSG_TYPE_XUDTS \
976 || m == SCCP_MSG_TYPE_LUDT|| m == SCCP_MSG_TYPE_LUDTS)
979 dissect_sccp_gt_address_information(tvbuff_t *tvb, proto_tree *tree,
980 guint length, gboolean even_length,
984 guint8 odd_signal, even_signal = 0x0f;
985 char gt_digits[GT_MAX_SIGNALS+1] = { 0 };
987 while(offset < length)
989 odd_signal = tvb_get_guint8(tvb, offset) & GT_ODD_SIGNAL_MASK;
990 even_signal = tvb_get_guint8(tvb, offset) & GT_EVEN_SIGNAL_MASK;
991 even_signal >>= GT_EVEN_SIGNAL_SHIFT;
993 strncat(gt_digits, val_to_str(odd_signal, sccp_address_signal_values,
994 "Unknown"), GT_MAX_SIGNALS - strlen(gt_digits));
996 /* If the last signal is NOT filler */
997 if (offset != (length - 1) || even_length == TRUE)
998 strncat(gt_digits, val_to_str(even_signal, sccp_address_signal_values,
999 "Unknown"), GT_MAX_SIGNALS - strlen(gt_digits));
1001 offset += GT_SIGNAL_LENGTH;
1004 if (is_connectionless(message_type) && sccp_msg) {
1005 guint8** gt_ptr = called ? &(sccp_msg->data.ud.called_gt) : &(sccp_msg->data.ud.calling_gt);
1007 *gt_ptr = ep_strdup(gt_digits);
1010 proto_tree_add_string_format(tree, called ? hf_sccp_called_gt_digits
1011 : hf_sccp_calling_gt_digits,
1012 tvb, 0, length, gt_digits,
1013 "Address information (digits): %s", gt_digits);
1014 proto_tree_add_string_hidden(tree, called ? hf_sccp_gt_digits
1015 : hf_sccp_gt_digits,
1016 tvb, 0, length, gt_digits);
1020 dissect_sccp_global_title(tvbuff_t *tvb, proto_tree *tree, guint length,
1021 guint8 gti, gboolean called)
1023 proto_item *gt_item = 0;
1024 proto_tree *gt_tree = 0;
1025 tvbuff_t *signals_tvb;
1027 guint8 odd_even, nai, tt, np, es;
1028 gboolean even = TRUE;
1030 /* Shift GTI to where we can work with it */
1033 gt_item = proto_tree_add_text(tree, tvb, offset, length,
1034 "Global Title 0x%x (%u byte%s)",
1035 gti, length, plurality(length,"", "s"));
1036 gt_tree = proto_item_add_subtree(gt_item, called ? ett_sccp_called_gt
1037 : ett_sccp_calling_gt);
1039 /* Decode Transation Type (if present) */
1043 /* Protocol doesn't tell us, so we ASSUME even... */
1046 case ITU_AI_GTI_TT_NP_ES:
1047 case ITU_AI_GTI_TT_NP_ES_NAI:
1048 case ANSI_AI_GTI_TT_NP_ES:
1050 tt = tvb_get_guint8(tvb, offset);
1051 proto_tree_add_uint(gt_tree, called ? hf_sccp_called_gt_tt
1052 : hf_sccp_calling_gt_tt,
1053 tvb, offset, GT_TT_LENGTH, tt);
1054 offset += GT_TT_LENGTH;
1057 /* Decode Numbering Plan and Encoding Scheme (if present) */
1059 case ITU_AI_GTI_TT_NP_ES:
1060 case ITU_AI_GTI_TT_NP_ES_NAI:
1061 case ANSI_AI_GTI_TT_NP_ES:
1063 np = tvb_get_guint8(tvb, offset) & GT_NP_MASK;
1064 proto_tree_add_uint(gt_tree, called ? hf_sccp_called_gt_np
1065 : hf_sccp_calling_gt_np,
1066 tvb, offset, GT_NP_ES_LENGTH, np);
1068 es = tvb_get_guint8(tvb, offset) & GT_ES_MASK;
1069 proto_tree_add_uint(gt_tree, called ? hf_sccp_called_gt_es
1070 : hf_sccp_calling_gt_es,
1071 tvb, offset, GT_NP_ES_LENGTH, es);
1073 even = (es == GT_ES_BCD_EVEN) ? TRUE : FALSE;
1075 offset += GT_NP_ES_LENGTH;
1078 /* Decode Odd/Even Indicator (if present) */
1079 if (gti == ITU_AI_GTI_NAI) {
1080 odd_even = tvb_get_guint8(tvb, offset) & GT_OE_MASK;
1081 proto_tree_add_uint(gt_tree, called ? hf_sccp_called_gt_oe
1082 : hf_sccp_calling_gt_oe,
1083 tvb, offset, GT_NAI_LENGTH, odd_even);
1084 even = (odd_even == GT_OE_EVEN) ? TRUE : FALSE;
1086 /* offset doesn't change */
1089 /* Decode Nature of Address Indicator (if present) */
1091 case ITU_AI_GTI_NAI:
1092 case ITU_AI_GTI_TT_NP_ES_NAI:
1093 nai = tvb_get_guint8(tvb, offset) & GT_NAI_MASK;
1094 proto_tree_add_uint(gt_tree, called ? hf_sccp_called_gt_nai
1095 : hf_sccp_calling_gt_nai,
1096 tvb, offset, GT_NAI_LENGTH, nai);
1098 offset += GT_NAI_LENGTH;
1101 /* Decode address signal(s) */
1102 if (length < offset)
1105 signals_tvb = tvb_new_subset(tvb, offset, (length - offset),
1107 dissect_sccp_gt_address_information(signals_tvb, gt_tree, (length - offset),
1112 dissect_sccp_3byte_pc(tvbuff_t *tvb, proto_tree *call_tree, guint offset,
1117 if (decode_mtp3_standard == ANSI_STANDARD)
1120 hf_pc = &hf_sccp_called_ansi_pc;
1122 hf_pc = &hf_sccp_calling_ansi_pc;
1123 } else /* CHINESE_ITU_STANDARD */ {
1125 hf_pc = &hf_sccp_called_chinese_pc;
1127 hf_pc = &hf_sccp_calling_chinese_pc;
1130 /* create and fill the PC tree */
1131 dissect_mtp3_3byte_pc(tvb, offset, call_tree,
1132 called ? ett_sccp_called_pc : ett_sccp_calling_pc,
1134 called ? hf_sccp_called_pc_network : hf_sccp_calling_pc_network,
1135 called ? hf_sccp_called_pc_cluster : hf_sccp_calling_pc_cluster,
1136 called ? hf_sccp_called_pc_member : hf_sccp_calling_pc_member,
1139 return(offset + ANSI_PC_LENGTH);
1142 /* FUNCTION dissect_sccp_called_calling_param():
1143 * Dissect the Calling or Called Party Address parameters.
1145 * The boolean 'called' describes whether this function is decoding a
1146 * called (TRUE) or calling (FALSE) party address. There is simply too
1147 * much code in this function to have 2 copies of it (one for called, one
1150 * NOTE: this function is called even when (!tree) so that we can get
1151 * the SSN and subsequently call subdissectors (if and when there's a data
1152 * parameter). Realistically we should put if (!tree)'s around a lot of the
1153 * code, but I think that would make it unreadable--and the expense of not
1154 * doing so does not appear to be very high.
1157 dissect_sccp_called_calling_param(tvbuff_t *tvb, proto_tree *tree,
1158 guint length, gboolean called)
1160 proto_item *call_item = 0, *call_ai_item = 0, *item;
1161 proto_tree *call_tree = 0, *call_ai_tree = 0;
1163 guint8 national = -1, routing_ind, gti, pci, ssni, ssn;
1165 dissector_handle_t ssn_dissector = NULL, tcap_ssn_dissector = NULL;
1166 const char *ssn_dissector_short_name = NULL;
1167 const char *tcap_ssn_dissector_short_name = NULL;
1169 call_item = proto_tree_add_text(tree, tvb, 0, length,
1170 "%s Party address (%u byte%s)",
1171 called ? "Called" : "Calling", length,
1172 plurality(length, "", "s"));
1173 call_tree = proto_item_add_subtree(call_item, called ? ett_sccp_called
1174 : ett_sccp_calling);
1176 call_ai_item = proto_tree_add_text(call_tree, tvb, 0,
1177 ADDRESS_INDICATOR_LENGTH,
1178 "Address Indicator");
1179 call_ai_tree = proto_item_add_subtree(call_ai_item, called ? ett_sccp_called_ai
1180 : ett_sccp_calling_ai);
1182 if (decode_mtp3_standard == ANSI_STANDARD)
1184 national = tvb_get_guint8(tvb, 0) & ANSI_NATIONAL_MASK;
1185 proto_tree_add_uint(call_ai_tree, called ? hf_sccp_called_national_indicator
1186 : hf_sccp_calling_national_indicator,
1187 tvb, 0, ADDRESS_INDICATOR_LENGTH, national);
1190 routing_ind = tvb_get_guint8(tvb, 0) & ROUTING_INDICATOR_MASK;
1191 proto_tree_add_uint(call_ai_tree, called ? hf_sccp_called_routing_indicator
1192 : hf_sccp_calling_routing_indicator,
1193 tvb, 0, ADDRESS_INDICATOR_LENGTH, routing_ind);
1195 gti = tvb_get_guint8(tvb, 0) & GTI_MASK;
1197 if (decode_mtp3_standard == ITU_STANDARD ||
1198 decode_mtp3_standard == CHINESE_ITU_STANDARD ||
1199 decode_mtp3_standard == JAPAN_STANDARD ||
1202 proto_tree_add_uint(call_ai_tree, called ? hf_sccp_called_itu_global_title_indicator
1203 : hf_sccp_called_itu_global_title_indicator,
1204 tvb, 0, ADDRESS_INDICATOR_LENGTH, gti);
1206 ssni = tvb_get_guint8(tvb, 0) & ITU_SSN_INDICATOR_MASK;
1207 proto_tree_add_uint(call_ai_tree, called ? hf_sccp_called_itu_ssn_indicator
1208 : hf_sccp_calling_itu_ssn_indicator,
1209 tvb, 0, ADDRESS_INDICATOR_LENGTH, ssni);
1211 pci = tvb_get_guint8(tvb, 0) & ITU_PC_INDICATOR_MASK;
1212 proto_tree_add_uint(call_ai_tree, called ? hf_sccp_called_itu_point_code_indicator
1213 : hf_sccp_calling_itu_point_code_indicator,
1214 tvb, 0, ADDRESS_INDICATOR_LENGTH, pci);
1216 offset = ADDRESS_INDICATOR_LENGTH;
1218 /* Dissect PC (if present) */
1220 if (decode_mtp3_standard == ITU_STANDARD) {
1222 proto_tree_add_item(call_tree, called ? hf_sccp_called_itu_pc
1223 : hf_sccp_calling_itu_pc,
1224 tvb, offset, ITU_PC_LENGTH, TRUE);
1226 offset += ITU_PC_LENGTH;
1228 } else if (decode_mtp3_standard == JAPAN_STANDARD) {
1230 proto_tree_add_item(call_tree, called ? hf_sccp_called_japan_pc
1231 : hf_sccp_calling_japan_pc,
1232 tvb, offset, JAPAN_PC_LENGTH, TRUE);
1234 offset += JAPAN_PC_LENGTH;
1236 } else /* CHINESE_ITU_STANDARD */ {
1238 offset = dissect_sccp_3byte_pc(tvb, call_tree, offset, called);
1243 /* Dissect SSN (if present) */
1245 ssn = tvb_get_guint8(tvb, offset);
1247 if (called && assoc)
1248 assoc->called_ssn = ssn;
1250 assoc->calling_ssn = ssn;
1252 if (is_connectionless(message_type) && sccp_msg) {
1253 guint* ssn_ptr = called ? &(sccp_msg->data.ud.called_ssn) : &(sccp_msg->data.ud.calling_ssn);
1258 proto_tree_add_uint(call_tree, called ? hf_sccp_called_ssn
1259 : hf_sccp_calling_ssn,
1260 tvb, offset, ADDRESS_SSN_LENGTH, ssn);
1261 proto_tree_add_uint_hidden(call_tree, hf_sccp_ssn, tvb, offset,
1262 ADDRESS_SSN_LENGTH, ssn);
1263 offset += ADDRESS_SSN_LENGTH;
1265 /* Get the dissector handle of the dissector registered for this ssn
1266 * And print it's name.
1268 ssn_dissector = dissector_get_port_handle(sccp_ssn_dissector_table, ssn);
1270 if (ssn_dissector) {
1271 ssn_dissector_short_name = dissector_handle_get_short_name(ssn_dissector);
1273 if(ssn_dissector_short_name) {
1274 item = proto_tree_add_text(call_tree, tvb, offset - 1, ADDRESS_SSN_LENGTH, "Linked to %s", ssn_dissector_short_name);
1275 PROTO_ITEM_SET_GENERATED(item);
1277 if (strncasecmp("TCAP", ssn_dissector_short_name, 4)== 0) {
1278 tcap_ssn_dissector = get_itu_tcap_subdissector(ssn);
1280 if(tcap_ssn_dissector){
1281 tcap_ssn_dissector_short_name = dissector_handle_get_short_name(tcap_ssn_dissector);
1282 proto_item_append_text(item,", TCAP SSN linked to %s", tcap_ssn_dissector_short_name);
1286 } /* ssn_dissector */
1290 return; /* got SSN, that's all we need here... */
1292 /* Dissect GT (if present) */
1293 if (gti != AI_GTI_NO_GT) {
1294 if (length < offset)
1297 gt_tvb = tvb_new_subset(tvb, offset, (length - offset),
1299 dissect_sccp_global_title(gt_tvb, call_tree, (length - offset), gti,
1303 } else if (decode_mtp3_standard == ANSI_STANDARD) {
1305 proto_tree_add_uint(call_ai_tree, called ? hf_sccp_called_ansi_global_title_indicator
1306 : hf_sccp_calling_ansi_global_title_indicator,
1307 tvb, 0, ADDRESS_INDICATOR_LENGTH, gti);
1309 pci = tvb_get_guint8(tvb, 0) & ANSI_PC_INDICATOR_MASK;
1310 proto_tree_add_uint(call_ai_tree, called ? hf_sccp_called_ansi_point_code_indicator
1311 : hf_sccp_calling_ansi_point_code_indicator,
1312 tvb, 0, ADDRESS_INDICATOR_LENGTH, pci);
1314 ssni = tvb_get_guint8(tvb, 0) & ANSI_SSN_INDICATOR_MASK;
1315 proto_tree_add_uint(call_ai_tree, called ? hf_sccp_called_ansi_ssn_indicator
1316 : hf_sccp_calling_ansi_ssn_indicator,
1317 tvb, 0, ADDRESS_INDICATOR_LENGTH, ssni);
1319 offset = ADDRESS_INDICATOR_LENGTH;
1321 /* Dissect SSN (if present) */
1323 ssn = tvb_get_guint8(tvb, offset);
1325 if (called && assoc)
1326 assoc->called_ssn = ssn;
1328 assoc->calling_ssn = ssn;
1330 if (is_connectionless(message_type) && sccp_msg) {
1331 guint* ssn_ptr = called ? &(sccp_msg->data.ud.called_ssn) : &(sccp_msg->data.ud.calling_ssn);
1336 proto_tree_add_uint(call_tree, called ? hf_sccp_called_ssn
1337 : hf_sccp_calling_ssn,
1338 tvb, offset, ADDRESS_SSN_LENGTH, ssn);
1339 proto_tree_add_uint_hidden(call_tree, hf_sccp_ssn, tvb, offset,
1340 ADDRESS_SSN_LENGTH, ssn);
1341 offset += ADDRESS_SSN_LENGTH;
1345 return; /* got SSN, that's all we need here... */
1347 /* Dissect PC (if present) */
1349 offset = dissect_sccp_3byte_pc(tvb, call_tree, offset, called);
1352 /* Dissect GT (if present) */
1353 if (gti != AI_GTI_NO_GT) {
1354 if (length < offset)
1356 gt_tvb = tvb_new_subset(tvb, offset, (length - offset),
1358 dissect_sccp_global_title(gt_tvb, call_tree, (length - offset), gti,
1367 dissect_sccp_called_param(tvbuff_t *tvb, proto_tree *tree, guint length)
1369 dissect_sccp_called_calling_param(tvb, tree, length, TRUE);
1373 dissect_sccp_calling_param(tvbuff_t *tvb, proto_tree *tree, guint length)
1375 dissect_sccp_called_calling_param(tvb, tree, length, FALSE);
1379 dissect_sccp_class_param(tvbuff_t *tvb, proto_tree *tree, guint length)
1381 guint8 class, handling;
1383 class = tvb_get_guint8(tvb, 0) & CLASS_CLASS_MASK;
1384 handling = tvb_get_guint8(tvb, 0) & CLASS_SPARE_HANDLING_MASK;
1386 proto_tree_add_uint(tree, hf_sccp_class, tvb, 0, length, class);
1388 if (class == 0 || class == 1)
1389 proto_tree_add_uint(tree, hf_sccp_handling, tvb, 0, length, handling);
1393 dissect_sccp_segmenting_reassembling_param(tvbuff_t *tvb, proto_tree *tree, guint length)
1395 proto_tree_add_item(tree, hf_sccp_more, tvb, 0, length, FALSE);
1399 dissect_sccp_receive_sequence_number_param(tvbuff_t *tvb, proto_tree *tree, guint length)
1403 rsn = tvb_get_guint8(tvb, 0) >> 1;
1404 proto_tree_add_uint(tree, hf_sccp_rsn, tvb, 0, length, rsn);
1408 dissect_sccp_sequencing_segmenting_param(tvbuff_t *tvb, proto_tree *tree, guint length)
1410 guint8 rsn, ssn, more;
1411 proto_item *param_item;
1412 proto_tree *param_tree;
1414 ssn = tvb_get_guint8(tvb, 0) >> 1;
1415 rsn = tvb_get_guint8(tvb, SEQUENCING_SEGMENTING_SSN_LENGTH) >> 1;
1416 more = tvb_get_guint8(tvb, SEQUENCING_SEGMENTING_SSN_LENGTH) & SEQUENCING_SEGMENTING_MORE_MASK;
1418 param_item = proto_tree_add_text(tree, tvb, 0, length,
1419 val_to_str(PARAMETER_SEQUENCING_SEGMENTING,
1420 sccp_parameter_values, "Unknown"));
1421 param_tree = proto_item_add_subtree(param_item,
1422 ett_sccp_sequencing_segmenting);
1424 proto_tree_add_uint(param_tree, hf_sccp_sequencing_segmenting_ssn, tvb, 0,
1425 SEQUENCING_SEGMENTING_SSN_LENGTH, ssn);
1426 proto_tree_add_uint(param_tree, hf_sccp_sequencing_segmenting_rsn, tvb,
1427 SEQUENCING_SEGMENTING_SSN_LENGTH,
1428 SEQUENCING_SEGMENTING_RSN_LENGTH, rsn);
1429 proto_tree_add_uint(param_tree, hf_sccp_sequencing_segmenting_more, tvb,
1430 SEQUENCING_SEGMENTING_SSN_LENGTH,
1431 SEQUENCING_SEGMENTING_RSN_LENGTH, more);
1435 dissect_sccp_credit_param(tvbuff_t *tvb, proto_tree *tree, guint length)
1439 credit = tvb_get_guint8(tvb, 0);
1440 proto_tree_add_uint(tree, hf_sccp_credit, tvb, 0, length, credit);
1444 dissect_sccp_release_cause_param(tvbuff_t *tvb, proto_tree *tree, guint length, packet_info *pinfo)
1448 cause = tvb_get_guint8(tvb, 0);
1449 proto_tree_add_uint(tree, hf_sccp_release_cause, tvb, 0, length, cause);
1451 if (show_key_params && check_col(pinfo->cinfo, COL_INFO))
1452 col_append_fstr(pinfo->cinfo, COL_INFO, "Cause=%d ", cause);
1456 dissect_sccp_return_cause_param(tvbuff_t *tvb, proto_tree *tree, guint length, packet_info *pinfo)
1460 cause = tvb_get_guint8(tvb, 0);
1461 proto_tree_add_uint(tree, hf_sccp_return_cause, tvb, 0, length, cause);
1463 if (show_key_params && check_col(pinfo->cinfo, COL_INFO))
1464 col_append_fstr(pinfo->cinfo, COL_INFO, "Cause=%d ", cause);
1468 dissect_sccp_reset_cause_param(tvbuff_t *tvb, proto_tree *tree, guint length, packet_info *pinfo)
1472 cause = tvb_get_guint8(tvb, 0);
1473 proto_tree_add_uint(tree, hf_sccp_reset_cause, tvb, 0, length, cause);
1475 if (show_key_params && check_col(pinfo->cinfo, COL_INFO))
1476 col_append_fstr(pinfo->cinfo, COL_INFO, "Cause=%d ", cause);
1480 dissect_sccp_error_cause_param(tvbuff_t *tvb, proto_tree *tree, guint length, packet_info *pinfo)
1484 cause = tvb_get_guint8(tvb, 0);
1485 proto_tree_add_uint(tree, hf_sccp_error_cause, tvb, 0, length, cause);
1487 if (show_key_params && check_col(pinfo->cinfo, COL_INFO))
1488 col_append_fstr(pinfo->cinfo, COL_INFO, "Cause=%d ", cause);
1492 dissect_sccp_refusal_cause_param(tvbuff_t *tvb, proto_tree *tree, guint length, packet_info *pinfo)
1496 cause = tvb_get_guint8(tvb, 0);
1497 proto_tree_add_uint(tree, hf_sccp_refusal_cause, tvb, 0, length, cause);
1499 if (show_key_params && check_col(pinfo->cinfo, COL_INFO))
1500 col_append_fstr(pinfo->cinfo, COL_INFO, "Cause=%d ", cause);
1504 /* This function is used for both data and long data (ITU only) parameters */
1506 dissect_sccp_data_param(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
1508 guint8 ssn = INVALID_SSN;
1509 guint8 other_ssn = INVALID_SSN;
1510 const mtp3_addr_pc_t* dpc;
1511 const mtp3_addr_pc_t* opc;
1513 if (trace_sccp && assoc && assoc != &no_assoc) {
1514 pinfo->sccp_info = assoc->curr_msg;
1516 pinfo->sccp_info = NULL;
1519 switch (pinfo->p2p_dir) {
1521 ssn = assoc->calling_ssn;
1522 dpc = (const mtp3_addr_pc_t*)pinfo->dst.data;
1523 opc = (const mtp3_addr_pc_t*)pinfo->src.data;
1526 ssn = assoc->called_ssn;
1527 dpc = (const mtp3_addr_pc_t*)pinfo->src.data;
1528 opc = (const mtp3_addr_pc_t*)pinfo->dst.data;
1531 ssn = assoc->called_ssn;
1532 other_ssn = assoc->calling_ssn;
1533 dpc = (const mtp3_addr_pc_t*)pinfo->dst.data;
1534 opc = (const mtp3_addr_pc_t*)pinfo->src.data;
1539 if (num_sccp_users && pinfo->src.type == AT_SS7PC) {
1541 dissector_handle_t handle = NULL;
1542 gboolean uses_tcap = FALSE;
1544 for (i=0; i < num_sccp_users; i++) {
1545 sccp_user_t* u = &(sccp_users[i]);
1547 if (dpc->ni != u->ni) continue;
1549 if (value_is_in_range(u->called_ssn, ssn) && value_is_in_range(u->called_pc, dpc->pc) ) {
1550 handle = *(u->handlep);
1551 uses_tcap = u->uses_tcap;
1553 } else if (value_is_in_range(u->called_ssn, other_ssn) && value_is_in_range(u->called_pc, opc->pc) ) {
1554 handle = *(u->handlep);
1555 uses_tcap = u->uses_tcap;
1562 call_tcap_dissector(handle, tvb, pinfo, tree);
1564 call_dissector(handle, tvb, pinfo, tree);
1571 if (ssn != INVALID_SSN && dissector_try_port(sccp_ssn_dissector_table, ssn, tvb, pinfo, tree)) {
1575 if (other_ssn != INVALID_SSN && dissector_try_port(sccp_ssn_dissector_table, other_ssn, tvb, pinfo, tree)) {
1579 /* try heuristic subdissector list to see if there are any takers */
1580 if (dissector_try_heuristic(heur_subdissector_list, tvb, pinfo, tree)) {
1584 /* No sub-dissection occured, treat it as raw data */
1585 call_dissector(data_handle, tvb, pinfo, tree);
1590 dissect_sccp_segmentation_param(tvbuff_t *tvb, proto_tree *tree, guint length)
1592 guint8 first, class, remaining;
1594 proto_item *param_item;
1595 proto_tree *param_tree;
1597 first = tvb_get_guint8(tvb, 0) & SEGMENTATION_FIRST_SEGMENT_MASK;
1598 class = tvb_get_guint8(tvb, 0) & SEGMENTATION_CLASS_MASK;
1599 remaining = tvb_get_guint8(tvb, 0) & SEGMENTATION_REMAINING_MASK;
1601 slr = tvb_get_letoh24(tvb, 1);
1603 param_item = proto_tree_add_text(tree, tvb, 0, length,
1604 val_to_str(PARAMETER_SEGMENTATION,
1605 sccp_parameter_values, "Unknown"));
1606 param_tree = proto_item_add_subtree(param_item, ett_sccp_segmentation);
1608 proto_tree_add_uint(param_tree, hf_sccp_segmentation_first, tvb, 0, length,
1610 proto_tree_add_uint(param_tree, hf_sccp_segmentation_class, tvb, 0, length,
1612 proto_tree_add_uint(param_tree, hf_sccp_segmentation_remaining, tvb, 0,
1614 proto_tree_add_uint(param_tree, hf_sccp_segmentation_slr, tvb, 1, length,
1619 dissect_sccp_hop_counter_param(tvbuff_t *tvb, proto_tree *tree, guint length)
1623 hops = tvb_get_guint8(tvb, 0);
1624 proto_tree_add_uint(tree, hf_sccp_hop_counter, tvb, 0, length, hops);
1628 dissect_sccp_importance_param(tvbuff_t *tvb, proto_tree *tree, guint length)
1632 importance = tvb_get_guint8(tvb, 0) & IMPORTANCE_IMPORTANCE_MASK;
1633 proto_tree_add_uint(tree, hf_sccp_importance, tvb, 0, length, importance);
1637 dissect_sccp_isni_param(tvbuff_t *tvb, proto_tree *tree, guint length)
1639 guint8 mi, iri, ti, network, netspec;
1641 proto_item *param_item;
1642 proto_tree *param_tree;
1644 /* Create a subtree for ISNI Routing Control */
1645 param_item = proto_tree_add_text(tree, tvb, offset, ANSI_ISNI_ROUTING_CONTROL_LENGTH,
1646 "ISNI Routing Control");
1647 param_tree = proto_item_add_subtree(param_item,
1648 ett_sccp_ansi_isni_routing_control);
1650 mi = tvb_get_guint8(tvb, offset) & ANSI_ISNI_MI_MASK;
1651 proto_tree_add_uint(param_tree, hf_sccp_ansi_isni_mi, tvb, offset,
1652 ANSI_ISNI_ROUTING_CONTROL_LENGTH, mi);
1654 iri = tvb_get_guint8(tvb, offset) & ANSI_ISNI_IRI_MASK;
1655 proto_tree_add_uint(param_tree, hf_sccp_ansi_isni_iri, tvb, offset,
1656 ANSI_ISNI_ROUTING_CONTROL_LENGTH, iri);
1658 ti = tvb_get_guint8(tvb, offset) & ANSI_ISNI_TI_MASK;
1659 proto_tree_add_uint(param_tree, hf_sccp_ansi_isni_ti, tvb, offset,
1660 ANSI_ISNI_ROUTING_CONTROL_LENGTH, ti);
1662 offset += ANSI_ISNI_ROUTING_CONTROL_LENGTH;
1664 if ((ti >> ANSI_ISNI_TI_SHIFT) == ANSI_ISNI_TYPE_1) {
1665 netspec = tvb_get_guint8(tvb, offset) & ANSI_ISNI_NETSPEC_MASK;
1666 proto_tree_add_uint(param_tree, hf_sccp_ansi_isni_netspec, tvb, offset,
1667 ANSI_ISNI_ROUTING_CONTROL_LENGTH, ti);
1668 offset += ANSI_ISNI_ROUTING_CONTROL_LENGTH;
1671 while (offset < length) {
1673 network = tvb_get_guint8(tvb, offset);
1674 proto_tree_add_text(tree, tvb, offset, ANSI_NCM_LENGTH,
1675 "Network ID network: %d", network);
1678 network = tvb_get_guint8(tvb, offset);
1679 proto_tree_add_text(tree, tvb, offset, ANSI_NCM_LENGTH,
1680 "Network ID cluster: %d", network);
1686 /* FUNCTION dissect_sccp_parameter():
1687 * Dissect a parameter given its type, offset into tvb, and length.
1690 dissect_sccp_parameter(tvbuff_t *tvb, packet_info *pinfo, proto_tree *sccp_tree,
1691 proto_tree *tree, guint8 parameter_type, guint16 offset,
1692 guint16 parameter_length)
1694 tvbuff_t *parameter_tvb;
1696 switch (parameter_type) {
1697 case PARAMETER_CALLED_PARTY_ADDRESS:
1698 case PARAMETER_CALLING_PARTY_ADDRESS:
1699 case PARAMETER_DATA:
1700 case PARAMETER_LONG_DATA:
1701 case PARAMETER_SOURCE_LOCAL_REFERENCE:
1702 case PARAMETER_DESTINATION_LOCAL_REFERENCE:
1703 case PARAMETER_RELEASE_CAUSE:
1704 case PARAMETER_RETURN_CAUSE:
1705 case PARAMETER_RESET_CAUSE:
1706 case PARAMETER_ERROR_CAUSE:
1707 case PARAMETER_REFUSAL_CAUSE:
1709 /* These parameters must be dissected even if !sccp_tree (so that
1710 * assoc information can be created).
1715 if (!sccp_tree) return(parameter_length);
1719 parameter_tvb = tvb_new_subset(tvb, offset, parameter_length, parameter_length);
1721 switch (parameter_type) {
1723 case PARAMETER_END_OF_OPTIONAL_PARAMETERS:
1724 proto_tree_add_text(sccp_tree, tvb, offset, parameter_length,
1728 case PARAMETER_DESTINATION_LOCAL_REFERENCE:
1729 dissect_sccp_dlr_param(parameter_tvb, sccp_tree, parameter_length, pinfo);
1732 case PARAMETER_SOURCE_LOCAL_REFERENCE:
1733 dissect_sccp_slr_param(parameter_tvb, sccp_tree, parameter_length, pinfo);
1736 case PARAMETER_CALLED_PARTY_ADDRESS:
1737 dissect_sccp_called_param(parameter_tvb, sccp_tree, parameter_length);
1740 case PARAMETER_CALLING_PARTY_ADDRESS:
1741 dissect_sccp_calling_param(parameter_tvb, sccp_tree, parameter_length);
1744 case PARAMETER_CLASS:
1745 dissect_sccp_class_param(parameter_tvb, sccp_tree, parameter_length);
1748 case PARAMETER_SEGMENTING_REASSEMBLING:
1749 dissect_sccp_segmenting_reassembling_param(parameter_tvb, sccp_tree,
1753 case PARAMETER_RECEIVE_SEQUENCE_NUMBER:
1754 dissect_sccp_receive_sequence_number_param(parameter_tvb, sccp_tree,
1758 case PARAMETER_SEQUENCING_SEGMENTING:
1759 dissect_sccp_sequencing_segmenting_param(parameter_tvb, sccp_tree,
1763 case PARAMETER_CREDIT:
1764 dissect_sccp_credit_param(parameter_tvb, sccp_tree, parameter_length);
1767 case PARAMETER_RELEASE_CAUSE:
1768 dissect_sccp_release_cause_param(parameter_tvb, sccp_tree, parameter_length, pinfo);
1771 case PARAMETER_RETURN_CAUSE:
1772 dissect_sccp_return_cause_param(parameter_tvb, sccp_tree, parameter_length, pinfo);
1775 case PARAMETER_RESET_CAUSE:
1776 dissect_sccp_reset_cause_param(parameter_tvb, sccp_tree, parameter_length, pinfo);
1779 case PARAMETER_ERROR_CAUSE:
1780 dissect_sccp_error_cause_param(parameter_tvb, sccp_tree, parameter_length, pinfo);
1783 case PARAMETER_REFUSAL_CAUSE:
1784 dissect_sccp_refusal_cause_param(parameter_tvb, sccp_tree, parameter_length, pinfo);
1787 case PARAMETER_DATA:
1788 dissect_sccp_data_param(parameter_tvb, pinfo, tree);
1790 /* TODO? Re-adjust length of SCCP item since it may be sub-dissected */
1791 /* sccp_length = proto_item_get_len(sccp_item);
1792 * sccp_length -= parameter_length;
1793 * proto_item_set_len(sccp_item, sccp_length);
1797 case PARAMETER_SEGMENTATION:
1798 dissect_sccp_segmentation_param(parameter_tvb, sccp_tree, parameter_length);
1801 case PARAMETER_HOP_COUNTER:
1802 dissect_sccp_hop_counter_param(parameter_tvb, sccp_tree, parameter_length);
1805 case PARAMETER_IMPORTANCE:
1806 if (decode_mtp3_standard != ANSI_STANDARD)
1807 dissect_sccp_importance_param(parameter_tvb, sccp_tree, parameter_length);
1809 dissect_sccp_unknown_param(parameter_tvb, sccp_tree, parameter_type,
1813 case PARAMETER_LONG_DATA:
1814 if (decode_mtp3_standard != ANSI_STANDARD)
1815 dissect_sccp_data_param(parameter_tvb, pinfo, tree);
1817 dissect_sccp_unknown_param(parameter_tvb, sccp_tree, parameter_type,
1821 case PARAMETER_ISNI:
1822 if (decode_mtp3_standard != ANSI_STANDARD)
1823 dissect_sccp_unknown_param(parameter_tvb, sccp_tree, parameter_type,
1826 dissect_sccp_isni_param(parameter_tvb, sccp_tree, parameter_length);
1830 dissect_sccp_unknown_param(parameter_tvb, sccp_tree, parameter_type,
1835 return(parameter_length);
1838 /* FUNCTION dissect_sccp_variable_parameter():
1839 * Dissect a variable parameter given its type and offset into tvb. Length
1840 * of the parameter is gotten from tvb[0].
1841 * Length returned is sum of (length + parameter).
1844 dissect_sccp_variable_parameter(tvbuff_t *tvb, packet_info *pinfo,
1845 proto_tree *sccp_tree, proto_tree *tree,
1846 guint8 parameter_type, guint16 offset)
1848 guint16 parameter_length;
1849 guint8 length_length;
1851 if (parameter_type != PARAMETER_LONG_DATA)
1853 parameter_length = tvb_get_guint8(tvb, offset);
1854 length_length = PARAMETER_LENGTH_LENGTH;
1858 /* Long data parameter has 16 bit length */
1859 parameter_length = tvb_get_letohs(tvb, offset);
1860 length_length = PARAMETER_LONG_DATA_LENGTH_LENGTH;
1863 if (sccp_tree && sccp_show_length)
1865 proto_tree_add_text(sccp_tree, tvb, offset, length_length,
1867 val_to_str(parameter_type, sccp_parameter_values,
1872 offset += length_length;
1874 dissect_sccp_parameter(tvb, pinfo, sccp_tree, tree, parameter_type, offset,
1877 return(parameter_length + length_length);
1880 /* FUNCTION dissect_sccp_optional_parameters():
1881 * Dissect all the optional parameters given the start of the optional
1882 * parameters into tvb. Parameter types and lengths are read from tvb.
1885 dissect_sccp_optional_parameters(tvbuff_t *tvb, packet_info *pinfo,
1886 proto_tree *sccp_tree, proto_tree *tree,
1889 guint8 parameter_type;
1891 while ((parameter_type = tvb_get_guint8(tvb, offset)) !=
1892 PARAMETER_END_OF_OPTIONAL_PARAMETERS) {
1894 offset += PARAMETER_TYPE_LENGTH;
1895 offset += dissect_sccp_variable_parameter(tvb, pinfo, sccp_tree, tree,
1896 parameter_type, offset);
1899 /* Process end of optional parameters */
1900 dissect_sccp_parameter(tvb, pinfo, sccp_tree, tree, parameter_type, offset,
1901 END_OF_OPTIONAL_PARAMETERS_LENGTH);
1905 static sccp_msg_info_t* new_ud_msg(packet_info* pinfo, guint32 msg_type _U_) {
1906 sccp_msg_info_t* m = ep_alloc(sizeof(sccp_msg_info_t));
1907 m->framenum = pinfo->fd->num;
1908 m->offset = 0; /* irrelevant */
1910 m->data.ud.calling_gt = NULL;
1911 m->data.ud.calling_ssn = 0;
1912 m->data.ud.called_gt = NULL;
1913 m->data.ud.called_ssn = 0;
1919 dissect_sccp_message(tvbuff_t *tvb, packet_info *pinfo, proto_tree *sccp_tree,
1922 guint16 variable_pointer1 = 0, variable_pointer2 = 0, variable_pointer3 = 0;
1923 guint16 optional_pointer = 0, orig_opt_ptr = 0;
1925 guint8 parameter_type;
1926 gboolean save_fragmented;
1927 tvbuff_t *new_tvb = NULL;
1928 fragment_data *frag_msg = NULL;
1929 guint32 source_local_ref=0;
1931 guint msg_offset = offset_from_real_beginning(tvb,0);
1933 /* Macro for getting pointer to mandatory variable parameters */
1934 #define VARIABLE_POINTER(var, hf_var, ptr_size) \
1935 if (ptr_size == POINTER_LENGTH) \
1936 var = tvb_get_guint8(tvb, offset); \
1938 var = tvb_get_letohs(tvb, offset); \
1939 proto_tree_add_uint(sccp_tree, hf_var, tvb, \
1940 offset, ptr_size, var); \
1942 if (ptr_size == POINTER_LENGTH_LONG) \
1946 /* Macro for getting pointer to optional parameters */
1947 #define OPTIONAL_POINTER(ptr_size) \
1948 if (ptr_size == POINTER_LENGTH) \
1949 orig_opt_ptr = optional_pointer = tvb_get_guint8(tvb, offset); \
1951 orig_opt_ptr = optional_pointer = tvb_get_letohs(tvb, offset); \
1952 proto_tree_add_uint(sccp_tree, hf_sccp_optional_pointer, tvb, \
1953 offset, ptr_size, optional_pointer); \
1954 optional_pointer += offset; \
1955 if (ptr_size == POINTER_LENGTH_LONG) \
1956 optional_pointer += 1; \
1960 /* Extract the message type; all other processing is based on this */
1961 message_type = tvb_get_guint8(tvb, SCCP_MSG_TYPE_OFFSET);
1962 offset = SCCP_MSG_TYPE_LENGTH;
1964 if (check_col(pinfo->cinfo, COL_INFO)) {
1965 col_append_fstr(pinfo->cinfo, COL_INFO, "%s ",
1966 val_to_str(message_type, sccp_message_type_acro_values, "Unknown"));
1970 /* add the message type to the protocol tree */
1971 proto_tree_add_uint(sccp_tree, hf_sccp_message_type, tvb,
1972 SCCP_MSG_TYPE_OFFSET, SCCP_MSG_TYPE_LENGTH, message_type);
1976 /* Starting a new message dissection; clear the global assoc, SLR, and DLR values */
1981 no_assoc.calling_dpc = 0;
1982 no_assoc.called_dpc = 0;
1983 no_assoc.calling_ssn = INVALID_SSN;
1984 no_assoc.called_ssn = INVALID_SSN;
1985 no_assoc.has_fw_key = FALSE;
1986 no_assoc.has_bw_key = FALSE;
1987 no_assoc.payload = SCCP_PLOAD_NONE;
1988 no_assoc.called_party = NULL;
1989 no_assoc.calling_party = NULL;
1990 no_assoc.extra_info = NULL;
1992 switch(message_type) {
1993 case SCCP_MSG_TYPE_CR:
1994 /* TTC and NTT (Japan) say that the connection-oriented messages are
1995 * deleted (not standardized), but they appear to be used anyway, so
1996 * we'll dissect it...
1998 offset += dissect_sccp_parameter(tvb, pinfo, sccp_tree, tree,
1999 PARAMETER_SOURCE_LOCAL_REFERENCE,
2000 offset, SOURCE_LOCAL_REFERENCE_LENGTH);
2001 offset += dissect_sccp_parameter(tvb, pinfo, sccp_tree, tree,
2002 PARAMETER_CLASS, offset,
2003 PROTOCOL_CLASS_LENGTH);
2004 assoc = get_sccp_assoc(pinfo, msg_offset, slr, dlr, message_type);
2006 VARIABLE_POINTER(variable_pointer1, hf_sccp_variable_pointer1, POINTER_LENGTH)
2007 OPTIONAL_POINTER(POINTER_LENGTH)
2009 dissect_sccp_variable_parameter(tvb, pinfo, sccp_tree, tree,
2010 PARAMETER_CALLED_PARTY_ADDRESS,
2014 case SCCP_MSG_TYPE_CC:
2015 /* TODO: connection has been established; theoretically we could keep
2016 * keep track of the SLR/DLR with the called/calling from the CR and
2017 * track the connection (e.g., on subsequent messages regarding this
2018 * SLR we could set the global vars "call*_ssn" so data could get
2021 offset += dissect_sccp_parameter(tvb, pinfo, sccp_tree, tree,
2022 PARAMETER_DESTINATION_LOCAL_REFERENCE,
2024 DESTINATION_LOCAL_REFERENCE_LENGTH);
2025 offset += dissect_sccp_parameter(tvb, pinfo, sccp_tree, tree,
2026 PARAMETER_SOURCE_LOCAL_REFERENCE,
2027 offset, SOURCE_LOCAL_REFERENCE_LENGTH);
2029 assoc = get_sccp_assoc(pinfo, msg_offset, slr, dlr, message_type);
2031 offset += dissect_sccp_parameter(tvb, pinfo, sccp_tree, tree,
2032 PARAMETER_CLASS, offset,
2033 PROTOCOL_CLASS_LENGTH);
2034 OPTIONAL_POINTER(POINTER_LENGTH);
2037 case SCCP_MSG_TYPE_CREF:
2038 offset += dissect_sccp_parameter(tvb, pinfo, sccp_tree, tree,
2039 PARAMETER_DESTINATION_LOCAL_REFERENCE,
2041 DESTINATION_LOCAL_REFERENCE_LENGTH);
2043 assoc = get_sccp_assoc(pinfo, msg_offset, slr, dlr, message_type);
2045 offset += dissect_sccp_parameter(tvb, pinfo, sccp_tree, tree,
2046 PARAMETER_REFUSAL_CAUSE, offset,
2047 REFUSAL_CAUSE_LENGTH);
2048 OPTIONAL_POINTER(POINTER_LENGTH);
2051 case SCCP_MSG_TYPE_RLSD:
2052 offset += dissect_sccp_parameter(tvb, pinfo, sccp_tree, tree,
2053 PARAMETER_DESTINATION_LOCAL_REFERENCE,
2055 DESTINATION_LOCAL_REFERENCE_LENGTH);
2056 offset += dissect_sccp_parameter(tvb, pinfo, sccp_tree, tree,
2057 PARAMETER_SOURCE_LOCAL_REFERENCE,
2058 offset, SOURCE_LOCAL_REFERENCE_LENGTH);
2060 assoc = get_sccp_assoc(pinfo, msg_offset, slr, dlr, message_type);
2062 offset += dissect_sccp_parameter(tvb, pinfo, sccp_tree, tree,
2063 PARAMETER_RELEASE_CAUSE, offset,
2064 RELEASE_CAUSE_LENGTH);
2066 OPTIONAL_POINTER(POINTER_LENGTH);
2067 assoc = get_sccp_assoc(pinfo, msg_offset, slr, dlr, message_type);
2070 case SCCP_MSG_TYPE_RLC:
2071 offset += dissect_sccp_parameter(tvb, pinfo, sccp_tree, tree,
2072 PARAMETER_DESTINATION_LOCAL_REFERENCE,
2074 DESTINATION_LOCAL_REFERENCE_LENGTH);
2075 offset += dissect_sccp_parameter(tvb, pinfo, sccp_tree, tree,
2076 PARAMETER_SOURCE_LOCAL_REFERENCE,
2077 offset, SOURCE_LOCAL_REFERENCE_LENGTH);
2079 assoc = get_sccp_assoc(pinfo, msg_offset, slr, dlr, message_type);
2083 case SCCP_MSG_TYPE_DT1:
2084 source_local_ref = tvb_get_letoh24(tvb, offset);
2085 offset += dissect_sccp_parameter(tvb, pinfo, sccp_tree, tree,
2086 PARAMETER_DESTINATION_LOCAL_REFERENCE,
2088 DESTINATION_LOCAL_REFERENCE_LENGTH);
2090 assoc = get_sccp_assoc(pinfo, msg_offset, slr, dlr, message_type);
2092 more = tvb_get_guint8(tvb, offset) & SEGMENTING_REASSEMBLING_MASK;
2094 offset += dissect_sccp_parameter(tvb, pinfo, sccp_tree, tree,
2095 PARAMETER_SEGMENTING_REASSEMBLING,
2096 offset, SEGMENTING_REASSEMBLING_LENGTH);
2097 VARIABLE_POINTER(variable_pointer1, hf_sccp_variable_pointer1, POINTER_LENGTH)
2100 if (!sccp_xudt_desegment) {
2101 proto_tree_add_text(sccp_tree, tvb, variable_pointer1,
2102 tvb_get_guint8(tvb, variable_pointer1)+1,
2104 dissect_sccp_variable_parameter(tvb, pinfo, sccp_tree, tree,
2105 PARAMETER_DATA, variable_pointer1);
2108 save_fragmented = pinfo->fragmented;
2109 pinfo->fragmented = TRUE;
2110 frag_msg = fragment_add_seq_next(tvb, variable_pointer1 + 1, pinfo,
2111 source_local_ref, /* ID for fragments belonging together */
2112 sccp_xudt_msg_fragment_table, /* list of message fragments */
2113 sccp_xudt_msg_reassembled_table, /* list of reassembled messages */
2114 tvb_get_guint8(tvb,variable_pointer1),/* fragment length - to the end */
2115 more); /* More fragments? */
2117 new_tvb = process_reassembled_data(tvb, variable_pointer1 + 1, pinfo,
2118 "Reassembled Message", frag_msg,
2119 &sccp_xudt_msg_frag_items, NULL,
2122 if (frag_msg && frag_msg->next) { /* Reassembled */
2123 if (check_col(pinfo->cinfo, COL_INFO))
2124 col_append_str(pinfo->cinfo, COL_INFO,
2125 "(Message reassembled) ");
2126 } else if (more) { /* Not last packet of reassembled message */
2127 if (check_col(pinfo->cinfo, COL_INFO))
2128 col_append_str(pinfo->cinfo, COL_INFO, "(Message fragment) ");
2131 pinfo->fragmented = save_fragmented;
2134 dissect_sccp_data_param(new_tvb, pinfo, tree);
2137 /* End reassemble */
2140 case SCCP_MSG_TYPE_DT2:
2141 offset += dissect_sccp_parameter(tvb, pinfo, sccp_tree, tree,
2142 PARAMETER_DESTINATION_LOCAL_REFERENCE,
2144 DESTINATION_LOCAL_REFERENCE_LENGTH);
2146 assoc = get_sccp_assoc(pinfo, msg_offset, slr, dlr, message_type);
2148 offset += dissect_sccp_parameter(tvb, pinfo, sccp_tree, tree,
2149 PARAMETER_SEQUENCING_SEGMENTING, offset,
2150 SEQUENCING_SEGMENTING_LENGTH);
2153 case SCCP_MSG_TYPE_AK:
2154 offset += dissect_sccp_parameter(tvb, pinfo, sccp_tree, tree,
2155 PARAMETER_DESTINATION_LOCAL_REFERENCE,
2157 DESTINATION_LOCAL_REFERENCE_LENGTH);
2159 assoc = get_sccp_assoc(pinfo, msg_offset, slr, dlr, message_type);
2161 offset += dissect_sccp_parameter(tvb, pinfo, sccp_tree, tree,
2162 PARAMETER_RECEIVE_SEQUENCE_NUMBER,
2163 offset, RECEIVE_SEQUENCE_NUMBER_LENGTH);
2164 offset += dissect_sccp_parameter(tvb, pinfo, sccp_tree, tree,
2165 PARAMETER_CREDIT, offset, CREDIT_LENGTH);
2168 case SCCP_MSG_TYPE_UDT:
2169 pinfo->sccp_info = sccp_msg = new_ud_msg(pinfo,message_type);
2171 offset += dissect_sccp_parameter(tvb, pinfo, sccp_tree, tree,
2172 PARAMETER_CLASS, offset,
2173 PROTOCOL_CLASS_LENGTH);
2174 VARIABLE_POINTER(variable_pointer1, hf_sccp_variable_pointer1, POINTER_LENGTH)
2175 VARIABLE_POINTER(variable_pointer2, hf_sccp_variable_pointer2, POINTER_LENGTH)
2176 VARIABLE_POINTER(variable_pointer3, hf_sccp_variable_pointer3, POINTER_LENGTH)
2178 assoc = get_sccp_assoc(pinfo, msg_offset, slr, dlr, message_type);
2180 dissect_sccp_variable_parameter(tvb, pinfo, sccp_tree, tree,
2181 PARAMETER_CALLED_PARTY_ADDRESS,
2183 dissect_sccp_variable_parameter(tvb, pinfo, sccp_tree, tree,
2184 PARAMETER_CALLING_PARTY_ADDRESS,
2187 dissect_sccp_variable_parameter(tvb, pinfo, sccp_tree, tree, PARAMETER_DATA,
2191 case SCCP_MSG_TYPE_UDTS:
2192 pinfo->sccp_info = sccp_msg = new_ud_msg(pinfo,message_type);
2194 offset += dissect_sccp_parameter(tvb, pinfo, sccp_tree, tree,
2195 PARAMETER_RETURN_CAUSE, offset,
2196 RETURN_CAUSE_LENGTH);
2198 VARIABLE_POINTER(variable_pointer1, hf_sccp_variable_pointer1, POINTER_LENGTH)
2199 VARIABLE_POINTER(variable_pointer2, hf_sccp_variable_pointer2, POINTER_LENGTH)
2200 VARIABLE_POINTER(variable_pointer3, hf_sccp_variable_pointer3, POINTER_LENGTH)
2202 assoc = get_sccp_assoc(pinfo, msg_offset, slr, dlr, message_type);
2204 dissect_sccp_variable_parameter(tvb, pinfo, sccp_tree, tree,
2205 PARAMETER_CALLED_PARTY_ADDRESS,
2208 dissect_sccp_variable_parameter(tvb, pinfo, sccp_tree, tree,
2209 PARAMETER_CALLING_PARTY_ADDRESS,
2212 dissect_sccp_variable_parameter(tvb, pinfo, sccp_tree, tree, PARAMETER_DATA,
2216 case SCCP_MSG_TYPE_ED:
2217 offset += dissect_sccp_parameter(tvb, pinfo, sccp_tree, tree,
2218 PARAMETER_DESTINATION_LOCAL_REFERENCE,
2220 DESTINATION_LOCAL_REFERENCE_LENGTH);
2222 assoc = get_sccp_assoc(pinfo, msg_offset, slr, dlr, message_type);
2224 VARIABLE_POINTER(variable_pointer1, hf_sccp_variable_pointer1, POINTER_LENGTH);
2226 dissect_sccp_variable_parameter(tvb, pinfo, sccp_tree, tree, PARAMETER_DATA,
2230 case SCCP_MSG_TYPE_EA:
2231 offset += dissect_sccp_parameter(tvb, pinfo, sccp_tree, tree,
2232 PARAMETER_DESTINATION_LOCAL_REFERENCE,
2234 DESTINATION_LOCAL_REFERENCE_LENGTH);
2235 assoc = get_sccp_assoc(pinfo, msg_offset, slr, dlr, message_type);
2239 case SCCP_MSG_TYPE_RSR:
2240 offset += dissect_sccp_parameter(tvb, pinfo, sccp_tree, tree,
2241 PARAMETER_DESTINATION_LOCAL_REFERENCE,
2243 DESTINATION_LOCAL_REFERENCE_LENGTH);
2244 offset += dissect_sccp_parameter(tvb, pinfo, sccp_tree, tree,
2245 PARAMETER_SOURCE_LOCAL_REFERENCE,
2246 offset, SOURCE_LOCAL_REFERENCE_LENGTH);
2247 offset += dissect_sccp_parameter(tvb, pinfo, sccp_tree, tree,
2248 PARAMETER_RESET_CAUSE, offset,
2249 RESET_CAUSE_LENGTH);
2250 assoc = get_sccp_assoc(pinfo, msg_offset, slr, dlr, message_type);
2253 case SCCP_MSG_TYPE_RSC:
2254 offset += dissect_sccp_parameter(tvb, pinfo, sccp_tree, tree,
2255 PARAMETER_DESTINATION_LOCAL_REFERENCE,
2257 DESTINATION_LOCAL_REFERENCE_LENGTH);
2258 offset += dissect_sccp_parameter(tvb, pinfo, sccp_tree, tree,
2259 PARAMETER_SOURCE_LOCAL_REFERENCE,
2260 offset, SOURCE_LOCAL_REFERENCE_LENGTH);
2261 assoc = get_sccp_assoc(pinfo, msg_offset, slr, dlr, message_type);
2264 case SCCP_MSG_TYPE_ERR:
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_ERROR_CAUSE, offset,
2271 ERROR_CAUSE_LENGTH);
2272 assoc = get_sccp_assoc(pinfo, msg_offset, slr, dlr, message_type);
2275 case SCCP_MSG_TYPE_IT:
2276 offset += dissect_sccp_parameter(tvb, pinfo, sccp_tree, tree,
2277 PARAMETER_DESTINATION_LOCAL_REFERENCE,
2279 DESTINATION_LOCAL_REFERENCE_LENGTH);
2280 offset += dissect_sccp_parameter(tvb, pinfo, sccp_tree, tree,
2281 PARAMETER_SOURCE_LOCAL_REFERENCE,
2282 offset, SOURCE_LOCAL_REFERENCE_LENGTH);
2283 assoc = get_sccp_assoc(pinfo, msg_offset, slr, dlr, message_type);
2284 offset += dissect_sccp_parameter(tvb, pinfo, sccp_tree, tree,
2285 PARAMETER_CLASS, offset,
2286 PROTOCOL_CLASS_LENGTH);
2287 offset += dissect_sccp_parameter(tvb, pinfo, sccp_tree, tree,
2288 PARAMETER_SEQUENCING_SEGMENTING,
2289 offset, SEQUENCING_SEGMENTING_LENGTH);
2290 offset += dissect_sccp_parameter(tvb, pinfo, sccp_tree, tree,
2291 PARAMETER_CREDIT, offset, CREDIT_LENGTH);
2294 case SCCP_MSG_TYPE_XUDT:
2295 pinfo->sccp_info = sccp_msg = new_ud_msg(pinfo,message_type);
2296 offset += dissect_sccp_parameter(tvb, pinfo, sccp_tree, tree,
2297 PARAMETER_CLASS, offset,
2298 PROTOCOL_CLASS_LENGTH);
2299 offset += dissect_sccp_parameter(tvb, pinfo, sccp_tree, tree,
2300 PARAMETER_HOP_COUNTER, offset,
2301 HOP_COUNTER_LENGTH);
2303 VARIABLE_POINTER(variable_pointer1, hf_sccp_variable_pointer1, POINTER_LENGTH)
2304 VARIABLE_POINTER(variable_pointer2, hf_sccp_variable_pointer2, POINTER_LENGTH)
2305 VARIABLE_POINTER(variable_pointer3, hf_sccp_variable_pointer3, POINTER_LENGTH)
2306 OPTIONAL_POINTER(POINTER_LENGTH)
2308 /* Optional parameters are Segmentation and Importance
2309 * NOTE 2 - Segmentation Should not be present in case of a single XUDT
2313 assoc = get_sccp_assoc(pinfo, msg_offset, slr, dlr, message_type);
2315 dissect_sccp_variable_parameter(tvb, pinfo, sccp_tree, tree,
2316 PARAMETER_CALLED_PARTY_ADDRESS,
2318 dissect_sccp_variable_parameter(tvb, pinfo, sccp_tree, tree,
2319 PARAMETER_CALLING_PARTY_ADDRESS,
2322 if ((parameter_type = tvb_get_guint8(tvb, optional_pointer)) == PARAMETER_SEGMENTATION){
2323 if (!sccp_xudt_desegment){
2324 proto_tree_add_text(sccp_tree, tvb, variable_pointer3, tvb_get_guint8(tvb, variable_pointer3)+1, "Segmented Data" );
2328 gboolean more_frag = TRUE;
2331 /* Get the first octet of parameter Segmentation, Ch 3.17 in Q.713
2332 * Bit 8 of octet 1 is used for First segment indication
2333 * Bit 7 of octet 1 is used to keep in the message in sequence
2334 * delivery option required by the SCCP user
2335 * Bits 6 and 5 in octet 1 are spare bits.
2336 * Bits 4-1 of octet 1 are used to indicate the number of
2337 * remaining segments.
2338 * The values 0000 to 1111 are possible; the value 0000 indicates
2341 octet = tvb_get_guint8(tvb,optional_pointer+2);
2342 source_local_ref = tvb_get_letoh24(tvb, optional_pointer+3);
2344 if ((octet&0x0f) == 0)
2347 save_fragmented = pinfo->fragmented;
2348 pinfo->fragmented = TRUE;
2349 frag_msg = fragment_add_seq_next(tvb, variable_pointer3 + 1, pinfo,
2350 source_local_ref, /* ID for fragments belonging together */
2351 sccp_xudt_msg_fragment_table, /* list of message fragments */
2352 sccp_xudt_msg_reassembled_table, /* list of reassembled messages */
2353 tvb_get_guint8(tvb,variable_pointer3), /* fragment length - to the end */
2354 more_frag); /* More fragments? */
2356 if ((octet&0x80) == 0x80) /*First segment, set number of segments*/
2357 fragment_set_tot_len(pinfo, source_local_ref, sccp_xudt_msg_fragment_table,(octet & 0xf));
2359 new_tvb = process_reassembled_data(tvb, variable_pointer3 + 1,
2360 pinfo, "Reassembled Message",
2362 &sccp_xudt_msg_frag_items,
2365 if (frag_msg) { /* Reassembled */
2366 if (check_col(pinfo->cinfo, COL_INFO))
2367 col_append_str(pinfo->cinfo, COL_INFO,
2368 "(Message reassembled) ");
2369 } else { /* Not last packet of reassembled message */
2370 if (check_col(pinfo->cinfo, COL_INFO))
2371 col_append_str(pinfo->cinfo, COL_INFO,
2372 "(Message fragment) ");
2375 pinfo->fragmented = save_fragmented;
2378 dissect_sccp_data_param(new_tvb, pinfo, tree);
2381 dissect_sccp_variable_parameter(tvb, pinfo, sccp_tree, tree,
2382 PARAMETER_DATA, variable_pointer3);
2386 case SCCP_MSG_TYPE_XUDTS:
2387 pinfo->sccp_info = sccp_msg = new_ud_msg(pinfo,message_type);
2388 offset += dissect_sccp_parameter(tvb, pinfo, sccp_tree, tree,
2389 PARAMETER_RETURN_CAUSE, offset,
2390 RETURN_CAUSE_LENGTH);
2391 offset += dissect_sccp_parameter(tvb, pinfo, sccp_tree, tree,
2392 PARAMETER_HOP_COUNTER, offset,
2393 HOP_COUNTER_LENGTH);
2395 VARIABLE_POINTER(variable_pointer1, hf_sccp_variable_pointer1, POINTER_LENGTH)
2396 VARIABLE_POINTER(variable_pointer2, hf_sccp_variable_pointer2, POINTER_LENGTH)
2397 VARIABLE_POINTER(variable_pointer3, hf_sccp_variable_pointer3, POINTER_LENGTH)
2398 OPTIONAL_POINTER(POINTER_LENGTH)
2400 assoc = get_sccp_assoc(pinfo, msg_offset, slr, dlr, message_type);
2402 dissect_sccp_variable_parameter(tvb, pinfo, sccp_tree, tree,
2403 PARAMETER_CALLED_PARTY_ADDRESS,
2405 dissect_sccp_variable_parameter(tvb, pinfo, sccp_tree, tree,
2406 PARAMETER_CALLING_PARTY_ADDRESS,
2408 dissect_sccp_variable_parameter(tvb, pinfo, sccp_tree, tree, PARAMETER_DATA,
2412 case SCCP_MSG_TYPE_LUDT:
2413 pinfo->sccp_info = sccp_msg = new_ud_msg(pinfo,message_type);
2414 if (decode_mtp3_standard != ANSI_STANDARD)
2416 offset += dissect_sccp_parameter(tvb, pinfo, sccp_tree, tree,
2417 PARAMETER_CLASS, offset,
2418 PROTOCOL_CLASS_LENGTH);
2419 offset += dissect_sccp_parameter(tvb, pinfo, sccp_tree, tree,
2420 PARAMETER_HOP_COUNTER, offset,
2421 HOP_COUNTER_LENGTH);
2423 VARIABLE_POINTER(variable_pointer1, hf_sccp_variable_pointer1, POINTER_LENGTH_LONG)
2424 VARIABLE_POINTER(variable_pointer2, hf_sccp_variable_pointer2, POINTER_LENGTH_LONG)
2425 VARIABLE_POINTER(variable_pointer3, hf_sccp_variable_pointer3, POINTER_LENGTH_LONG)
2426 OPTIONAL_POINTER(POINTER_LENGTH_LONG)
2428 assoc = get_sccp_assoc(pinfo, msg_offset, slr, dlr, message_type);
2430 dissect_sccp_variable_parameter(tvb, pinfo, sccp_tree, tree,
2431 PARAMETER_CALLED_PARTY_ADDRESS,
2433 dissect_sccp_variable_parameter(tvb, pinfo, sccp_tree, tree,
2434 PARAMETER_CALLING_PARTY_ADDRESS,
2436 dissect_sccp_variable_parameter(tvb, pinfo, sccp_tree, tree,
2437 PARAMETER_LONG_DATA, variable_pointer3);
2439 dissect_sccp_unknown_message(tvb, sccp_tree);
2442 case SCCP_MSG_TYPE_LUDTS:
2443 pinfo->sccp_info = sccp_msg = new_ud_msg(pinfo,message_type);
2444 if (decode_mtp3_standard != ANSI_STANDARD)
2446 offset += dissect_sccp_parameter(tvb, pinfo, sccp_tree, tree,
2447 PARAMETER_RETURN_CAUSE, offset,
2448 RETURN_CAUSE_LENGTH);
2449 offset += dissect_sccp_parameter(tvb, pinfo, sccp_tree, tree,
2450 PARAMETER_HOP_COUNTER, offset,
2451 HOP_COUNTER_LENGTH);
2453 VARIABLE_POINTER(variable_pointer1, hf_sccp_variable_pointer1, POINTER_LENGTH_LONG)
2454 VARIABLE_POINTER(variable_pointer2, hf_sccp_variable_pointer2, POINTER_LENGTH_LONG)
2455 VARIABLE_POINTER(variable_pointer3, hf_sccp_variable_pointer3, POINTER_LENGTH_LONG)
2456 OPTIONAL_POINTER(POINTER_LENGTH_LONG)
2458 assoc = get_sccp_assoc(pinfo, msg_offset, slr, dlr, message_type);
2460 dissect_sccp_variable_parameter(tvb, pinfo, sccp_tree, tree,
2461 PARAMETER_CALLED_PARTY_ADDRESS,
2463 dissect_sccp_variable_parameter(tvb, pinfo, sccp_tree, tree,
2464 PARAMETER_CALLING_PARTY_ADDRESS,
2466 dissect_sccp_variable_parameter(tvb, pinfo, sccp_tree, tree,
2467 PARAMETER_LONG_DATA, variable_pointer3);
2469 dissect_sccp_unknown_message(tvb, sccp_tree);
2473 dissect_sccp_unknown_message(tvb, sccp_tree);
2477 dissect_sccp_optional_parameters(tvb, pinfo, sccp_tree, tree,
2480 if (trace_sccp && assoc && assoc != &no_assoc) {
2481 proto_item* pi = proto_tree_add_uint(sccp_tree,hf_sccp_assoc_id,tvb,0,0,assoc->id);
2482 proto_tree* pt = proto_item_add_subtree(pi,ett_sccp_assoc);
2483 PROTO_ITEM_SET_GENERATED(pi);
2486 for(m = assoc->msgs; m ; m = m->data.co.next) {
2487 pi = proto_tree_add_uint( pt,hf_sccp_assoc_msg,tvb,0,0,m->framenum);
2489 if (assoc->payload != SCCP_PLOAD_NONE)
2490 proto_item_append_text(pi," %s", val_to_str(assoc->payload, assoc_protos, "Unknown"));
2492 if (m->data.co.label)
2493 proto_item_append_text(pi," %s", m->data.co.label);
2495 if (m->framenum == pinfo->fd->num && m->offset == msg_offset ) {
2496 tap_queue_packet(sccp_tap, pinfo, m);
2497 proto_item_append_text(pi," (current)");
2499 PROTO_ITEM_SET_GENERATED(pi);
2507 dissect_sccp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
2509 proto_item *sccp_item = NULL;
2510 proto_tree *sccp_tree = NULL;
2511 const mtp3_addr_pc_t *mtp3_addr_p;
2513 if ((pinfo->src.type == AT_SS7PC) &&
2514 ((mtp3_addr_p = (const mtp3_addr_pc_t *)pinfo->src.data)->type <= CHINESE_ITU_STANDARD))
2517 * Allow a protocol beneath to specify how the SCCP layer should be
2520 * It is possible to have multiple sets of SCCP traffic some of which is
2521 * ITU and some of which is ANSI.
2522 * An example is A-interface traffic having ANSI MTP3/ANSI SCCP/3GPP2 IOS
2523 * and at the same time ITU MTP3/ITU SCCP/ANSI TCAP/ANSI MAP.
2525 decode_mtp3_standard = mtp3_addr_p->type;
2529 decode_mtp3_standard = mtp3_standard;
2532 /* Make entry in the Protocol column on summary display */
2533 if (check_col(pinfo->cinfo, COL_PROTOCOL))
2534 switch(decode_mtp3_standard) {
2536 col_set_str(pinfo->cinfo, COL_PROTOCOL, "SCCP (Int. ITU)");
2539 col_set_str(pinfo->cinfo, COL_PROTOCOL, "SCCP (ANSI)");
2541 case CHINESE_ITU_STANDARD:
2542 col_set_str(pinfo->cinfo, COL_PROTOCOL, "SCCP (Chin. ITU)");
2544 case JAPAN_STANDARD:
2545 col_set_str(pinfo->cinfo, COL_PROTOCOL, "SCCP (Japan)");
2549 /* In the interest of speed, if "tree" is NULL, don't do any work not
2550 necessary to generate protocol tree items. */
2552 /* create the sccp protocol tree */
2553 sccp_item = proto_tree_add_item(tree, proto_sccp, tvb, 0, -1, FALSE);
2554 sccp_tree = proto_item_add_subtree(sccp_item, ett_sccp);
2557 /* Set whether message is UPLINK, DOWNLINK, or of UNKNOWN direction */
2559 if (pinfo->src.type == AT_SS7PC)
2562 * XXX - we assume that the "data" pointers of the source and destination
2563 * addresses are set to point to "mtp3_addr_pc_t" structures, so that
2564 * we can safely cast them.
2566 mtp3_addr_p = (const mtp3_addr_pc_t *)pinfo->src.data;
2568 if (sccp_source_pc_global == mtp3_addr_p->pc)
2570 pinfo->p2p_dir = P2P_DIR_SENT;
2574 /* assuming if src was SS7 PC then dst will be too */
2575 mtp3_addr_p = (const mtp3_addr_pc_t *)pinfo->dst.data;
2577 if (sccp_source_pc_global == mtp3_addr_p->pc)
2579 pinfo->p2p_dir = P2P_DIR_RECV;
2583 pinfo->p2p_dir = P2P_DIR_UNKNOWN;
2588 /* dissect the message */
2589 dissect_sccp_message(tvb, pinfo, sccp_tree, tree);
2593 /*** SccpUsers Table **/
2595 static struct _sccp_ul {
2598 dissector_handle_t* handlep;
2600 {SCCP_USER_DATA,FALSE,&data_handle},
2601 {SCCP_USER_TCAP,FALSE,&tcap_handle},
2602 {SCCP_USER_RANAP,FALSE,&ranap_handle},
2603 {SCCP_USER_BSSAP,FALSE,&bssap_handle},
2604 {SCCP_USER_GSMMAP,TRUE,&gsmmap_handle},
2605 {SCCP_USER_CAMEL,TRUE,&camel_handle},
2606 {SCCP_USER_INAP,TRUE,&inap_handle},
2610 static void sccp_users_update_cb(void* r, const char** err _U_) {
2614 for (c=user_list; c->handlep; c++) {
2615 if (c->id == u->user) {
2616 u->uses_tcap = c->uses_tcap;
2617 u->handlep = c->handlep;
2622 u->uses_tcap = FALSE;
2623 u->handlep = &data_handle;
2626 static void* sccp_users_copy_cb(void* n, const void* o, unsigned siz _U_) {
2627 const sccp_user_t* u = o;
2628 sccp_user_t* un = n;
2632 un->uses_tcap = u->uses_tcap;
2633 un->handlep = u->handlep;
2634 if (u->called_pc) un->called_pc = range_copy(u->called_pc);
2635 if (u->called_ssn) un->called_ssn = range_copy(u->called_ssn);
2640 static void sccp_users_free_cb(void*r) {
2642 if (u->called_pc) g_free(u->called_pc);
2643 if (u->called_ssn) g_free(u->called_ssn);
2647 UAT_DEC_CB_DEF(sccp_users, ni, sccp_user_t)
2648 UAT_RANGE_CB_DEF(sccp_users,called_pc,sccp_user_t)
2649 UAT_RANGE_CB_DEF(sccp_users,called_ssn,sccp_user_t)
2650 UAT_VS_DEF(sccp_users, user, sccp_user_t, SCCP_USER_DATA, "Data")
2652 /** End SccpUsersTable **/
2655 static void init_sccp(void) {
2657 fragment_table_init (&sccp_xudt_msg_fragment_table);
2658 reassembled_table_init(&sccp_xudt_msg_reassembled_table);
2662 /* Register the protocol with Wireshark */
2664 proto_register_sccp(void)
2666 /* Setup list of header fields */
2667 static hf_register_info hf[] = {
2668 { &hf_sccp_message_type,
2669 { "Message Type", "sccp.message_type",
2670 FT_UINT8, BASE_HEX, VALS(sccp_message_type_values), 0x0,
2672 { &hf_sccp_variable_pointer1,
2673 { "Pointer to first Mandatory Variable parameter", "sccp.variable_pointer1",
2674 FT_UINT16, BASE_DEC, NULL, 0x0,
2676 { &hf_sccp_variable_pointer2,
2677 { "Pointer to second Mandatory Variable parameter", "sccp.variable_pointer2",
2678 FT_UINT16, BASE_DEC, NULL, 0x0,
2680 { &hf_sccp_variable_pointer3,
2681 { "Pointer to third Mandatory Variable parameter", "sccp.variable_pointer3",
2682 FT_UINT16, BASE_DEC, NULL, 0x0,
2684 { &hf_sccp_optional_pointer,
2685 { "Pointer to Optional parameter", "sccp.optional_pointer",
2686 FT_UINT16, BASE_DEC, NULL, 0x0,
2689 { "Called or Calling SubSystem Number", "sccp.ssn",
2690 FT_UINT8, BASE_DEC, VALS(sccp_ssn_values), 0x0,
2692 { &hf_sccp_gt_digits,
2693 { "Called or Calling GT Digits",
2695 FT_STRING, BASE_NONE, NULL, 0x0,
2697 { &hf_sccp_called_national_indicator,
2698 { "National Indicator", "sccp.called.ni",
2699 FT_UINT8, BASE_HEX, VALS(sccp_national_indicator_values), ANSI_NATIONAL_MASK,
2701 { &hf_sccp_called_routing_indicator,
2702 { "Routing Indicator", "sccp.called.ri",
2703 FT_UINT8, BASE_HEX, VALS(sccp_routing_indicator_values), ROUTING_INDICATOR_MASK,
2705 { &hf_sccp_called_itu_global_title_indicator,
2706 { "Global Title Indicator", "sccp.called.gti",
2707 FT_UINT8, BASE_HEX, VALS(sccp_itu_global_title_indicator_values), GTI_MASK,
2709 { &hf_sccp_called_ansi_global_title_indicator,
2710 { "Global Title Indicator", "sccp.called.gti",
2711 FT_UINT8, BASE_HEX, VALS(sccp_ansi_global_title_indicator_values), GTI_MASK,
2713 { &hf_sccp_called_itu_ssn_indicator,
2714 { "SubSystem Number Indicator", "sccp.called.ssni",
2715 FT_UINT8, BASE_HEX, VALS(sccp_ai_ssni_values), ITU_SSN_INDICATOR_MASK,
2717 { &hf_sccp_called_itu_point_code_indicator,
2718 { "Point Code Indicator", "sccp.called.pci",
2719 FT_UINT8, BASE_HEX, VALS(sccp_ai_pci_values), ITU_PC_INDICATOR_MASK,
2721 { &hf_sccp_called_ansi_ssn_indicator,
2722 { "SubSystem Number Indicator", "sccp.called.ssni",
2723 FT_UINT8, BASE_HEX, VALS(sccp_ai_ssni_values), ANSI_SSN_INDICATOR_MASK,
2725 { &hf_sccp_called_ansi_point_code_indicator,
2726 { "Point Code Indicator", "sccp.called.pci",
2727 FT_UINT8, BASE_HEX, VALS(sccp_ai_pci_values), ANSI_PC_INDICATOR_MASK,
2729 { &hf_sccp_called_ssn,
2730 { "SubSystem Number", "sccp.called.ssn",
2731 FT_UINT8, BASE_DEC, VALS(sccp_ssn_values), 0x0,
2733 { &hf_sccp_called_itu_pc,
2734 { "PC", "sccp.called.pc",
2735 FT_UINT16, BASE_DEC, NULL, ITU_PC_MASK,
2737 { &hf_sccp_called_ansi_pc,
2738 { "PC", "sccp.called.ansi_pc",
2739 FT_STRING, BASE_NONE, NULL, 0x0,
2741 { &hf_sccp_called_chinese_pc,
2742 { "PC", "sccp.called.chinese_pc",
2743 FT_STRING, BASE_NONE, NULL, 0x0,
2745 { &hf_sccp_called_japan_pc,
2746 { "PC", "sccp.called.pc",
2747 FT_UINT16, BASE_DEC, NULL, 0x0,
2749 { &hf_sccp_called_pc_network,
2751 "sccp.called.network",
2752 FT_UINT24, BASE_DEC, NULL, ANSI_NETWORK_MASK,
2754 { &hf_sccp_called_pc_cluster,
2756 "sccp.called.cluster",
2757 FT_UINT24, BASE_DEC, NULL, ANSI_CLUSTER_MASK,
2759 { &hf_sccp_called_pc_member,
2761 "sccp.called.member",
2762 FT_UINT24, BASE_DEC, NULL, ANSI_MEMBER_MASK,
2764 { &hf_sccp_called_gt_nai,
2765 { "Nature of Address Indicator",
2767 FT_UINT8, BASE_HEX, VALS(sccp_nai_values), GT_NAI_MASK,
2769 { &hf_sccp_called_gt_oe,
2770 { "Odd/Even Indicator",
2772 FT_UINT8, BASE_HEX, VALS(sccp_oe_values), GT_OE_MASK,
2774 { &hf_sccp_called_gt_tt,
2775 { "Translation Type",
2777 FT_UINT8, BASE_HEX, NULL, 0x0,
2779 { &hf_sccp_called_gt_np,
2782 FT_UINT8, BASE_HEX, VALS(sccp_np_values), GT_NP_MASK,
2784 { &hf_sccp_called_gt_es,
2785 { "Encoding Scheme",
2787 FT_UINT8, BASE_HEX, VALS(sccp_es_values), GT_ES_MASK,
2789 { &hf_sccp_called_gt_digits,
2791 "sccp.called.digits",
2792 FT_STRING, BASE_NONE, NULL, 0x0,
2794 { &hf_sccp_calling_national_indicator,
2795 { "National Indicator", "sccp.calling.ni",
2796 FT_UINT8, BASE_HEX, VALS(sccp_national_indicator_values), ANSI_NATIONAL_MASK,
2798 { &hf_sccp_calling_routing_indicator,
2799 { "Routing Indicator", "sccp.calling.ri",
2800 FT_UINT8, BASE_HEX, VALS(sccp_routing_indicator_values), ROUTING_INDICATOR_MASK,
2802 { &hf_sccp_calling_itu_global_title_indicator,
2803 { "Global Title Indicator", "sccp.calling.gti",
2804 FT_UINT8, BASE_HEX, VALS(sccp_itu_global_title_indicator_values), GTI_MASK,
2806 { &hf_sccp_calling_ansi_global_title_indicator,
2807 { "Global Title Indicator", "sccp.calling.gti",
2808 FT_UINT8, BASE_HEX, VALS(sccp_ansi_global_title_indicator_values), GTI_MASK,
2810 { &hf_sccp_calling_itu_ssn_indicator,
2811 { "SubSystem Number Indicator", "sccp.calling.ssni",
2812 FT_UINT8, BASE_HEX, VALS(sccp_ai_ssni_values), ITU_SSN_INDICATOR_MASK,
2814 { &hf_sccp_calling_itu_point_code_indicator,
2815 { "Point Code Indicator", "sccp.calling.pci",
2816 FT_UINT8, BASE_HEX, VALS(sccp_ai_pci_values), ITU_PC_INDICATOR_MASK,
2818 { &hf_sccp_calling_ansi_ssn_indicator,
2819 { "SubSystem Number Indicator", "sccp.calling.ssni",
2820 FT_UINT8, BASE_HEX, VALS(sccp_ai_ssni_values), ANSI_SSN_INDICATOR_MASK,
2822 { &hf_sccp_calling_ansi_point_code_indicator,
2823 { "Point Code Indicator", "sccp.calling.pci",
2824 FT_UINT8, BASE_HEX, VALS(sccp_ai_pci_values), ANSI_PC_INDICATOR_MASK,
2826 { &hf_sccp_calling_ssn,
2827 { "SubSystem Number", "sccp.calling.ssn",
2828 FT_UINT8, BASE_DEC, VALS(sccp_ssn_values), 0x0,
2830 { &hf_sccp_calling_itu_pc,
2831 { "PC", "sccp.calling.pc",
2832 FT_UINT16, BASE_DEC, NULL, ITU_PC_MASK,
2834 { &hf_sccp_calling_ansi_pc,
2835 { "PC", "sccp.calling.ansi_pc",
2836 FT_STRING, BASE_NONE, NULL, 0x0,
2838 { &hf_sccp_calling_chinese_pc,
2839 { "PC", "sccp.calling.chinese_pc",
2840 FT_STRING, BASE_NONE, NULL, 0x0,
2842 { &hf_sccp_calling_japan_pc,
2843 { "PC", "sccp.calling.pc",
2844 FT_UINT16, BASE_DEC, NULL, 0x0,
2846 { &hf_sccp_calling_pc_network,
2848 "sccp.calling.network",
2849 FT_UINT24, BASE_DEC, NULL, ANSI_NETWORK_MASK,
2851 { &hf_sccp_calling_pc_cluster,
2853 "sccp.calling.cluster",
2854 FT_UINT24, BASE_DEC, NULL, ANSI_CLUSTER_MASK,
2856 { &hf_sccp_calling_pc_member,
2858 "sccp.calling.member",
2859 FT_UINT24, BASE_DEC, NULL, ANSI_MEMBER_MASK,
2861 { &hf_sccp_calling_gt_nai,
2862 { "Nature of Address Indicator",
2864 FT_UINT8, BASE_HEX, VALS(sccp_nai_values), GT_NAI_MASK,
2866 { &hf_sccp_calling_gt_oe,
2867 { "Odd/Even Indicator",
2869 FT_UINT8, BASE_HEX, VALS(sccp_oe_values), GT_OE_MASK,
2871 { &hf_sccp_calling_gt_tt,
2872 { "Translation Type",
2874 FT_UINT8, BASE_HEX, NULL, 0x0,
2876 { &hf_sccp_calling_gt_np,
2879 FT_UINT8, BASE_HEX, VALS(sccp_np_values), GT_NP_MASK,
2881 { &hf_sccp_calling_gt_es,
2882 { "Encoding Scheme",
2884 FT_UINT8, BASE_HEX, VALS(sccp_es_values), GT_ES_MASK,
2886 { &hf_sccp_calling_gt_digits,
2888 "sccp.calling.digits",
2889 FT_STRING, BASE_NONE, NULL, 0x0,
2892 { "Destination Local Reference", "sccp.dlr",
2893 FT_UINT24, BASE_HEX, NULL, 0x0,
2896 { "Source Local Reference", "sccp.slr",
2897 FT_UINT24, BASE_HEX, NULL, 0x0,
2900 { "Local Reference", "sccp.lr",
2901 FT_UINT24, BASE_HEX, NULL, 0x0,
2904 { "Class", "sccp.class",
2905 FT_UINT8, BASE_HEX, NULL, CLASS_CLASS_MASK,
2907 { &hf_sccp_handling,
2908 { "Message handling", "sccp.handling",
2909 FT_UINT8, BASE_HEX, VALS(sccp_class_handling_values), CLASS_SPARE_HANDLING_MASK,
2912 { "More data", "sccp.more",
2913 FT_UINT8, BASE_HEX, VALS(sccp_segmenting_reassembling_values), SEGMENTING_REASSEMBLING_MASK,
2916 { "Receive Sequence Number", "sccp.rsn",
2917 FT_UINT8, BASE_HEX, NULL, RSN_MASK,
2919 { &hf_sccp_sequencing_segmenting_ssn,
2920 { "Sequencing Segmenting: Send Sequence Number", "sccp.sequencing_segmenting.ssn",
2921 FT_UINT8, BASE_HEX, NULL, SEND_SEQUENCE_NUMBER_MASK,
2923 { &hf_sccp_sequencing_segmenting_rsn,
2924 { "Sequencing Segmenting: Receive Sequence Number", "sccp.sequencing_segmenting.rsn",
2925 FT_UINT8, BASE_HEX, NULL, RECEIVE_SEQUENCE_NUMBER_MASK,
2927 { &hf_sccp_sequencing_segmenting_more,
2928 { "Sequencing Segmenting: More", "sccp.sequencing_segmenting.more",
2929 FT_UINT8, BASE_HEX, VALS(sccp_segmenting_reassembling_values), SEQUENCING_SEGMENTING_MORE_MASK,
2932 { "Credit", "sccp.credit",
2933 FT_UINT8, BASE_HEX, NULL, 0x0,
2935 { &hf_sccp_release_cause,
2936 { "Release Cause", "sccp.release_cause",
2937 FT_UINT8, BASE_HEX, VALS(sccp_release_cause_values), 0x0,
2939 { &hf_sccp_return_cause,
2940 { "Return Cause", "sccp.return_cause",
2941 FT_UINT8, BASE_HEX, VALS(sccp_return_cause_values), 0x0,
2943 { &hf_sccp_reset_cause,
2944 { "Reset Cause", "sccp.reset_cause",
2945 FT_UINT8, BASE_HEX, VALS(sccp_reset_cause_values), 0x0,
2947 { &hf_sccp_error_cause,
2948 { "Error Cause", "sccp.error_cause",
2949 FT_UINT8, BASE_HEX, VALS(sccp_error_cause_values), 0x0,
2951 { &hf_sccp_refusal_cause,
2952 { "Refusal Cause", "sccp.refusal_cause",
2953 FT_UINT8, BASE_HEX, VALS(sccp_refusal_cause_values), 0x0,
2955 { &hf_sccp_segmentation_first,
2956 { "Segmentation: First", "sccp.segmentation.first",
2957 FT_UINT8, BASE_HEX, VALS(sccp_segmentation_first_segment_values), SEGMENTATION_FIRST_SEGMENT_MASK,
2959 { &hf_sccp_segmentation_class,
2960 { "Segmentation: Class", "sccp.segmentation.class",
2961 FT_UINT8, BASE_HEX, VALS(sccp_segmentation_class_values), SEGMENTATION_CLASS_MASK,
2963 { &hf_sccp_segmentation_remaining,
2964 { "Segmentation: Remaining", "sccp.segmentation.remaining",
2965 FT_UINT8, BASE_HEX, NULL, SEGMENTATION_REMAINING_MASK,
2967 { &hf_sccp_segmentation_slr,
2968 { "Segmentation: Source Local Reference", "sccp.segmentation.slr",
2969 FT_UINT24, BASE_HEX, NULL, 0x0,
2971 { &hf_sccp_hop_counter,
2972 { "Hop Counter", "sccp.hops",
2973 FT_UINT8, BASE_HEX, NULL, 0x0,
2975 { &hf_sccp_importance,
2976 { "Importance", "sccp.importance",
2977 FT_UINT8, BASE_HEX, NULL, IMPORTANCE_IMPORTANCE_MASK,
2979 /* ISNI is ANSI only */
2980 { &hf_sccp_ansi_isni_mi,
2981 { "ISNI Mark for Identification Indicator", "sccp.isni.mi",
2982 FT_UINT8, BASE_HEX, VALS(sccp_isni_mark_for_id_values), ANSI_ISNI_MI_MASK,
2984 { &hf_sccp_ansi_isni_iri,
2985 { "ISNI Routing Indicator", "sccp.isni.iri",
2986 FT_UINT8, BASE_HEX, VALS(sccp_isni_iri_values), ANSI_ISNI_IRI_MASK,
2988 { &hf_sccp_ansi_isni_ti,
2989 { "ISNI Type Indicator", "sccp.isni.ti",
2990 FT_UINT8, BASE_HEX, VALS(sccp_isni_ti_values), ANSI_ISNI_TI_MASK,
2992 { &hf_sccp_ansi_isni_netspec,
2993 { "ISNI Network Specific (Type 1)", "sccp.isni.netspec",
2994 FT_UINT8, BASE_HEX, NULL, ANSI_ISNI_NETSPEC_MASK,
2996 { &hf_sccp_ansi_isni_counter,
2997 { "ISNI Counter", "sccp.isni.counter",
2998 FT_UINT8, BASE_HEX, NULL, ANSI_ISNI_COUNTER_MASK,
3000 {&hf_sccp_xudt_msg_fragments,
3001 {"Message fragments", "sccp.msg.fragments",
3002 FT_NONE, BASE_NONE, NULL, 0x00, NULL, HFILL }
3004 {&hf_sccp_xudt_msg_fragment,
3005 {"Message fragment", "sccp.msg.fragment",
3006 FT_FRAMENUM, BASE_NONE, NULL, 0x00, NULL, HFILL }
3008 {&hf_sccp_xudt_msg_fragment_overlap,
3009 {"Message fragment overlap", "sccp.msg.fragment.overlap",
3010 FT_BOOLEAN, BASE_NONE, NULL, 0x00, NULL, HFILL }
3012 {&hf_sccp_xudt_msg_fragment_overlap_conflicts,
3013 {"Message fragment overlapping with conflicting data", "sccp.msg.fragment.overlap.conflicts",
3014 FT_BOOLEAN, BASE_NONE, NULL, 0x00, NULL, HFILL }
3016 {&hf_sccp_xudt_msg_fragment_multiple_tails,
3017 {"Message has multiple tail fragments", "sccp.msg.fragment.multiple_tails",
3018 FT_BOOLEAN, BASE_NONE, NULL, 0x00, NULL, HFILL }
3020 {&hf_sccp_xudt_msg_fragment_too_long_fragment,
3021 {"Message fragment too long", "sccp.msg.fragment.too_long_fragment",
3022 FT_BOOLEAN, BASE_NONE, NULL, 0x00, NULL, HFILL }
3024 {&hf_sccp_xudt_msg_fragment_error,
3025 {"Message defragmentation error", "sccp.msg.fragment.error",
3026 FT_FRAMENUM, BASE_NONE, NULL, 0x00, NULL, HFILL }
3028 {&hf_sccp_xudt_msg_reassembled_in,
3029 {"Reassembled in", "sccp.msg.reassembled.in",
3030 FT_FRAMENUM, BASE_NONE, NULL, 0x00, NULL, HFILL }
3032 { &hf_sccp_assoc_id,
3033 { "Association ID", "sccp.assoc.id",
3034 FT_UINT32, BASE_DEC, NULL, 0x0, "", HFILL}},
3035 {&hf_sccp_assoc_msg,
3036 {"Message in frame", "sccp.assoc.msg",
3037 FT_FRAMENUM, BASE_NONE, NULL, 0x00, "", HFILL }
3042 /* Setup protocol subtree array */
3043 static gint *ett[] = {
3046 &ett_sccp_called_ai,
3047 &ett_sccp_called_pc,
3048 &ett_sccp_called_gt,
3050 &ett_sccp_calling_ai,
3051 &ett_sccp_calling_pc,
3052 &ett_sccp_calling_gt,
3053 &ett_sccp_sequencing_segmenting,
3054 &ett_sccp_segmentation,
3055 &ett_sccp_ansi_isni_routing_control,
3056 &ett_sccp_xudt_msg_fragment,
3057 &ett_sccp_xudt_msg_fragments,
3062 static uat_field_t users_flds[] = {
3063 UAT_FLD_DEC(sccp_users,ni,"Network Indicator"),
3064 UAT_FLD_RANGE(sccp_users,called_pc,65535,"DPCs for which this protocol is to be used"),
3065 UAT_FLD_RANGE(sccp_users,called_ssn,65535,"Called SSNs for which this protocol is to be used"),
3066 UAT_FLD_VS(sccp_users,user,sccp_users_vals,"The User Protocol"),
3071 uat_t* users_uat = uat_new("SCCP Users Table",
3072 sizeof(sccp_user_t),
3074 (void**) &sccp_users,
3079 sccp_users_update_cb,
3083 /* Register the protocol name and description */
3084 proto_sccp = proto_register_protocol("Signalling Connection Control Part",
3087 register_dissector("sccp", dissect_sccp, proto_sccp);
3089 /* Required function calls to register the header fields and subtrees used */
3090 proto_register_field_array(proto_sccp, hf, array_length(hf));
3091 proto_register_subtree_array(ett, array_length(ett));
3094 sccp_ssn_dissector_table = register_dissector_table("sccp.ssn", "SCCP SSN", FT_UINT8, BASE_DEC);
3096 register_heur_dissector_list("sccp", &heur_subdissector_list);
3098 sccp_module = prefs_register_protocol(proto_sccp, NULL);
3100 prefs_register_uint_preference(sccp_module, "source_pc",
3102 "The source point code (usually MSC) (to determine whether message is uplink or downlink)",
3103 16, &sccp_source_pc_global);
3105 prefs_register_bool_preference(sccp_module, "show_length", "Show length",
3106 "Show parameter length in the protocol tree",
3109 prefs_register_bool_preference(sccp_module, "defragment_xudt",
3110 "Reassemble XUDT messages",
3111 "Whether XUDT messages should be reassembled",
3112 &sccp_xudt_desegment);
3114 prefs_register_bool_preference(sccp_module, "trace_sccp",
3115 "Trace Associations",
3116 "Whether to keep infomation about messages and their associations",
3120 prefs_register_bool_preference(sccp_module, "show_more_info",
3121 "Show key parameters in Info Column",
3122 "Show SLR, DLR, and CAUSE Parameters in the Information Column of the Summary",
3126 prefs_register_uat_preference(sccp_module, "users_table", "Users Table",
3127 "A table that enumerates user protocols to be used against specific PCs and SSNs",
3130 register_init_routine(&init_sccp);
3132 assocs = se_tree_create(EMEM_TREE_TYPE_RED_BLACK, "sccp_associations");
3134 sccp_tap = register_tap("sccp");
3139 proto_reg_handoff_sccp(void)
3141 dissector_handle_t sccp_handle;
3143 sccp_handle = find_dissector("sccp");
3145 dissector_add("mtp3.service_indicator", SCCP_SI, sccp_handle);
3146 dissector_add_string("tali.opcode", "sccp", sccp_handle);
3148 data_handle = find_dissector("data");
3149 tcap_handle = find_dissector("tcap");
3150 ranap_handle = find_dissector("ranap");
3151 bssap_handle = find_dissector("bssap");
3152 gsmmap_handle = find_dissector("gsm_map");
3153 camel_handle = find_dissector("camel");
3154 inap_handle = find_dissector("inap");