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 "packet-tcap.h"
54 #include "packet-sccp.h"
57 static Standard_Type decode_mtp3_standard;
60 #define SCCP_MSG_TYPE_OFFSET 0
61 #define SCCP_MSG_TYPE_LENGTH 1
62 #define POINTER_LENGTH 1
63 #define POINTER_LENGTH_LONG 2
65 /* Same as below but with names typed out */
66 static const value_string sccp_message_type_values[] = {
67 { SCCP_MSG_TYPE_CR, "Connection Request" },
68 { SCCP_MSG_TYPE_CC, "Connection Confirm" },
69 { SCCP_MSG_TYPE_CREF, "Connection Refused" },
70 { SCCP_MSG_TYPE_RLSD, "Released" },
71 { SCCP_MSG_TYPE_RLC, "Release Complete" },
72 { SCCP_MSG_TYPE_DT1, "Data Form 1" },
73 { SCCP_MSG_TYPE_DT2, "Data Form 2" },
74 { SCCP_MSG_TYPE_AK, "Data Acknowledgement" },
75 { SCCP_MSG_TYPE_UDT, "Unitdata" },
76 { SCCP_MSG_TYPE_UDTS, "Unitdata Service" },
77 { SCCP_MSG_TYPE_ED, "Expedited Data" },
78 { SCCP_MSG_TYPE_EA, "Expedited Data Acknowledgement" },
79 { SCCP_MSG_TYPE_RSR, "Reset Request" },
80 { SCCP_MSG_TYPE_RSC, "Reset Confirmation" },
81 { SCCP_MSG_TYPE_ERR, "Error" },
82 { SCCP_MSG_TYPE_IT, "Inactivity Timer" },
83 { SCCP_MSG_TYPE_XUDT, "Extended Unitdata" },
84 { SCCP_MSG_TYPE_XUDTS, "Extended Unitdata Service" },
85 { SCCP_MSG_TYPE_LUDT, "Long Unitdata (ITU)" },
86 { SCCP_MSG_TYPE_LUDTS, "Long Unitdata Service (ITU)" },
89 /* Same as above but in acronym form (for the Info column) */
90 const value_string sccp_message_type_acro_values[] = {
91 { SCCP_MSG_TYPE_CR, "CR" },
92 { SCCP_MSG_TYPE_CC, "CC" },
93 { SCCP_MSG_TYPE_CREF, "CREF" },
94 { SCCP_MSG_TYPE_RLSD, "RLSD" },
95 { SCCP_MSG_TYPE_RLC, "RLC" },
96 { SCCP_MSG_TYPE_DT1, "DT1" },
97 { SCCP_MSG_TYPE_DT2, "DT2" },
98 { SCCP_MSG_TYPE_AK, "AK" },
99 { SCCP_MSG_TYPE_UDT, "UDT" },
100 { SCCP_MSG_TYPE_UDTS, "UDTS" },
101 { SCCP_MSG_TYPE_ED, "ED" },
102 { SCCP_MSG_TYPE_EA, "EA" },
103 { SCCP_MSG_TYPE_RSR, "RSR" },
104 { SCCP_MSG_TYPE_RSC, "RSC" },
105 { SCCP_MSG_TYPE_ERR, "ERR" },
106 { SCCP_MSG_TYPE_IT, "IT" },
107 { SCCP_MSG_TYPE_XUDT, "XUDT" },
108 { SCCP_MSG_TYPE_XUDTS, "XUDTS" },
109 { SCCP_MSG_TYPE_LUDT, "LUDT" },
110 { SCCP_MSG_TYPE_LUDTS, "LUDTS" },
113 #define PARAMETER_LENGTH_LENGTH 1
114 #define PARAMETER_LONG_DATA_LENGTH_LENGTH 2
115 #define PARAMETER_TYPE_LENGTH 1
117 #define PARAMETER_END_OF_OPTIONAL_PARAMETERS 0x00
118 #define PARAMETER_DESTINATION_LOCAL_REFERENCE 0x01
119 #define PARAMETER_SOURCE_LOCAL_REFERENCE 0x02
120 #define PARAMETER_CALLED_PARTY_ADDRESS 0x03
121 #define PARAMETER_CALLING_PARTY_ADDRESS 0x04
122 #define PARAMETER_CLASS 0x05
123 #define PARAMETER_SEGMENTING_REASSEMBLING 0x06
124 #define PARAMETER_RECEIVE_SEQUENCE_NUMBER 0x07
125 #define PARAMETER_SEQUENCING_SEGMENTING 0x08
126 #define PARAMETER_CREDIT 0x09
127 #define PARAMETER_RELEASE_CAUSE 0x0a
128 #define PARAMETER_RETURN_CAUSE 0x0b
129 #define PARAMETER_RESET_CAUSE 0x0c
130 #define PARAMETER_ERROR_CAUSE 0x0d
131 #define PARAMETER_REFUSAL_CAUSE 0x0e
132 #define PARAMETER_DATA 0x0f
133 #define PARAMETER_SEGMENTATION 0x10
134 #define PARAMETER_HOP_COUNTER 0x11
135 /* The below 2 are ITU only */
136 #define PARAMETER_IMPORTANCE 0x12
137 #define PARAMETER_LONG_DATA 0x13
138 /* ISNI is ANSI only */
139 #define PARAMETER_ISNI 0xfa
141 static const value_string sccp_parameter_values[] = {
142 { PARAMETER_END_OF_OPTIONAL_PARAMETERS, "End of Optional Parameters" },
143 { PARAMETER_DESTINATION_LOCAL_REFERENCE, "Destination Local Reference" },
144 { PARAMETER_SOURCE_LOCAL_REFERENCE, "Source Local Reference" },
145 { PARAMETER_CALLED_PARTY_ADDRESS, "Called Party Address" },
146 { PARAMETER_CALLING_PARTY_ADDRESS, "Calling Party Address" },
147 { PARAMETER_CLASS, "Protocol Class" },
148 { PARAMETER_SEGMENTING_REASSEMBLING, "Segmenting/Reassembling" },
149 { PARAMETER_RECEIVE_SEQUENCE_NUMBER, "Receive Sequence Number" },
150 { PARAMETER_SEQUENCING_SEGMENTING, "Sequencing/Segmenting" },
151 { PARAMETER_CREDIT, "Credit" },
152 { PARAMETER_RELEASE_CAUSE, "Release Cause" },
153 { PARAMETER_RETURN_CAUSE, "Return Cause" },
154 { PARAMETER_RESET_CAUSE, "Reset Cause" },
155 { PARAMETER_ERROR_CAUSE, "Error Cause" },
156 { PARAMETER_REFUSAL_CAUSE, "Refusal Cause" },
157 { PARAMETER_DATA, "Data" },
158 { PARAMETER_SEGMENTATION, "Segmentation" },
159 { PARAMETER_HOP_COUNTER, "Hop Counter" },
160 { PARAMETER_IMPORTANCE, "Importance (ITU)" },
161 { PARAMETER_LONG_DATA, "Long Data (ITU)" },
162 { PARAMETER_ISNI, "Intermediate Signaling Network Identification (ANSI)" },
166 #define END_OF_OPTIONAL_PARAMETERS_LENGTH 1
167 #define DESTINATION_LOCAL_REFERENCE_LENGTH 3
168 #define SOURCE_LOCAL_REFERENCE_LENGTH 3
169 #define PROTOCOL_CLASS_LENGTH 1
170 #define RECEIVE_SEQUENCE_NUMBER_LENGTH 1
171 #define CREDIT_LENGTH 1
172 #define RELEASE_CAUSE_LENGTH 1
173 #define RETURN_CAUSE_LENGTH 1
174 #define RESET_CAUSE_LENGTH 1
175 #define ERROR_CAUSE_LENGTH 1
176 #define REFUSAL_CAUSE_LENGTH 1
177 #define HOP_COUNTER_LENGTH 1
178 #define IMPORTANCE_LENGTH 1
181 /* Parts of the Called and Calling Address parameters */
182 /* Address Indicator */
183 #define ADDRESS_INDICATOR_LENGTH 1
184 #define ITU_RESERVED_MASK 0x80
185 #define ANSI_NATIONAL_MASK 0x80
186 #define ROUTING_INDICATOR_MASK 0x40
187 #define GTI_MASK 0x3C
189 #define ITU_SSN_INDICATOR_MASK 0x02
190 #define ITU_PC_INDICATOR_MASK 0x01
191 #define ANSI_PC_INDICATOR_MASK 0x02
192 #define ANSI_SSN_INDICATOR_MASK 0x01
194 static const value_string sccp_national_indicator_values[] = {
195 { 0x0, "Address coded to International standard" },
196 { 0x1, "Address coded to National standard" },
199 static const value_string sccp_routing_indicator_values[] = {
200 { 0x0, "Route on GT" },
201 { 0x1, "Route on SSN" },
204 #define AI_GTI_NO_GT 0x0
205 #define ITU_AI_GTI_NAI 0x1
206 #define AI_GTI_TT 0x2
207 #define ITU_AI_GTI_TT_NP_ES 0x3
208 #define ITU_AI_GTI_TT_NP_ES_NAI 0x4
209 static const value_string sccp_itu_global_title_indicator_values[] = {
210 { AI_GTI_NO_GT, "No Global Title" },
211 { ITU_AI_GTI_NAI, "Nature of Address Indicator only" },
212 { AI_GTI_TT, "Translation Type only" },
213 { ITU_AI_GTI_TT_NP_ES, "Translation Type, Numbering Plan, and Encoding Scheme included" },
214 { ITU_AI_GTI_TT_NP_ES_NAI, "Translation Type, Numbering Plan, Encoding Scheme, and Nature of Address Indicator included" },
217 /* #define AI_GTI_NO_GT 0x0 */
218 #define ANSI_AI_GTI_TT_NP_ES 0x1
219 /* #define AI_GTI_TT 0x2 */
220 static const value_string sccp_ansi_global_title_indicator_values[] = {
221 { AI_GTI_NO_GT, "No Global Title" },
222 { ANSI_AI_GTI_TT_NP_ES, "Translation Type, Numbering Plan, and Encoding Scheme included" },
223 { AI_GTI_TT, "Translation Type only" },
226 static const value_string sccp_ai_pci_values[] = {
227 { 0x1, "Point Code present" },
228 { 0x0, "Point Code not present" },
231 static const value_string sccp_ai_ssni_values[] = {
232 { 0x1, "SSN present" },
233 { 0x0, "SSN not present" },
236 #define ADDRESS_SSN_LENGTH 1
237 #define INVALID_SSN 0xff
238 /* Some values from 3GPP TS 23.003 */
239 /* Japan TTC and NTT define a lot of SSNs, some of which conflict with
240 * these. They are not added for now.
242 static const value_string sccp_ssn_values[] = {
243 { 0x00, "SSN not known/not used" },
244 { 0x01, "SCCP management" },
245 { 0x02, "Reserved for ITU-T allocation" },
246 { 0x03, "ISDN User Part" },
247 { 0x04, "OMAP (Operation, Maintenance, and Administration Part)" },
248 { 0x05, "MAP (Mobile Application Part)" },
249 { 0x06, "HLR (Home Location Register)" },
250 { 0x07, "VLR (Visitor Location Register)" },
251 { 0x08, "MSC (Mobile Switching Center)" },
252 { 0x09, "EIC/EIR (Equipment Identifier Center/Equipment Identification Register)" },
253 { 0x0a, "AUC/AC (Authentication Center)" },
254 { 0x0b, "ISDN supplementary services (ITU only)" },
255 { 0x0c, "Reserved for international use (ITU only)" },
256 { 0x0d, "Broadband ISDN edge-to-edge applications (ITU only)" },
257 { 0x0e, "TC test responder (ITU only)" },
258 /* The following national network subsystem numbers have been allocated for use within and
259 * between GSM/UMTS networks:
263 { 0x91, "GMLC(MAP)" },
265 { 0x93, "gsmSCF (MAP) or IM-SSF (MAP) or Presence Network Agent" },
266 { 0x94, "SIWF (MAP)" },
267 { 0x95, "SGSN (MAP)" },
268 { 0x96, "GGSN (MAP)" },
269 /* The following national network subsystem numbers have been allocated for use within GSM/UMTS networks:*/
271 { 0xfa, "BSC (BSSAP-LE)" },
272 { 0xfb, "MSC (BSSAP-LE)" },
273 { 0xfc, "IOS or SMLC (BSSAP-LE)" },
274 { 0xfd, "BSS O&M (A interface)" },
275 { 0xfe, "BSSAP/BSAP" },
279 /* * * * * * * * * * * * * * * * *
280 * Global Title: ITU GTI == 0001 *
281 * * * * * * * * * * * * * * * * */
282 #define GT_NAI_MASK 0x7F
283 #define GT_NAI_LENGTH 1
284 static const value_string sccp_nai_values[] = {
285 { 0x00, "NAI unknown" },
286 { 0x01, "Subscriber Number" },
287 { 0x02, "Reserved for national use" },
288 { 0x03, "National significant number" },
289 { 0x04, "International number" },
293 #define GT_OE_MASK 0x80
296 static const value_string sccp_oe_values[] = {
297 { GT_OE_EVEN, "Even number of address signals" },
298 { GT_OE_ODD, "Odd number of address signals" },
301 #define GT_SIGNAL_LENGTH 1
302 #define GT_ODD_SIGNAL_MASK 0x0f
303 #define GT_EVEN_SIGNAL_MASK 0xf0
304 #define GT_EVEN_SIGNAL_SHIFT 4
305 #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 */
306 static const value_string sccp_address_signal_values[] = {
326 /* * * * * * * * * * * * * * * * * * * * *
327 * Global Title: ITU and ANSI GTI == 0010 *
328 * * * * * * * * * * * * * * * * * * * * */
329 #define GT_TT_LENGTH 1
332 /* * * * * * * * * * * * * * * * * * * * * * * * * *
333 * Global Title: ITU GTI == 0011, ANSI GTI == 0001 *
334 * * * * * * * * * * * * * * * * * * * * * * * * * */
335 #define GT_NP_MASK 0xf0
336 #define GT_NP_ES_LENGTH 1
337 static const value_string sccp_np_values[] = {
339 { 0x1, "ISDN/telephony" },
340 { 0x2, "Generic (ITU)/Reserved (ANSI)" },
343 { 0x5, "Maritime mobile" },
344 { 0x6, "Land mobile" },
345 { 0x7, "ISDN/mobile" },
346 { 0xe, "Private network or network-specific" },
350 #define GT_ES_MASK 0x0f
351 #define GT_ES_UNKNOWN 0x0
352 #define GT_ES_BCD_ODD 0x1
353 #define GT_ES_BCD_EVEN 0x2
354 #define GT_ES_NATIONAL 0x3
355 #define GT_ES_RESERVED 0xf
356 static const value_string sccp_es_values[] = {
357 { GT_ES_UNKNOWN, "Unknown" },
358 { GT_ES_BCD_ODD, "BCD, odd number of digits" },
359 { GT_ES_BCD_EVEN, "BCD, even number of digits" },
360 { GT_ES_NATIONAL, "National specific" },
361 { GT_ES_RESERVED, "Reserved (ITU)/Spare (ANSI)" },
364 /* Address signals above */
367 /* * * * * * * * * * * * * * * * *
368 * Global Title: ITU GTI == 0100 *
369 * * * * * * * * * * * * * * * * */
373 /* Address signals above */
376 #define CLASS_CLASS_MASK 0xf
377 #define CLASS_SPARE_HANDLING_MASK 0xf0
378 static const value_string sccp_class_handling_values [] = {
379 { 0x0, "No special options" },
380 { 0x8, "Return message on error" },
384 #define SEGMENTING_REASSEMBLING_LENGTH 1
385 #define SEGMENTING_REASSEMBLING_MASK 0x01
386 #define NO_MORE_DATA 0
388 /* This is also used by sequencing-segmenting parameter */
389 static const value_string sccp_segmenting_reassembling_values [] = {
390 { NO_MORE_DATA, "No more data" },
391 { MORE_DATA, "More data" },
395 #define RECEIVE_SEQUENCE_NUMBER_LENGTH 1
396 #define RSN_MASK 0xfe
398 #define SEQUENCING_SEGMENTING_LENGTH 2
399 #define SEQUENCING_SEGMENTING_SSN_LENGTH 1
400 #define SEQUENCING_SEGMENTING_RSN_LENGTH 1
401 #define SEND_SEQUENCE_NUMBER_MASK 0xfe
402 #define RECEIVE_SEQUENCE_NUMBER_MASK 0xfe
403 #define SEQUENCING_SEGMENTING_MORE_MASK 0x01
406 #define CREDIT_LENGTH 1
408 #define RELEASE_CAUSE_LENGTH 1
409 static const value_string sccp_release_cause_values [] = {
410 { 0x00, "End user originated" },
411 { 0x01, "End user congestion" },
412 { 0x02, "End user failure" },
413 { 0x03, "SCCP user originated" },
414 { 0x04, "Remote procedure error" },
415 { 0x05, "Inconsistent connection data" },
416 { 0x06, "Access failure" },
417 { 0x07, "Access congestion" },
418 { 0x08, "Subsystem failure" },
419 { 0x09, "Subsystem congestion" },
420 { 0x0a, "MTP failure" },
421 { 0x0b, "Netowrk congestion" },
422 { 0x0c, "Expiration of reset timer" },
423 { 0x0d, "Expiration of receive inactivity timer" },
424 { 0x0e, "Reserved" },
425 { 0x0f, "Unqualified" },
426 { 0x10, "SCCP failure (ITU only)" },
430 #define RETURN_CAUSE_LENGTH 1
431 static const value_string sccp_return_cause_values [] = {
432 { 0x00, "No translation for an address of such nature" },
433 { 0x01, "No translation for this specific address" },
434 { 0x02, "Subsystem congestion" },
435 { 0x03, "Subsystem failure" },
436 { 0x04, "Unequipped failure" },
437 { 0x05, "MTP failure" },
438 { 0x06, "Network congestion" },
439 { 0x07, "Unqualified" },
440 { 0x08, "Error in message transport" },
441 { 0x09, "Error in local processing" },
442 { 0x0a, "Destination cannot perform reassembly" },
443 { 0x0b, "SCCP failure" },
444 { 0x0c, "Hop counter violation" },
445 { 0x0d, "Segmentation not supported (ITU only)" },
446 { 0x0e, "Segmentation failure (ITU only)" },
447 { 0xf9, "Invalid ISNI routing request (ANSI only)"},
448 { 0xfa, "Unauthorized message (ANSI only)" },
449 { 0xfb, "Message incompatibility (ANSI only)" },
450 { 0xfc, "Cannot perform ISNI constrained routing (ANSI only)" },
451 { 0xfd, "Unable to perform ISNI identification (ANSI only)" },
455 #define RESET_CAUSE_LENGTH 1
456 static const value_string sccp_reset_cause_values [] = {
457 { 0x00, "End user originated" },
458 { 0x01, "SCCP user originated" },
459 { 0x02, "Message out of order - incorrect send sequence number" },
460 { 0x03, "Message out of order - incorrect receive sequence number" },
461 { 0x04, "Remote procedure error - message out of window" },
462 { 0x05, "Remote procedure error - incorrect send sequence number after (re)initialization" },
463 { 0x06, "Remote procedure error - general" },
464 { 0x07, "Remote end user operational" },
465 { 0x08, "Network operational" },
466 { 0x09, "Access operational" },
467 { 0x0a, "Network congestion" },
468 { 0x0b, "Reserved (ITU)/Not obtainable (ANSI)" },
469 { 0x0c, "Unqualified" },
473 #define ERROR_CAUSE_LENGTH 1
474 static const value_string sccp_error_cause_values [] = {
475 { 0x00, "Local Reference Number (LRN) mismatch - unassigned destination LRN" },
476 { 0x01, "Local Reference Number (LRN) mismatch - inconsistent source LRN" },
477 { 0x02, "Point code mismatch" },
478 { 0x03, "Service class mismatch" },
479 { 0x04, "Unqualified" },
483 #define REFUSAL_CAUSE_LENGTH 1
484 static const value_string sccp_refusal_cause_values [] = {
485 { 0x00, "End user originated" },
486 { 0x01, "End user congestion" },
487 { 0x02, "End user failure" },
488 { 0x03, "SCCP user originated" },
489 { 0x04, "Destination address unknown" },
490 { 0x05, "Destination inaccessible" },
491 { 0x06, "Network resource - QOS not available/non-transient" },
492 { 0x07, "Network resource - QOS not available/transient" },
493 { 0x08, "Access failure" },
494 { 0x09, "Access congestion" },
495 { 0x0a, "Subsystem failure" },
496 { 0x0b, "Subsystem congestion" },
497 { 0x0c, "Expiration of connection establishment timer" },
498 { 0x0d, "Incompatible user data" },
499 { 0x0e, "Reserved" },
500 { 0x0f, "Unqualified" },
501 { 0x10, "Hop counter violation" },
502 { 0x11, "SCCP failure (ITU only)" },
503 { 0x12, "No translation for an address of such nature" },
504 { 0x13, "Unequipped user" },
508 #define SEGMENTATION_LENGTH 4
509 #define SEGMENTATION_FIRST_SEGMENT_MASK 0x80
510 #define SEGMENTATION_CLASS_MASK 0x40
511 #define SEGMENTATION_SPARE_MASK 0x30
512 #define SEGMENTATION_REMAINING_MASK 0x0f
513 static const value_string sccp_segmentation_first_segment_values [] = {
514 { 1, "First segment" },
515 { 0, "Not first segment" },
517 static const value_string sccp_segmentation_class_values [] = {
518 { 0, "Class 0 selected" },
519 { 1, "Class 1 selected" },
523 #define HOP_COUNTER_LENGTH 1
525 #define IMPORTANCE_LENGTH 1
526 #define IMPORTANCE_IMPORTANCE_MASK 0x7
529 #define ANSI_ISNI_ROUTING_CONTROL_LENGTH 1
530 #define ANSI_ISNI_MI_MASK 0x01
531 #define ANSI_ISNI_IRI_MASK 0x06
532 #define ANSI_ISNI_RES_MASK 0x08
533 #define ANSI_ISNI_TI_MASK 0x10
534 #define ANSI_ISNI_TI_SHIFT 4
535 #define ANSI_ISNI_COUNTER_MASK 0xe0
536 #define ANSI_ISNI_NETSPEC_MASK 0x03
538 static const value_string sccp_isni_mark_for_id_values [] = {
539 { 0x0, "Do not identify networks" },
540 { 0x1, "Identify networks" },
543 static const value_string sccp_isni_iri_values [] = {
544 { 0x0, "Neither constrained nor suggested ISNI routing" },
545 { 0x1, "Constrained ISNI routing" },
546 { 0x2, "Reserved for suggested ISNI routing" },
550 #define ANSI_ISNI_TYPE_0 0x0
551 #define ANSI_ISNI_TYPE_1 0x1
552 static const value_string sccp_isni_ti_values [] = {
553 { ANSI_ISNI_TYPE_0, "Type zero ISNI parameter format" },
554 { ANSI_ISNI_TYPE_1, "Type one ISNI parameter format" },
558 /* Initialize the protocol and registered fields */
559 static int proto_sccp = -1;
560 static int hf_sccp_message_type = -1;
561 static int hf_sccp_variable_pointer1 = -1;
562 static int hf_sccp_variable_pointer2 = -1;
563 static int hf_sccp_variable_pointer3 = -1;
564 static int hf_sccp_optional_pointer = -1;
565 static int hf_sccp_ssn = -1;
566 static int hf_sccp_gt_digits = -1;
568 /* Called Party address */
569 static int hf_sccp_called_national_indicator = -1;
570 static int hf_sccp_called_routing_indicator = -1;
571 static int hf_sccp_called_itu_global_title_indicator = -1;
572 static int hf_sccp_called_ansi_global_title_indicator = -1;
573 static int hf_sccp_called_itu_ssn_indicator = -1;
574 static int hf_sccp_called_itu_point_code_indicator = -1;
575 static int hf_sccp_called_ansi_ssn_indicator = -1;
576 static int hf_sccp_called_ansi_point_code_indicator = -1;
577 static int hf_sccp_called_ssn = -1;
578 static int hf_sccp_called_pc_member = -1;
579 static int hf_sccp_called_pc_cluster = -1;
580 static int hf_sccp_called_pc_network = -1;
581 static int hf_sccp_called_ansi_pc = -1;
582 static int hf_sccp_called_chinese_pc = -1;
583 static int hf_sccp_called_itu_pc = -1;
584 static int hf_sccp_called_japan_pc = -1;
585 static int hf_sccp_called_gt_nai = -1;
586 static int hf_sccp_called_gt_oe = -1;
587 static int hf_sccp_called_gt_tt = -1;
588 static int hf_sccp_called_gt_np = -1;
589 static int hf_sccp_called_gt_es = -1;
590 static int hf_sccp_called_gt_digits = -1;
592 /* Calling party address */
593 static int hf_sccp_calling_national_indicator = -1;
594 static int hf_sccp_calling_routing_indicator = -1;
595 static int hf_sccp_calling_itu_global_title_indicator = -1;
596 static int hf_sccp_calling_ansi_global_title_indicator = -1;
597 static int hf_sccp_calling_itu_ssn_indicator = -1;
598 static int hf_sccp_calling_itu_point_code_indicator = -1;
599 static int hf_sccp_calling_ansi_ssn_indicator = -1;
600 static int hf_sccp_calling_ansi_point_code_indicator = -1;
601 static int hf_sccp_calling_ssn = -1;
602 static int hf_sccp_calling_pc_member = -1;
603 static int hf_sccp_calling_pc_cluster = -1;
604 static int hf_sccp_calling_pc_network = -1;
605 static int hf_sccp_calling_ansi_pc = -1;
606 static int hf_sccp_calling_chinese_pc = -1;
607 static int hf_sccp_calling_itu_pc = -1;
608 static int hf_sccp_calling_japan_pc = -1;
609 static int hf_sccp_calling_gt_nai = -1;
610 static int hf_sccp_calling_gt_oe = -1;
611 static int hf_sccp_calling_gt_tt = -1;
612 static int hf_sccp_calling_gt_np = -1;
613 static int hf_sccp_calling_gt_es = -1;
614 static int hf_sccp_calling_gt_digits = -1;
616 /* Other parameter values */
617 static int hf_sccp_dlr = -1;
618 static int hf_sccp_slr = -1;
619 static int hf_sccp_lr = -1;
620 static int hf_sccp_class = -1;
621 static int hf_sccp_handling = -1;
622 static int hf_sccp_more = -1;
623 static int hf_sccp_rsn = -1;
624 static int hf_sccp_sequencing_segmenting_ssn = -1;
625 static int hf_sccp_sequencing_segmenting_rsn = -1;
626 static int hf_sccp_sequencing_segmenting_more = -1;
627 static int hf_sccp_credit = -1;
628 static int hf_sccp_release_cause = -1;
629 static int hf_sccp_return_cause = -1;
630 static int hf_sccp_reset_cause = -1;
631 static int hf_sccp_error_cause = -1;
632 static int hf_sccp_refusal_cause = -1;
633 static int hf_sccp_segmentation_first = -1;
634 static int hf_sccp_segmentation_class = -1;
635 static int hf_sccp_segmentation_remaining = -1;
636 static int hf_sccp_segmentation_slr = -1;
637 static int hf_sccp_hop_counter = -1;
638 static int hf_sccp_importance = -1;
639 static int hf_sccp_ansi_isni_mi = -1;
640 static int hf_sccp_ansi_isni_iri = -1;
641 static int hf_sccp_ansi_isni_ti = -1;
642 static int hf_sccp_ansi_isni_netspec = -1;
643 static int hf_sccp_ansi_isni_counter = -1;
644 static int hf_sccp_xudt_msg_fragments = -1;
645 static int hf_sccp_xudt_msg_fragment = -1;
646 static int hf_sccp_xudt_msg_fragment_overlap = -1;
647 static int hf_sccp_xudt_msg_fragment_overlap_conflicts = -1;
648 static int hf_sccp_xudt_msg_fragment_multiple_tails = -1;
649 static int hf_sccp_xudt_msg_fragment_too_long_fragment = -1;
650 static int hf_sccp_xudt_msg_fragment_error = -1;
651 static int hf_sccp_xudt_msg_reassembled_in = -1;
652 static int hf_sccp_assoc_msg = -1;
653 static int hf_sccp_assoc_id = -1;
655 /* Initialize the subtree pointers */
656 static gint ett_sccp = -1;
657 static gint ett_sccp_called = -1;
658 static gint ett_sccp_called_ai = -1;
659 static gint ett_sccp_called_pc = -1;
660 static gint ett_sccp_called_gt = -1;
661 static gint ett_sccp_calling = -1;
662 static gint ett_sccp_calling_ai = -1;
663 static gint ett_sccp_calling_pc = -1;
664 static gint ett_sccp_calling_gt = -1;
665 static gint ett_sccp_sequencing_segmenting = -1;
666 static gint ett_sccp_segmentation = -1;
667 static gint ett_sccp_ansi_isni_routing_control = -1;
668 static gint ett_sccp_xudt_msg_fragment = -1;
669 static gint ett_sccp_xudt_msg_fragments = -1;
670 static gint ett_sccp_assoc = -1;
672 /* Declarations to desegment XUDT Messages */
673 static gboolean sccp_xudt_desegment = TRUE;
675 static gboolean show_key_params = FALSE;
677 static int sccp_tap = -1;
680 static const fragment_items sccp_xudt_msg_frag_items = {
681 /* Fragment subtrees */
682 &ett_sccp_xudt_msg_fragment,
683 &ett_sccp_xudt_msg_fragments,
684 /* Fragment fields */
685 &hf_sccp_xudt_msg_fragments,
686 &hf_sccp_xudt_msg_fragment,
687 &hf_sccp_xudt_msg_fragment_overlap,
688 &hf_sccp_xudt_msg_fragment_overlap_conflicts,
689 &hf_sccp_xudt_msg_fragment_multiple_tails,
690 &hf_sccp_xudt_msg_fragment_too_long_fragment,
691 &hf_sccp_xudt_msg_fragment_error,
692 /* Reassembled in field */
693 &hf_sccp_xudt_msg_reassembled_in,
695 "SCCP XUDT Message fragments"
698 static GHashTable *sccp_xudt_msg_fragment_table = NULL;
699 static GHashTable *sccp_xudt_msg_reassembled_table = NULL;
704 * Here are the global variables associated with
705 * the various user definable characteristics of the dissection
707 static guint32 sccp_source_pc_global = 0;
708 static gboolean sccp_show_length = FALSE;
710 static module_t *sccp_module;
711 static heur_dissector_list_t heur_subdissector_list;
713 /* Keep track of SSN value of current message so if/when we get to the data
714 * parameter, we can call appropriate sub-dissector. TODO: can this info
715 * be stored elsewhere?
718 static guint8 message_type = 0;
719 static guint dlr = 0;
720 static guint slr = 0;
722 static dissector_handle_t data_handle;
723 static dissector_table_t sccp_ssn_dissector_table;
725 static emem_tree_t* assocs = NULL;
726 static sccp_assoc_info_t* assoc;
727 static sccp_msg_info_t* sccp_msg;
728 static sccp_assoc_info_t no_assoc = {0,0,0,0,0,FALSE,FALSE,NULL,NULL,SCCP_PLOAD_NONE,NULL,NULL,NULL};
729 static gboolean trace_sccp = FALSE;
730 static guint32 next_assoc_id = 0;
732 static const value_string assoc_protos[] = {
733 { SCCP_PLOAD_BSSAP, "BSSAP" },
734 { SCCP_PLOAD_RANAP, "RANAP" },
738 static sccp_assoc_info_t* new_assoc(guint32 calling, guint32 called){
739 sccp_assoc_info_t* a = se_alloc(sizeof(sccp_assoc_info_t));
741 a->id = next_assoc_id++;
742 a->calling_dpc = calling;
743 a->called_dpc = called;
744 a->calling_ssn = INVALID_SSN;
745 a->called_ssn = INVALID_SSN;
746 a->has_fw_key = FALSE;
747 a->has_bw_key = FALSE;
748 a->payload = SCCP_PLOAD_NONE;
749 a->calling_party = NULL;
750 a->called_party = NULL;
751 a->extra_info = NULL;
757 void reset_sccp_assoc(void) {
761 sccp_assoc_info_t* get_sccp_assoc(packet_info* pinfo, guint offset, guint32 src_lr, guint32 dst_lr, guint msg_type) {
763 address* opc = &(pinfo->src);
764 address* dpc = &(pinfo->dst);
765 guint framenum = pinfo->fd->num;
770 opck = opc->type == AT_SS7PC ? mtp3_pc_hash(opc->data) : g_str_hash(address_to_str(opc));
771 dpck = dpc->type == AT_SS7PC ? mtp3_pc_hash(dpc->data) : g_str_hash(address_to_str(dpc));
775 case SCCP_MSG_TYPE_CR:
777 /* CR contains the opc,dpc,dlr key of backward messages swapped as dpc,opc,slr */
778 emem_tree_key_t bw_key[] = {
779 {1, &dpck}, {1, &opck}, {1, &src_lr}, {0, NULL}
782 if (! ( assoc = se_tree_lookup32_array(assocs,bw_key) ) && ! pinfo->fd->flags.visited ) {
783 assoc = new_assoc(opck,dpck);
784 se_tree_insert32_array(assocs,bw_key,assoc);
785 assoc->has_bw_key = TRUE;
789 case SCCP_MSG_TYPE_CC:
791 emem_tree_key_t fw_key[] = {
792 {1, &dpck}, {1, &opck}, {1, &src_lr}, {0, NULL}
794 emem_tree_key_t bw_key[] = {
795 {1, &opck}, {1, &dpck}, {1, &dst_lr}, {0, NULL}
798 if ( ( assoc = se_tree_lookup32_array(assocs,bw_key) ) ) {
802 if ( (assoc = se_tree_lookup32_array(assocs,fw_key) ) ) {
806 assoc = new_assoc(opck,dpck);
809 if ( ! pinfo->fd->flags.visited && ! assoc->has_bw_key ) {
810 se_tree_insert32_array(assocs,bw_key,assoc);
811 assoc->has_bw_key = TRUE;
814 if ( ! pinfo->fd->flags.visited && ! assoc->has_fw_key ) {
815 se_tree_insert32_array(assocs,fw_key,assoc);
816 assoc->has_fw_key = TRUE;
823 emem_tree_key_t key[] = {
824 {1, &opck}, {1, &dpck}, {1, &dst_lr}, {0, NULL}
827 assoc = se_tree_lookup32_array(assocs,key);
833 if (assoc && trace_sccp) {
834 if ( ! pinfo->fd->flags.visited) {
835 sccp_msg_info_t* msg = se_alloc(sizeof(sccp_msg_info_t));
836 msg->framenum = framenum;
837 msg->offset = offset;
838 msg->data.co.next = NULL;
839 msg->data.co.assoc = assoc;
840 msg->data.co.label = NULL;
841 msg->data.co.comment = NULL;
842 msg->type = msg_type;
846 for (m = assoc->msgs; m->data.co.next; m = m->data.co.next) ;
847 m->data.co.next = msg;
852 assoc->curr_msg = msg;
858 for (m = assoc->msgs; m; m = m->data.co.next) {
859 if (m->framenum == framenum && m->offset == offset) {
867 return assoc ? assoc : &no_assoc;
872 dissect_sccp_unknown_message(tvbuff_t *message_tvb, proto_tree *sccp_tree)
874 guint32 message_length;
876 message_length = tvb_length(message_tvb);
878 proto_tree_add_text(sccp_tree, message_tvb, 0, message_length,
879 "Unknown message (%u byte%s)",
880 message_length, plurality(message_length, "", "s"));
884 dissect_sccp_unknown_param(tvbuff_t *tvb, proto_tree *tree, guint8 type, guint length)
886 proto_tree_add_text(tree, tvb, 0, length, "Unknown parameter 0x%x (%u byte%s)",
887 type, length, plurality(length, "", "s"));
891 dissect_sccp_dlr_param(tvbuff_t *tvb, proto_tree *tree, guint length, packet_info *pinfo)
895 dlr = tvb_get_letoh24(tvb, 0);
896 proto_tree_add_uint(tree, hf_sccp_dlr, tvb, 0, length, dlr);
897 lr_item = proto_tree_add_uint(tree, hf_sccp_lr, tvb, 0, length, dlr);
898 PROTO_ITEM_SET_HIDDEN(lr_item);
900 if (show_key_params && check_col(pinfo->cinfo, COL_INFO))
901 col_append_fstr(pinfo->cinfo, COL_INFO, "DLR=%d ", dlr);
905 dissect_sccp_slr_param(tvbuff_t *tvb, proto_tree *tree, guint length, packet_info *pinfo)
909 slr = tvb_get_letoh24(tvb, 0);
910 proto_tree_add_uint(tree, hf_sccp_slr, tvb, 0, length, slr);
911 lr_item = proto_tree_add_uint(tree, hf_sccp_lr, tvb, 0, length, slr);
912 PROTO_ITEM_SET_HIDDEN(lr_item);
914 if (show_key_params && check_col(pinfo->cinfo, COL_INFO))
915 col_append_fstr(pinfo->cinfo, COL_INFO, "SLR=%d ", slr);
919 #define is_connectionless(m) \
920 ( m == SCCP_MSG_TYPE_UDT || m == SCCP_MSG_TYPE_UDTS \
921 || m == SCCP_MSG_TYPE_XUDT|| m == SCCP_MSG_TYPE_XUDTS \
922 || m == SCCP_MSG_TYPE_LUDT|| m == SCCP_MSG_TYPE_LUDTS)
925 dissect_sccp_gt_address_information(tvbuff_t *tvb, proto_tree *tree,
926 guint length, gboolean even_length,
930 guint8 odd_signal, even_signal = 0x0f;
931 char gt_digits[GT_MAX_SIGNALS+1] = { 0 };
933 while(offset < length)
935 odd_signal = tvb_get_guint8(tvb, offset) & GT_ODD_SIGNAL_MASK;
936 even_signal = tvb_get_guint8(tvb, offset) & GT_EVEN_SIGNAL_MASK;
937 even_signal >>= GT_EVEN_SIGNAL_SHIFT;
939 strncat(gt_digits, val_to_str(odd_signal, sccp_address_signal_values,
940 "Unknown"), GT_MAX_SIGNALS - strlen(gt_digits));
942 /* If the last signal is NOT filler */
943 if (offset != (length - 1) || even_length == TRUE)
944 strncat(gt_digits, val_to_str(even_signal, sccp_address_signal_values,
945 "Unknown"), GT_MAX_SIGNALS - strlen(gt_digits));
947 offset += GT_SIGNAL_LENGTH;
950 if (is_connectionless(message_type) && sccp_msg) {
951 guint8** gt_ptr = called ? &(sccp_msg->data.ud.called_gt) : &(sccp_msg->data.ud.calling_gt);
953 *gt_ptr = ep_strdup(gt_digits);
956 proto_tree_add_string_format(tree, called ? hf_sccp_called_gt_digits
957 : hf_sccp_calling_gt_digits,
958 tvb, 0, length, gt_digits,
959 "Address information (digits): %s", gt_digits);
960 proto_tree_add_string_hidden(tree, called ? hf_sccp_gt_digits
962 tvb, 0, length, gt_digits);
966 dissect_sccp_global_title(tvbuff_t *tvb, proto_tree *tree, guint length,
967 guint8 gti, gboolean called)
969 proto_item *gt_item = 0;
970 proto_tree *gt_tree = 0;
971 tvbuff_t *signals_tvb;
973 guint8 odd_even, nai, tt, np, es;
974 gboolean even = TRUE;
976 /* Shift GTI to where we can work with it */
979 gt_item = proto_tree_add_text(tree, tvb, offset, length,
980 "Global Title 0x%x (%u byte%s)",
981 gti, length, plurality(length,"", "s"));
982 gt_tree = proto_item_add_subtree(gt_item, called ? ett_sccp_called_gt
983 : ett_sccp_calling_gt);
985 /* Decode Transation Type (if present) */
989 /* Protocol doesn't tell us, so we ASSUME even... */
992 case ITU_AI_GTI_TT_NP_ES:
993 case ITU_AI_GTI_TT_NP_ES_NAI:
994 case ANSI_AI_GTI_TT_NP_ES:
996 tt = tvb_get_guint8(tvb, offset);
997 proto_tree_add_uint(gt_tree, called ? hf_sccp_called_gt_tt
998 : hf_sccp_calling_gt_tt,
999 tvb, offset, GT_TT_LENGTH, tt);
1000 offset += GT_TT_LENGTH;
1003 /* Decode Numbering Plan and Encoding Scheme (if present) */
1005 case ITU_AI_GTI_TT_NP_ES:
1006 case ITU_AI_GTI_TT_NP_ES_NAI:
1007 case ANSI_AI_GTI_TT_NP_ES:
1009 np = tvb_get_guint8(tvb, offset) & GT_NP_MASK;
1010 proto_tree_add_uint(gt_tree, called ? hf_sccp_called_gt_np
1011 : hf_sccp_calling_gt_np,
1012 tvb, offset, GT_NP_ES_LENGTH, np);
1014 es = tvb_get_guint8(tvb, offset) & GT_ES_MASK;
1015 proto_tree_add_uint(gt_tree, called ? hf_sccp_called_gt_es
1016 : hf_sccp_calling_gt_es,
1017 tvb, offset, GT_NP_ES_LENGTH, es);
1019 even = (es == GT_ES_BCD_EVEN) ? TRUE : FALSE;
1021 offset += GT_NP_ES_LENGTH;
1024 /* Decode Odd/Even Indicator (if present) */
1025 if (gti == ITU_AI_GTI_NAI) {
1026 odd_even = tvb_get_guint8(tvb, offset) & GT_OE_MASK;
1027 proto_tree_add_uint(gt_tree, called ? hf_sccp_called_gt_oe
1028 : hf_sccp_calling_gt_oe,
1029 tvb, offset, GT_NAI_LENGTH, odd_even);
1030 even = (odd_even == GT_OE_EVEN) ? TRUE : FALSE;
1032 /* offset doesn't change */
1035 /* Decode Nature of Address Indicator (if present) */
1037 case ITU_AI_GTI_NAI:
1038 case ITU_AI_GTI_TT_NP_ES_NAI:
1039 nai = tvb_get_guint8(tvb, offset) & GT_NAI_MASK;
1040 proto_tree_add_uint(gt_tree, called ? hf_sccp_called_gt_nai
1041 : hf_sccp_calling_gt_nai,
1042 tvb, offset, GT_NAI_LENGTH, nai);
1044 offset += GT_NAI_LENGTH;
1047 /* Decode address signal(s) */
1048 if (length < offset)
1051 signals_tvb = tvb_new_subset(tvb, offset, (length - offset),
1053 dissect_sccp_gt_address_information(signals_tvb, gt_tree, (length - offset),
1058 dissect_sccp_3byte_pc(tvbuff_t *tvb, proto_tree *call_tree, guint offset,
1063 if (decode_mtp3_standard == ANSI_STANDARD)
1066 hf_pc = &hf_sccp_called_ansi_pc;
1068 hf_pc = &hf_sccp_calling_ansi_pc;
1069 } else /* CHINESE_ITU_STANDARD */ {
1071 hf_pc = &hf_sccp_called_chinese_pc;
1073 hf_pc = &hf_sccp_calling_chinese_pc;
1076 /* create and fill the PC tree */
1077 dissect_mtp3_3byte_pc(tvb, offset, call_tree,
1078 called ? ett_sccp_called_pc : ett_sccp_calling_pc,
1080 called ? hf_sccp_called_pc_network : hf_sccp_calling_pc_network,
1081 called ? hf_sccp_called_pc_cluster : hf_sccp_calling_pc_cluster,
1082 called ? hf_sccp_called_pc_member : hf_sccp_calling_pc_member,
1085 return(offset + ANSI_PC_LENGTH);
1088 /* FUNCTION dissect_sccp_called_calling_param():
1089 * Dissect the Calling or Called Party Address parameters.
1091 * The boolean 'called' describes whether this function is decoding a
1092 * called (TRUE) or calling (FALSE) party address. There is simply too
1093 * much code in this function to have 2 copies of it (one for called, one
1096 * NOTE: this function is called even when (!tree) so that we can get
1097 * the SSN and subsequently call subdissectors (if and when there's a data
1098 * parameter). Realistically we should put if (!tree)'s around a lot of the
1099 * code, but I think that would make it unreadable--and the expense of not
1100 * doing so does not appear to be very high.
1103 dissect_sccp_called_calling_param(tvbuff_t *tvb, proto_tree *tree,
1104 guint length, gboolean called)
1106 proto_item *call_item = 0, *call_ai_item = 0, *item;
1107 proto_tree *call_tree = 0, *call_ai_tree = 0;
1109 guint8 national = -1, routing_ind, gti, pci, ssni, ssn;
1111 dissector_handle_t ssn_dissector = NULL, tcap_ssn_dissector = NULL;
1112 const char *ssn_dissector_short_name = NULL;
1113 const char *tcap_ssn_dissector_short_name = NULL;
1115 call_item = proto_tree_add_text(tree, tvb, 0, length,
1116 "%s Party address (%u byte%s)",
1117 called ? "Called" : "Calling", length,
1118 plurality(length, "", "s"));
1119 call_tree = proto_item_add_subtree(call_item, called ? ett_sccp_called
1120 : ett_sccp_calling);
1122 call_ai_item = proto_tree_add_text(call_tree, tvb, 0,
1123 ADDRESS_INDICATOR_LENGTH,
1124 "Address Indicator");
1125 call_ai_tree = proto_item_add_subtree(call_ai_item, called ? ett_sccp_called_ai
1126 : ett_sccp_calling_ai);
1128 if (decode_mtp3_standard == ANSI_STANDARD)
1130 national = tvb_get_guint8(tvb, 0) & ANSI_NATIONAL_MASK;
1131 proto_tree_add_uint(call_ai_tree, called ? hf_sccp_called_national_indicator
1132 : hf_sccp_calling_national_indicator,
1133 tvb, 0, ADDRESS_INDICATOR_LENGTH, national);
1136 routing_ind = tvb_get_guint8(tvb, 0) & ROUTING_INDICATOR_MASK;
1137 proto_tree_add_uint(call_ai_tree, called ? hf_sccp_called_routing_indicator
1138 : hf_sccp_calling_routing_indicator,
1139 tvb, 0, ADDRESS_INDICATOR_LENGTH, routing_ind);
1141 gti = tvb_get_guint8(tvb, 0) & GTI_MASK;
1143 if (decode_mtp3_standard == ITU_STANDARD ||
1144 decode_mtp3_standard == CHINESE_ITU_STANDARD ||
1145 decode_mtp3_standard == JAPAN_STANDARD ||
1148 proto_tree_add_uint(call_ai_tree, called ? hf_sccp_called_itu_global_title_indicator
1149 : hf_sccp_called_itu_global_title_indicator,
1150 tvb, 0, ADDRESS_INDICATOR_LENGTH, gti);
1152 ssni = tvb_get_guint8(tvb, 0) & ITU_SSN_INDICATOR_MASK;
1153 proto_tree_add_uint(call_ai_tree, called ? hf_sccp_called_itu_ssn_indicator
1154 : hf_sccp_calling_itu_ssn_indicator,
1155 tvb, 0, ADDRESS_INDICATOR_LENGTH, ssni);
1157 pci = tvb_get_guint8(tvb, 0) & ITU_PC_INDICATOR_MASK;
1158 proto_tree_add_uint(call_ai_tree, called ? hf_sccp_called_itu_point_code_indicator
1159 : hf_sccp_calling_itu_point_code_indicator,
1160 tvb, 0, ADDRESS_INDICATOR_LENGTH, pci);
1162 offset = ADDRESS_INDICATOR_LENGTH;
1164 /* Dissect PC (if present) */
1166 if (decode_mtp3_standard == ITU_STANDARD) {
1168 proto_tree_add_item(call_tree, called ? hf_sccp_called_itu_pc
1169 : hf_sccp_calling_itu_pc,
1170 tvb, offset, ITU_PC_LENGTH, TRUE);
1172 offset += ITU_PC_LENGTH;
1174 } else if (decode_mtp3_standard == JAPAN_STANDARD) {
1176 proto_tree_add_item(call_tree, called ? hf_sccp_called_japan_pc
1177 : hf_sccp_calling_japan_pc,
1178 tvb, offset, JAPAN_PC_LENGTH, TRUE);
1180 offset += JAPAN_PC_LENGTH;
1182 } else /* CHINESE_ITU_STANDARD */ {
1184 offset = dissect_sccp_3byte_pc(tvb, call_tree, offset, called);
1189 /* Dissect SSN (if present) */
1191 ssn = tvb_get_guint8(tvb, offset);
1193 if (called && assoc)
1194 assoc->called_ssn = ssn;
1196 assoc->calling_ssn = ssn;
1198 if (is_connectionless(message_type) && sccp_msg) {
1199 guint* ssn_ptr = called ? &(sccp_msg->data.ud.called_ssn) : &(sccp_msg->data.ud.calling_ssn);
1204 proto_tree_add_uint(call_tree, called ? hf_sccp_called_ssn
1205 : hf_sccp_calling_ssn,
1206 tvb, offset, ADDRESS_SSN_LENGTH, ssn);
1207 proto_tree_add_uint_hidden(call_tree, hf_sccp_ssn, tvb, offset,
1208 ADDRESS_SSN_LENGTH, ssn);
1209 offset += ADDRESS_SSN_LENGTH;
1211 /* Get the dissector handle of the dissector registered for this ssn
1212 * And print it's name.
1214 ssn_dissector = dissector_get_port_handle(sccp_ssn_dissector_table, ssn);
1216 if (ssn_dissector) {
1217 ssn_dissector_short_name = dissector_handle_get_short_name(ssn_dissector);
1219 if(ssn_dissector_short_name) {
1220 item = proto_tree_add_text(call_tree, tvb, offset - 1, ADDRESS_SSN_LENGTH, "Linked to %s", ssn_dissector_short_name);
1221 PROTO_ITEM_SET_GENERATED(item);
1223 if (strncasecmp("TCAP", ssn_dissector_short_name, 4)== 0) {
1224 tcap_ssn_dissector = get_itu_tcap_subdissector(ssn);
1226 if(tcap_ssn_dissector){
1227 tcap_ssn_dissector_short_name = dissector_handle_get_short_name(tcap_ssn_dissector);
1228 proto_item_append_text(item,", TCAP SSN linked to %s", tcap_ssn_dissector_short_name);
1232 } /* ssn_dissector */
1236 return; /* got SSN, that's all we need here... */
1238 /* Dissect GT (if present) */
1239 if (gti != AI_GTI_NO_GT) {
1240 if (length < offset)
1243 gt_tvb = tvb_new_subset(tvb, offset, (length - offset),
1245 dissect_sccp_global_title(gt_tvb, call_tree, (length - offset), gti,
1249 } else if (decode_mtp3_standard == ANSI_STANDARD) {
1251 proto_tree_add_uint(call_ai_tree, called ? hf_sccp_called_ansi_global_title_indicator
1252 : hf_sccp_calling_ansi_global_title_indicator,
1253 tvb, 0, ADDRESS_INDICATOR_LENGTH, gti);
1255 pci = tvb_get_guint8(tvb, 0) & ANSI_PC_INDICATOR_MASK;
1256 proto_tree_add_uint(call_ai_tree, called ? hf_sccp_called_ansi_point_code_indicator
1257 : hf_sccp_calling_ansi_point_code_indicator,
1258 tvb, 0, ADDRESS_INDICATOR_LENGTH, pci);
1260 ssni = tvb_get_guint8(tvb, 0) & ANSI_SSN_INDICATOR_MASK;
1261 proto_tree_add_uint(call_ai_tree, called ? hf_sccp_called_ansi_ssn_indicator
1262 : hf_sccp_calling_ansi_ssn_indicator,
1263 tvb, 0, ADDRESS_INDICATOR_LENGTH, ssni);
1265 offset = ADDRESS_INDICATOR_LENGTH;
1267 /* Dissect SSN (if present) */
1269 ssn = tvb_get_guint8(tvb, offset);
1271 if (called && assoc)
1272 assoc->called_ssn = ssn;
1274 assoc->calling_ssn = ssn;
1276 if (is_connectionless(message_type) && sccp_msg) {
1277 guint* ssn_ptr = called ? &(sccp_msg->data.ud.called_ssn) : &(sccp_msg->data.ud.calling_ssn);
1282 proto_tree_add_uint(call_tree, called ? hf_sccp_called_ssn
1283 : hf_sccp_calling_ssn,
1284 tvb, offset, ADDRESS_SSN_LENGTH, ssn);
1285 proto_tree_add_uint_hidden(call_tree, hf_sccp_ssn, tvb, offset,
1286 ADDRESS_SSN_LENGTH, ssn);
1287 offset += ADDRESS_SSN_LENGTH;
1291 return; /* got SSN, that's all we need here... */
1293 /* Dissect PC (if present) */
1295 offset = dissect_sccp_3byte_pc(tvb, call_tree, offset, called);
1298 /* Dissect GT (if present) */
1299 if (gti != AI_GTI_NO_GT) {
1300 if (length < offset)
1302 gt_tvb = tvb_new_subset(tvb, offset, (length - offset),
1304 dissect_sccp_global_title(gt_tvb, call_tree, (length - offset), gti,
1313 dissect_sccp_called_param(tvbuff_t *tvb, proto_tree *tree, guint length)
1315 dissect_sccp_called_calling_param(tvb, tree, length, TRUE);
1319 dissect_sccp_calling_param(tvbuff_t *tvb, proto_tree *tree, guint length)
1321 dissect_sccp_called_calling_param(tvb, tree, length, FALSE);
1325 dissect_sccp_class_param(tvbuff_t *tvb, proto_tree *tree, guint length)
1327 guint8 class, handling;
1329 class = tvb_get_guint8(tvb, 0) & CLASS_CLASS_MASK;
1330 handling = tvb_get_guint8(tvb, 0) & CLASS_SPARE_HANDLING_MASK;
1332 proto_tree_add_uint(tree, hf_sccp_class, tvb, 0, length, class);
1334 if (class == 0 || class == 1)
1335 proto_tree_add_uint(tree, hf_sccp_handling, tvb, 0, length, handling);
1339 dissect_sccp_segmenting_reassembling_param(tvbuff_t *tvb, proto_tree *tree, guint length)
1341 proto_tree_add_item(tree, hf_sccp_more, tvb, 0, length, FALSE);
1345 dissect_sccp_receive_sequence_number_param(tvbuff_t *tvb, proto_tree *tree, guint length)
1349 rsn = tvb_get_guint8(tvb, 0) >> 1;
1350 proto_tree_add_uint(tree, hf_sccp_rsn, tvb, 0, length, rsn);
1354 dissect_sccp_sequencing_segmenting_param(tvbuff_t *tvb, proto_tree *tree, guint length)
1356 guint8 rsn, ssn, more;
1357 proto_item *param_item;
1358 proto_tree *param_tree;
1360 ssn = tvb_get_guint8(tvb, 0) >> 1;
1361 rsn = tvb_get_guint8(tvb, SEQUENCING_SEGMENTING_SSN_LENGTH) >> 1;
1362 more = tvb_get_guint8(tvb, SEQUENCING_SEGMENTING_SSN_LENGTH) & SEQUENCING_SEGMENTING_MORE_MASK;
1364 param_item = proto_tree_add_text(tree, tvb, 0, length,
1365 val_to_str(PARAMETER_SEQUENCING_SEGMENTING,
1366 sccp_parameter_values, "Unknown"));
1367 param_tree = proto_item_add_subtree(param_item,
1368 ett_sccp_sequencing_segmenting);
1370 proto_tree_add_uint(param_tree, hf_sccp_sequencing_segmenting_ssn, tvb, 0,
1371 SEQUENCING_SEGMENTING_SSN_LENGTH, ssn);
1372 proto_tree_add_uint(param_tree, hf_sccp_sequencing_segmenting_rsn, tvb,
1373 SEQUENCING_SEGMENTING_SSN_LENGTH,
1374 SEQUENCING_SEGMENTING_RSN_LENGTH, rsn);
1375 proto_tree_add_uint(param_tree, hf_sccp_sequencing_segmenting_more, tvb,
1376 SEQUENCING_SEGMENTING_SSN_LENGTH,
1377 SEQUENCING_SEGMENTING_RSN_LENGTH, more);
1381 dissect_sccp_credit_param(tvbuff_t *tvb, proto_tree *tree, guint length)
1385 credit = tvb_get_guint8(tvb, 0);
1386 proto_tree_add_uint(tree, hf_sccp_credit, tvb, 0, length, credit);
1390 dissect_sccp_release_cause_param(tvbuff_t *tvb, proto_tree *tree, guint length, packet_info *pinfo)
1394 cause = tvb_get_guint8(tvb, 0);
1395 proto_tree_add_uint(tree, hf_sccp_release_cause, tvb, 0, length, cause);
1397 if (show_key_params && check_col(pinfo->cinfo, COL_INFO))
1398 col_append_fstr(pinfo->cinfo, COL_INFO, "Cause=%d ", cause);
1402 dissect_sccp_return_cause_param(tvbuff_t *tvb, proto_tree *tree, guint length, packet_info *pinfo)
1406 cause = tvb_get_guint8(tvb, 0);
1407 proto_tree_add_uint(tree, hf_sccp_return_cause, tvb, 0, length, cause);
1409 if (show_key_params && check_col(pinfo->cinfo, COL_INFO))
1410 col_append_fstr(pinfo->cinfo, COL_INFO, "Cause=%d ", cause);
1414 dissect_sccp_reset_cause_param(tvbuff_t *tvb, proto_tree *tree, guint length, packet_info *pinfo)
1418 cause = tvb_get_guint8(tvb, 0);
1419 proto_tree_add_uint(tree, hf_sccp_reset_cause, tvb, 0, length, cause);
1421 if (show_key_params && check_col(pinfo->cinfo, COL_INFO))
1422 col_append_fstr(pinfo->cinfo, COL_INFO, "Cause=%d ", cause);
1426 dissect_sccp_error_cause_param(tvbuff_t *tvb, proto_tree *tree, guint length, packet_info *pinfo)
1430 cause = tvb_get_guint8(tvb, 0);
1431 proto_tree_add_uint(tree, hf_sccp_error_cause, tvb, 0, length, cause);
1433 if (show_key_params && check_col(pinfo->cinfo, COL_INFO))
1434 col_append_fstr(pinfo->cinfo, COL_INFO, "Cause=%d ", cause);
1438 dissect_sccp_refusal_cause_param(tvbuff_t *tvb, proto_tree *tree, guint length, packet_info *pinfo)
1442 cause = tvb_get_guint8(tvb, 0);
1443 proto_tree_add_uint(tree, hf_sccp_refusal_cause, tvb, 0, length, cause);
1445 if (show_key_params && check_col(pinfo->cinfo, COL_INFO))
1446 col_append_fstr(pinfo->cinfo, COL_INFO, "Cause=%d ", cause);
1449 /* This function is used for both data and long data (ITU only) parameters */
1451 dissect_sccp_data_param(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
1453 guint8 ssn = INVALID_SSN;
1454 guint8 other_ssn = INVALID_SSN;
1456 if (trace_sccp && assoc && assoc != &no_assoc) {
1457 pinfo->sccp_info = assoc->curr_msg;
1459 pinfo->sccp_info = NULL;
1463 other_ssn = INVALID_SSN;
1465 switch (pinfo->p2p_dir) {
1467 ssn = assoc->calling_ssn;
1470 ssn = assoc->called_ssn;
1473 ssn = assoc->called_ssn;
1474 other_ssn = assoc->calling_ssn;
1479 ssn = assoc->called_ssn;
1480 other_ssn = assoc->calling_ssn;
1483 if (ssn != INVALID_SSN && dissector_try_port(sccp_ssn_dissector_table, ssn, tvb, pinfo, tree)) {
1487 if (other_ssn != INVALID_SSN && dissector_try_port(sccp_ssn_dissector_table, other_ssn, tvb, pinfo, tree)) {
1491 /* try heuristic subdissector list to see if there are any takers */
1492 if (dissector_try_heuristic(heur_subdissector_list, tvb, pinfo, tree)) {
1496 /* No sub-dissection occured, treat it as raw data */
1497 call_dissector(data_handle, tvb, pinfo, tree);
1502 dissect_sccp_segmentation_param(tvbuff_t *tvb, proto_tree *tree, guint length)
1504 guint8 first, class, remaining;
1506 proto_item *param_item;
1507 proto_tree *param_tree;
1509 first = tvb_get_guint8(tvb, 0) & SEGMENTATION_FIRST_SEGMENT_MASK;
1510 class = tvb_get_guint8(tvb, 0) & SEGMENTATION_CLASS_MASK;
1511 remaining = tvb_get_guint8(tvb, 0) & SEGMENTATION_REMAINING_MASK;
1513 slr = tvb_get_letoh24(tvb, 1);
1515 param_item = proto_tree_add_text(tree, tvb, 0, length,
1516 val_to_str(PARAMETER_SEGMENTATION,
1517 sccp_parameter_values, "Unknown"));
1518 param_tree = proto_item_add_subtree(param_item, ett_sccp_segmentation);
1520 proto_tree_add_uint(param_tree, hf_sccp_segmentation_first, tvb, 0, length,
1522 proto_tree_add_uint(param_tree, hf_sccp_segmentation_class, tvb, 0, length,
1524 proto_tree_add_uint(param_tree, hf_sccp_segmentation_remaining, tvb, 0,
1526 proto_tree_add_uint(param_tree, hf_sccp_segmentation_slr, tvb, 1, length,
1531 dissect_sccp_hop_counter_param(tvbuff_t *tvb, proto_tree *tree, guint length)
1535 hops = tvb_get_guint8(tvb, 0);
1536 proto_tree_add_uint(tree, hf_sccp_hop_counter, tvb, 0, length, hops);
1540 dissect_sccp_importance_param(tvbuff_t *tvb, proto_tree *tree, guint length)
1544 importance = tvb_get_guint8(tvb, 0) & IMPORTANCE_IMPORTANCE_MASK;
1545 proto_tree_add_uint(tree, hf_sccp_importance, tvb, 0, length, importance);
1549 dissect_sccp_isni_param(tvbuff_t *tvb, proto_tree *tree, guint length)
1551 guint8 mi, iri, ti, network, netspec;
1553 proto_item *param_item;
1554 proto_tree *param_tree;
1556 /* Create a subtree for ISNI Routing Control */
1557 param_item = proto_tree_add_text(tree, tvb, offset, ANSI_ISNI_ROUTING_CONTROL_LENGTH,
1558 "ISNI Routing Control");
1559 param_tree = proto_item_add_subtree(param_item,
1560 ett_sccp_ansi_isni_routing_control);
1562 mi = tvb_get_guint8(tvb, offset) & ANSI_ISNI_MI_MASK;
1563 proto_tree_add_uint(param_tree, hf_sccp_ansi_isni_mi, tvb, offset,
1564 ANSI_ISNI_ROUTING_CONTROL_LENGTH, mi);
1566 iri = tvb_get_guint8(tvb, offset) & ANSI_ISNI_IRI_MASK;
1567 proto_tree_add_uint(param_tree, hf_sccp_ansi_isni_iri, tvb, offset,
1568 ANSI_ISNI_ROUTING_CONTROL_LENGTH, iri);
1570 ti = tvb_get_guint8(tvb, offset) & ANSI_ISNI_TI_MASK;
1571 proto_tree_add_uint(param_tree, hf_sccp_ansi_isni_ti, tvb, offset,
1572 ANSI_ISNI_ROUTING_CONTROL_LENGTH, ti);
1574 offset += ANSI_ISNI_ROUTING_CONTROL_LENGTH;
1576 if ((ti >> ANSI_ISNI_TI_SHIFT) == ANSI_ISNI_TYPE_1) {
1577 netspec = tvb_get_guint8(tvb, offset) & ANSI_ISNI_NETSPEC_MASK;
1578 proto_tree_add_uint(param_tree, hf_sccp_ansi_isni_netspec, tvb, offset,
1579 ANSI_ISNI_ROUTING_CONTROL_LENGTH, ti);
1580 offset += ANSI_ISNI_ROUTING_CONTROL_LENGTH;
1583 while (offset < length) {
1585 network = tvb_get_guint8(tvb, offset);
1586 proto_tree_add_text(tree, tvb, offset, ANSI_NCM_LENGTH,
1587 "Network ID network: %d", network);
1590 network = tvb_get_guint8(tvb, offset);
1591 proto_tree_add_text(tree, tvb, offset, ANSI_NCM_LENGTH,
1592 "Network ID cluster: %d", network);
1598 /* FUNCTION dissect_sccp_parameter():
1599 * Dissect a parameter given its type, offset into tvb, and length.
1602 dissect_sccp_parameter(tvbuff_t *tvb, packet_info *pinfo, proto_tree *sccp_tree,
1603 proto_tree *tree, guint8 parameter_type, guint16 offset,
1604 guint16 parameter_length)
1606 tvbuff_t *parameter_tvb;
1608 switch (parameter_type) {
1609 case PARAMETER_CALLED_PARTY_ADDRESS:
1610 case PARAMETER_CALLING_PARTY_ADDRESS:
1611 case PARAMETER_DATA:
1612 case PARAMETER_LONG_DATA:
1613 case PARAMETER_SOURCE_LOCAL_REFERENCE:
1614 case PARAMETER_DESTINATION_LOCAL_REFERENCE:
1615 case PARAMETER_RELEASE_CAUSE:
1616 case PARAMETER_RETURN_CAUSE:
1617 case PARAMETER_RESET_CAUSE:
1618 case PARAMETER_ERROR_CAUSE:
1619 case PARAMETER_REFUSAL_CAUSE:
1621 /* These parameters must be dissected even if !sccp_tree (so that
1622 * assoc information can be created).
1627 if (!sccp_tree) return(parameter_length);
1631 parameter_tvb = tvb_new_subset(tvb, offset, parameter_length, parameter_length);
1633 switch (parameter_type) {
1635 case PARAMETER_END_OF_OPTIONAL_PARAMETERS:
1636 proto_tree_add_text(sccp_tree, tvb, offset, parameter_length,
1640 case PARAMETER_DESTINATION_LOCAL_REFERENCE:
1641 dissect_sccp_dlr_param(parameter_tvb, sccp_tree, parameter_length, pinfo);
1644 case PARAMETER_SOURCE_LOCAL_REFERENCE:
1645 dissect_sccp_slr_param(parameter_tvb, sccp_tree, parameter_length, pinfo);
1648 case PARAMETER_CALLED_PARTY_ADDRESS:
1649 dissect_sccp_called_param(parameter_tvb, sccp_tree, parameter_length);
1652 case PARAMETER_CALLING_PARTY_ADDRESS:
1653 dissect_sccp_calling_param(parameter_tvb, sccp_tree, parameter_length);
1656 case PARAMETER_CLASS:
1657 dissect_sccp_class_param(parameter_tvb, sccp_tree, parameter_length);
1660 case PARAMETER_SEGMENTING_REASSEMBLING:
1661 dissect_sccp_segmenting_reassembling_param(parameter_tvb, sccp_tree,
1665 case PARAMETER_RECEIVE_SEQUENCE_NUMBER:
1666 dissect_sccp_receive_sequence_number_param(parameter_tvb, sccp_tree,
1670 case PARAMETER_SEQUENCING_SEGMENTING:
1671 dissect_sccp_sequencing_segmenting_param(parameter_tvb, sccp_tree,
1675 case PARAMETER_CREDIT:
1676 dissect_sccp_credit_param(parameter_tvb, sccp_tree, parameter_length);
1679 case PARAMETER_RELEASE_CAUSE:
1680 dissect_sccp_release_cause_param(parameter_tvb, sccp_tree, parameter_length, pinfo);
1683 case PARAMETER_RETURN_CAUSE:
1684 dissect_sccp_return_cause_param(parameter_tvb, sccp_tree, parameter_length, pinfo);
1687 case PARAMETER_RESET_CAUSE:
1688 dissect_sccp_reset_cause_param(parameter_tvb, sccp_tree, parameter_length, pinfo);
1691 case PARAMETER_ERROR_CAUSE:
1692 dissect_sccp_error_cause_param(parameter_tvb, sccp_tree, parameter_length, pinfo);
1695 case PARAMETER_REFUSAL_CAUSE:
1696 dissect_sccp_refusal_cause_param(parameter_tvb, sccp_tree, parameter_length, pinfo);
1699 case PARAMETER_DATA:
1700 dissect_sccp_data_param(parameter_tvb, pinfo, tree);
1702 /* TODO? Re-adjust length of SCCP item since it may be sub-dissected */
1703 /* sccp_length = proto_item_get_len(sccp_item);
1704 * sccp_length -= parameter_length;
1705 * proto_item_set_len(sccp_item, sccp_length);
1709 case PARAMETER_SEGMENTATION:
1710 dissect_sccp_segmentation_param(parameter_tvb, sccp_tree, parameter_length);
1713 case PARAMETER_HOP_COUNTER:
1714 dissect_sccp_hop_counter_param(parameter_tvb, sccp_tree, parameter_length);
1717 case PARAMETER_IMPORTANCE:
1718 if (decode_mtp3_standard != ANSI_STANDARD)
1719 dissect_sccp_importance_param(parameter_tvb, sccp_tree, parameter_length);
1721 dissect_sccp_unknown_param(parameter_tvb, sccp_tree, parameter_type,
1725 case PARAMETER_LONG_DATA:
1726 if (decode_mtp3_standard != ANSI_STANDARD)
1727 dissect_sccp_data_param(parameter_tvb, pinfo, tree);
1729 dissect_sccp_unknown_param(parameter_tvb, sccp_tree, parameter_type,
1733 case PARAMETER_ISNI:
1734 if (decode_mtp3_standard != ANSI_STANDARD)
1735 dissect_sccp_unknown_param(parameter_tvb, sccp_tree, parameter_type,
1738 dissect_sccp_isni_param(parameter_tvb, sccp_tree, parameter_length);
1742 dissect_sccp_unknown_param(parameter_tvb, sccp_tree, parameter_type,
1747 return(parameter_length);
1750 /* FUNCTION dissect_sccp_variable_parameter():
1751 * Dissect a variable parameter given its type and offset into tvb. Length
1752 * of the parameter is gotten from tvb[0].
1753 * Length returned is sum of (length + parameter).
1756 dissect_sccp_variable_parameter(tvbuff_t *tvb, packet_info *pinfo,
1757 proto_tree *sccp_tree, proto_tree *tree,
1758 guint8 parameter_type, guint16 offset)
1760 guint16 parameter_length;
1761 guint8 length_length;
1763 if (parameter_type != PARAMETER_LONG_DATA)
1765 parameter_length = tvb_get_guint8(tvb, offset);
1766 length_length = PARAMETER_LENGTH_LENGTH;
1770 /* Long data parameter has 16 bit length */
1771 parameter_length = tvb_get_letohs(tvb, offset);
1772 length_length = PARAMETER_LONG_DATA_LENGTH_LENGTH;
1775 if (sccp_tree && sccp_show_length)
1777 proto_tree_add_text(sccp_tree, tvb, offset, length_length,
1779 val_to_str(parameter_type, sccp_parameter_values,
1784 offset += length_length;
1786 dissect_sccp_parameter(tvb, pinfo, sccp_tree, tree, parameter_type, offset,
1789 return(parameter_length + length_length);
1792 /* FUNCTION dissect_sccp_optional_parameters():
1793 * Dissect all the optional parameters given the start of the optional
1794 * parameters into tvb. Parameter types and lengths are read from tvb.
1797 dissect_sccp_optional_parameters(tvbuff_t *tvb, packet_info *pinfo,
1798 proto_tree *sccp_tree, proto_tree *tree,
1801 guint8 parameter_type;
1803 while ((parameter_type = tvb_get_guint8(tvb, offset)) !=
1804 PARAMETER_END_OF_OPTIONAL_PARAMETERS) {
1806 offset += PARAMETER_TYPE_LENGTH;
1807 offset += dissect_sccp_variable_parameter(tvb, pinfo, sccp_tree, tree,
1808 parameter_type, offset);
1811 /* Process end of optional parameters */
1812 dissect_sccp_parameter(tvb, pinfo, sccp_tree, tree, parameter_type, offset,
1813 END_OF_OPTIONAL_PARAMETERS_LENGTH);
1817 static sccp_msg_info_t* new_ud_msg(packet_info* pinfo, guint32 msg_type _U_) {
1818 sccp_msg_info_t* m = ep_alloc(sizeof(sccp_msg_info_t));
1819 m->framenum = pinfo->fd->num;
1820 m->offset = 0; /* irrelevant */
1822 m->data.ud.calling_gt = NULL;
1823 m->data.ud.calling_ssn = 0;
1824 m->data.ud.called_gt = NULL;
1825 m->data.ud.called_ssn = 0;
1831 dissect_sccp_message(tvbuff_t *tvb, packet_info *pinfo, proto_tree *sccp_tree,
1834 guint16 variable_pointer1 = 0, variable_pointer2 = 0, variable_pointer3 = 0;
1835 guint16 optional_pointer = 0, orig_opt_ptr = 0;
1837 guint8 parameter_type;
1838 gboolean save_fragmented;
1839 tvbuff_t *new_tvb = NULL;
1840 fragment_data *frag_msg = NULL;
1841 guint32 source_local_ref=0;
1843 guint msg_offset = offset_from_real_beginning(tvb,0);
1845 /* Macro for getting pointer to mandatory variable parameters */
1846 #define VARIABLE_POINTER(var, hf_var, ptr_size) \
1847 if (ptr_size == POINTER_LENGTH) \
1848 var = tvb_get_guint8(tvb, offset); \
1850 var = tvb_get_letohs(tvb, offset); \
1851 proto_tree_add_uint(sccp_tree, hf_var, tvb, \
1852 offset, ptr_size, var); \
1854 if (ptr_size == POINTER_LENGTH_LONG) \
1858 /* Macro for getting pointer to optional parameters */
1859 #define OPTIONAL_POINTER(ptr_size) \
1860 if (ptr_size == POINTER_LENGTH) \
1861 orig_opt_ptr = optional_pointer = tvb_get_guint8(tvb, offset); \
1863 orig_opt_ptr = optional_pointer = tvb_get_letohs(tvb, offset); \
1864 proto_tree_add_uint(sccp_tree, hf_sccp_optional_pointer, tvb, \
1865 offset, ptr_size, optional_pointer); \
1866 optional_pointer += offset; \
1867 if (ptr_size == POINTER_LENGTH_LONG) \
1868 optional_pointer += 1; \
1872 /* Extract the message type; all other processing is based on this */
1873 message_type = tvb_get_guint8(tvb, SCCP_MSG_TYPE_OFFSET);
1874 offset = SCCP_MSG_TYPE_LENGTH;
1876 if (check_col(pinfo->cinfo, COL_INFO)) {
1877 col_append_fstr(pinfo->cinfo, COL_INFO, "%s ",
1878 val_to_str(message_type, sccp_message_type_acro_values, "Unknown"));
1882 /* add the message type to the protocol tree */
1883 proto_tree_add_uint(sccp_tree, hf_sccp_message_type, tvb,
1884 SCCP_MSG_TYPE_OFFSET, SCCP_MSG_TYPE_LENGTH, message_type);
1888 /* Starting a new message dissection; clear the global assoc, SLR, and DLR values */
1893 no_assoc.calling_dpc = 0;
1894 no_assoc.called_dpc = 0;
1895 no_assoc.calling_ssn = INVALID_SSN;
1896 no_assoc.called_ssn = INVALID_SSN;
1897 no_assoc.has_fw_key = FALSE;
1898 no_assoc.has_bw_key = FALSE;
1899 no_assoc.payload = SCCP_PLOAD_NONE;
1900 no_assoc.called_party = NULL;
1901 no_assoc.calling_party = NULL;
1902 no_assoc.extra_info = NULL;
1904 switch(message_type) {
1905 case SCCP_MSG_TYPE_CR:
1906 /* TTC and NTT (Japan) say that the connection-oriented messages are
1907 * deleted (not standardized), but they appear to be used anyway, so
1908 * we'll dissect it...
1910 offset += dissect_sccp_parameter(tvb, pinfo, sccp_tree, tree,
1911 PARAMETER_SOURCE_LOCAL_REFERENCE,
1912 offset, SOURCE_LOCAL_REFERENCE_LENGTH);
1913 offset += dissect_sccp_parameter(tvb, pinfo, sccp_tree, tree,
1914 PARAMETER_CLASS, offset,
1915 PROTOCOL_CLASS_LENGTH);
1916 assoc = get_sccp_assoc(pinfo, msg_offset, slr, dlr, message_type);
1918 VARIABLE_POINTER(variable_pointer1, hf_sccp_variable_pointer1, POINTER_LENGTH)
1919 OPTIONAL_POINTER(POINTER_LENGTH)
1921 dissect_sccp_variable_parameter(tvb, pinfo, sccp_tree, tree,
1922 PARAMETER_CALLED_PARTY_ADDRESS,
1926 case SCCP_MSG_TYPE_CC:
1927 /* TODO: connection has been established; theoretically we could keep
1928 * keep track of the SLR/DLR with the called/calling from the CR and
1929 * track the connection (e.g., on subsequent messages regarding this
1930 * SLR we could set the global vars "call*_ssn" so data could get
1933 offset += dissect_sccp_parameter(tvb, pinfo, sccp_tree, tree,
1934 PARAMETER_DESTINATION_LOCAL_REFERENCE,
1936 DESTINATION_LOCAL_REFERENCE_LENGTH);
1937 offset += dissect_sccp_parameter(tvb, pinfo, sccp_tree, tree,
1938 PARAMETER_SOURCE_LOCAL_REFERENCE,
1939 offset, SOURCE_LOCAL_REFERENCE_LENGTH);
1941 assoc = get_sccp_assoc(pinfo, msg_offset, slr, dlr, message_type);
1943 offset += dissect_sccp_parameter(tvb, pinfo, sccp_tree, tree,
1944 PARAMETER_CLASS, offset,
1945 PROTOCOL_CLASS_LENGTH);
1946 OPTIONAL_POINTER(POINTER_LENGTH);
1949 case SCCP_MSG_TYPE_CREF:
1950 offset += dissect_sccp_parameter(tvb, pinfo, sccp_tree, tree,
1951 PARAMETER_DESTINATION_LOCAL_REFERENCE,
1953 DESTINATION_LOCAL_REFERENCE_LENGTH);
1955 assoc = get_sccp_assoc(pinfo, msg_offset, slr, dlr, message_type);
1957 offset += dissect_sccp_parameter(tvb, pinfo, sccp_tree, tree,
1958 PARAMETER_REFUSAL_CAUSE, offset,
1959 REFUSAL_CAUSE_LENGTH);
1960 OPTIONAL_POINTER(POINTER_LENGTH);
1963 case SCCP_MSG_TYPE_RLSD:
1964 offset += dissect_sccp_parameter(tvb, pinfo, sccp_tree, tree,
1965 PARAMETER_DESTINATION_LOCAL_REFERENCE,
1967 DESTINATION_LOCAL_REFERENCE_LENGTH);
1968 offset += dissect_sccp_parameter(tvb, pinfo, sccp_tree, tree,
1969 PARAMETER_SOURCE_LOCAL_REFERENCE,
1970 offset, SOURCE_LOCAL_REFERENCE_LENGTH);
1972 assoc = get_sccp_assoc(pinfo, msg_offset, slr, dlr, message_type);
1974 offset += dissect_sccp_parameter(tvb, pinfo, sccp_tree, tree,
1975 PARAMETER_RELEASE_CAUSE, offset,
1976 RELEASE_CAUSE_LENGTH);
1978 OPTIONAL_POINTER(POINTER_LENGTH);
1979 assoc = get_sccp_assoc(pinfo, msg_offset, slr, dlr, message_type);
1982 case SCCP_MSG_TYPE_RLC:
1983 offset += dissect_sccp_parameter(tvb, pinfo, sccp_tree, tree,
1984 PARAMETER_DESTINATION_LOCAL_REFERENCE,
1986 DESTINATION_LOCAL_REFERENCE_LENGTH);
1987 offset += dissect_sccp_parameter(tvb, pinfo, sccp_tree, tree,
1988 PARAMETER_SOURCE_LOCAL_REFERENCE,
1989 offset, SOURCE_LOCAL_REFERENCE_LENGTH);
1991 assoc = get_sccp_assoc(pinfo, msg_offset, slr, dlr, message_type);
1995 case SCCP_MSG_TYPE_DT1:
1996 source_local_ref = tvb_get_letoh24(tvb, offset);
1997 offset += dissect_sccp_parameter(tvb, pinfo, sccp_tree, tree,
1998 PARAMETER_DESTINATION_LOCAL_REFERENCE,
2000 DESTINATION_LOCAL_REFERENCE_LENGTH);
2002 assoc = get_sccp_assoc(pinfo, msg_offset, slr, dlr, message_type);
2004 more = tvb_get_guint8(tvb, offset) & SEGMENTING_REASSEMBLING_MASK;
2006 offset += dissect_sccp_parameter(tvb, pinfo, sccp_tree, tree,
2007 PARAMETER_SEGMENTING_REASSEMBLING,
2008 offset, SEGMENTING_REASSEMBLING_LENGTH);
2009 VARIABLE_POINTER(variable_pointer1, hf_sccp_variable_pointer1, POINTER_LENGTH)
2012 if (!sccp_xudt_desegment) {
2013 proto_tree_add_text(sccp_tree, tvb, variable_pointer1,
2014 tvb_get_guint8(tvb, variable_pointer1)+1,
2016 dissect_sccp_variable_parameter(tvb, pinfo, sccp_tree, tree,
2017 PARAMETER_DATA, variable_pointer1);
2020 save_fragmented = pinfo->fragmented;
2021 pinfo->fragmented = TRUE;
2022 frag_msg = fragment_add_seq_next(tvb, variable_pointer1 + 1, pinfo,
2023 source_local_ref, /* ID for fragments belonging together */
2024 sccp_xudt_msg_fragment_table, /* list of message fragments */
2025 sccp_xudt_msg_reassembled_table, /* list of reassembled messages */
2026 tvb_get_guint8(tvb,variable_pointer1),/* fragment length - to the end */
2027 more); /* More fragments? */
2029 new_tvb = process_reassembled_data(tvb, variable_pointer1 + 1, pinfo,
2030 "Reassembled Message", frag_msg,
2031 &sccp_xudt_msg_frag_items, NULL,
2034 if (frag_msg && frag_msg->next) { /* Reassembled */
2035 if (check_col(pinfo->cinfo, COL_INFO))
2036 col_append_str(pinfo->cinfo, COL_INFO,
2037 "(Message reassembled) ");
2038 } else if (more) { /* Not last packet of reassembled message */
2039 if (check_col(pinfo->cinfo, COL_INFO))
2040 col_append_str(pinfo->cinfo, COL_INFO, "(Message fragment) ");
2043 pinfo->fragmented = save_fragmented;
2046 dissect_sccp_data_param(new_tvb, pinfo, tree);
2049 /* End reassemble */
2052 case SCCP_MSG_TYPE_DT2:
2053 offset += dissect_sccp_parameter(tvb, pinfo, sccp_tree, tree,
2054 PARAMETER_DESTINATION_LOCAL_REFERENCE,
2056 DESTINATION_LOCAL_REFERENCE_LENGTH);
2058 assoc = get_sccp_assoc(pinfo, msg_offset, slr, dlr, message_type);
2060 offset += dissect_sccp_parameter(tvb, pinfo, sccp_tree, tree,
2061 PARAMETER_SEQUENCING_SEGMENTING, offset,
2062 SEQUENCING_SEGMENTING_LENGTH);
2065 case SCCP_MSG_TYPE_AK:
2066 offset += dissect_sccp_parameter(tvb, pinfo, sccp_tree, tree,
2067 PARAMETER_DESTINATION_LOCAL_REFERENCE,
2069 DESTINATION_LOCAL_REFERENCE_LENGTH);
2071 assoc = get_sccp_assoc(pinfo, msg_offset, slr, dlr, message_type);
2073 offset += dissect_sccp_parameter(tvb, pinfo, sccp_tree, tree,
2074 PARAMETER_RECEIVE_SEQUENCE_NUMBER,
2075 offset, RECEIVE_SEQUENCE_NUMBER_LENGTH);
2076 offset += dissect_sccp_parameter(tvb, pinfo, sccp_tree, tree,
2077 PARAMETER_CREDIT, offset, CREDIT_LENGTH);
2080 case SCCP_MSG_TYPE_UDT:
2081 pinfo->sccp_info = sccp_msg = new_ud_msg(pinfo,message_type);
2083 offset += dissect_sccp_parameter(tvb, pinfo, sccp_tree, tree,
2084 PARAMETER_CLASS, offset,
2085 PROTOCOL_CLASS_LENGTH);
2086 VARIABLE_POINTER(variable_pointer1, hf_sccp_variable_pointer1, POINTER_LENGTH)
2087 VARIABLE_POINTER(variable_pointer2, hf_sccp_variable_pointer2, POINTER_LENGTH)
2088 VARIABLE_POINTER(variable_pointer3, hf_sccp_variable_pointer3, POINTER_LENGTH)
2090 assoc = get_sccp_assoc(pinfo, msg_offset, slr, dlr, message_type);
2092 dissect_sccp_variable_parameter(tvb, pinfo, sccp_tree, tree,
2093 PARAMETER_CALLED_PARTY_ADDRESS,
2095 dissect_sccp_variable_parameter(tvb, pinfo, sccp_tree, tree,
2096 PARAMETER_CALLING_PARTY_ADDRESS,
2099 dissect_sccp_variable_parameter(tvb, pinfo, sccp_tree, tree, PARAMETER_DATA,
2103 case SCCP_MSG_TYPE_UDTS:
2104 pinfo->sccp_info = sccp_msg = new_ud_msg(pinfo,message_type);
2106 offset += dissect_sccp_parameter(tvb, pinfo, sccp_tree, tree,
2107 PARAMETER_RETURN_CAUSE, offset,
2108 RETURN_CAUSE_LENGTH);
2110 VARIABLE_POINTER(variable_pointer1, hf_sccp_variable_pointer1, POINTER_LENGTH)
2111 VARIABLE_POINTER(variable_pointer2, hf_sccp_variable_pointer2, POINTER_LENGTH)
2112 VARIABLE_POINTER(variable_pointer3, hf_sccp_variable_pointer3, POINTER_LENGTH)
2114 assoc = get_sccp_assoc(pinfo, msg_offset, slr, dlr, message_type);
2116 dissect_sccp_variable_parameter(tvb, pinfo, sccp_tree, tree,
2117 PARAMETER_CALLED_PARTY_ADDRESS,
2120 dissect_sccp_variable_parameter(tvb, pinfo, sccp_tree, tree,
2121 PARAMETER_CALLING_PARTY_ADDRESS,
2124 dissect_sccp_variable_parameter(tvb, pinfo, sccp_tree, tree, PARAMETER_DATA,
2128 case SCCP_MSG_TYPE_ED:
2129 offset += dissect_sccp_parameter(tvb, pinfo, sccp_tree, tree,
2130 PARAMETER_DESTINATION_LOCAL_REFERENCE,
2132 DESTINATION_LOCAL_REFERENCE_LENGTH);
2134 assoc = get_sccp_assoc(pinfo, msg_offset, slr, dlr, message_type);
2136 VARIABLE_POINTER(variable_pointer1, hf_sccp_variable_pointer1, POINTER_LENGTH);
2138 dissect_sccp_variable_parameter(tvb, pinfo, sccp_tree, tree, PARAMETER_DATA,
2142 case SCCP_MSG_TYPE_EA:
2143 offset += dissect_sccp_parameter(tvb, pinfo, sccp_tree, tree,
2144 PARAMETER_DESTINATION_LOCAL_REFERENCE,
2146 DESTINATION_LOCAL_REFERENCE_LENGTH);
2147 assoc = get_sccp_assoc(pinfo, msg_offset, slr, dlr, message_type);
2151 case SCCP_MSG_TYPE_RSR:
2152 offset += dissect_sccp_parameter(tvb, pinfo, sccp_tree, tree,
2153 PARAMETER_DESTINATION_LOCAL_REFERENCE,
2155 DESTINATION_LOCAL_REFERENCE_LENGTH);
2156 offset += dissect_sccp_parameter(tvb, pinfo, sccp_tree, tree,
2157 PARAMETER_SOURCE_LOCAL_REFERENCE,
2158 offset, SOURCE_LOCAL_REFERENCE_LENGTH);
2159 offset += dissect_sccp_parameter(tvb, pinfo, sccp_tree, tree,
2160 PARAMETER_RESET_CAUSE, offset,
2161 RESET_CAUSE_LENGTH);
2162 assoc = get_sccp_assoc(pinfo, msg_offset, slr, dlr, message_type);
2165 case SCCP_MSG_TYPE_RSC:
2166 offset += dissect_sccp_parameter(tvb, pinfo, sccp_tree, tree,
2167 PARAMETER_DESTINATION_LOCAL_REFERENCE,
2169 DESTINATION_LOCAL_REFERENCE_LENGTH);
2170 offset += dissect_sccp_parameter(tvb, pinfo, sccp_tree, tree,
2171 PARAMETER_SOURCE_LOCAL_REFERENCE,
2172 offset, SOURCE_LOCAL_REFERENCE_LENGTH);
2173 assoc = get_sccp_assoc(pinfo, msg_offset, slr, dlr, message_type);
2176 case SCCP_MSG_TYPE_ERR:
2177 offset += dissect_sccp_parameter(tvb, pinfo, sccp_tree, tree,
2178 PARAMETER_DESTINATION_LOCAL_REFERENCE,
2180 DESTINATION_LOCAL_REFERENCE_LENGTH);
2181 offset += dissect_sccp_parameter(tvb, pinfo, sccp_tree, tree,
2182 PARAMETER_ERROR_CAUSE, offset,
2183 ERROR_CAUSE_LENGTH);
2184 assoc = get_sccp_assoc(pinfo, msg_offset, slr, dlr, message_type);
2187 case SCCP_MSG_TYPE_IT:
2188 offset += dissect_sccp_parameter(tvb, pinfo, sccp_tree, tree,
2189 PARAMETER_DESTINATION_LOCAL_REFERENCE,
2191 DESTINATION_LOCAL_REFERENCE_LENGTH);
2192 offset += dissect_sccp_parameter(tvb, pinfo, sccp_tree, tree,
2193 PARAMETER_SOURCE_LOCAL_REFERENCE,
2194 offset, SOURCE_LOCAL_REFERENCE_LENGTH);
2195 assoc = get_sccp_assoc(pinfo, msg_offset, slr, dlr, message_type);
2196 offset += dissect_sccp_parameter(tvb, pinfo, sccp_tree, tree,
2197 PARAMETER_CLASS, offset,
2198 PROTOCOL_CLASS_LENGTH);
2199 offset += dissect_sccp_parameter(tvb, pinfo, sccp_tree, tree,
2200 PARAMETER_SEQUENCING_SEGMENTING,
2201 offset, SEQUENCING_SEGMENTING_LENGTH);
2202 offset += dissect_sccp_parameter(tvb, pinfo, sccp_tree, tree,
2203 PARAMETER_CREDIT, offset, CREDIT_LENGTH);
2206 case SCCP_MSG_TYPE_XUDT:
2207 pinfo->sccp_info = sccp_msg = new_ud_msg(pinfo,message_type);
2208 offset += dissect_sccp_parameter(tvb, pinfo, sccp_tree, tree,
2209 PARAMETER_CLASS, offset,
2210 PROTOCOL_CLASS_LENGTH);
2211 offset += dissect_sccp_parameter(tvb, pinfo, sccp_tree, tree,
2212 PARAMETER_HOP_COUNTER, offset,
2213 HOP_COUNTER_LENGTH);
2215 VARIABLE_POINTER(variable_pointer1, hf_sccp_variable_pointer1, POINTER_LENGTH)
2216 VARIABLE_POINTER(variable_pointer2, hf_sccp_variable_pointer2, POINTER_LENGTH)
2217 VARIABLE_POINTER(variable_pointer3, hf_sccp_variable_pointer3, POINTER_LENGTH)
2218 OPTIONAL_POINTER(POINTER_LENGTH)
2220 /* Optional parameters are Segmentation and Importance
2221 * NOTE 2 - Segmentation Should not be present in case of a single XUDT
2225 assoc = get_sccp_assoc(pinfo, msg_offset, slr, dlr, message_type);
2227 dissect_sccp_variable_parameter(tvb, pinfo, sccp_tree, tree,
2228 PARAMETER_CALLED_PARTY_ADDRESS,
2230 dissect_sccp_variable_parameter(tvb, pinfo, sccp_tree, tree,
2231 PARAMETER_CALLING_PARTY_ADDRESS,
2234 if ((parameter_type = tvb_get_guint8(tvb, optional_pointer)) == PARAMETER_SEGMENTATION){
2235 if (!sccp_xudt_desegment){
2236 proto_tree_add_text(sccp_tree, tvb, variable_pointer3, tvb_get_guint8(tvb, variable_pointer3)+1, "Segmented Data" );
2240 gboolean more_frag = TRUE;
2243 /* Get the first octet of parameter Segmentation, Ch 3.17 in Q.713
2244 * Bit 8 of octet 1 is used for First segment indication
2245 * Bit 7 of octet 1 is used to keep in the message in sequence
2246 * delivery option required by the SCCP user
2247 * Bits 6 and 5 in octet 1 are spare bits.
2248 * Bits 4-1 of octet 1 are used to indicate the number of
2249 * remaining segments.
2250 * The values 0000 to 1111 are possible; the value 0000 indicates
2253 octet = tvb_get_guint8(tvb,optional_pointer+2);
2254 source_local_ref = tvb_get_letoh24(tvb, optional_pointer+3);
2256 if ((octet&0x0f) == 0)
2259 save_fragmented = pinfo->fragmented;
2260 pinfo->fragmented = TRUE;
2261 frag_msg = fragment_add_seq_next(tvb, variable_pointer3 + 1, pinfo,
2262 source_local_ref, /* ID for fragments belonging together */
2263 sccp_xudt_msg_fragment_table, /* list of message fragments */
2264 sccp_xudt_msg_reassembled_table, /* list of reassembled messages */
2265 tvb_get_guint8(tvb,variable_pointer3), /* fragment length - to the end */
2266 more_frag); /* More fragments? */
2268 if ((octet&0x80) == 0x80) /*First segment, set number of segments*/
2269 fragment_set_tot_len(pinfo, source_local_ref, sccp_xudt_msg_fragment_table,(octet & 0xf));
2271 new_tvb = process_reassembled_data(tvb, variable_pointer3 + 1,
2272 pinfo, "Reassembled Message",
2274 &sccp_xudt_msg_frag_items,
2277 if (frag_msg) { /* Reassembled */
2278 if (check_col(pinfo->cinfo, COL_INFO))
2279 col_append_str(pinfo->cinfo, COL_INFO,
2280 "(Message reassembled) ");
2281 } else { /* Not last packet of reassembled message */
2282 if (check_col(pinfo->cinfo, COL_INFO))
2283 col_append_str(pinfo->cinfo, COL_INFO,
2284 "(Message fragment) ");
2287 pinfo->fragmented = save_fragmented;
2290 dissect_sccp_data_param(new_tvb, pinfo, tree);
2293 dissect_sccp_variable_parameter(tvb, pinfo, sccp_tree, tree,
2294 PARAMETER_DATA, variable_pointer3);
2298 case SCCP_MSG_TYPE_XUDTS:
2299 pinfo->sccp_info = sccp_msg = new_ud_msg(pinfo,message_type);
2300 offset += dissect_sccp_parameter(tvb, pinfo, sccp_tree, tree,
2301 PARAMETER_RETURN_CAUSE, offset,
2302 RETURN_CAUSE_LENGTH);
2303 offset += dissect_sccp_parameter(tvb, pinfo, sccp_tree, tree,
2304 PARAMETER_HOP_COUNTER, offset,
2305 HOP_COUNTER_LENGTH);
2307 VARIABLE_POINTER(variable_pointer1, hf_sccp_variable_pointer1, POINTER_LENGTH)
2308 VARIABLE_POINTER(variable_pointer2, hf_sccp_variable_pointer2, POINTER_LENGTH)
2309 VARIABLE_POINTER(variable_pointer3, hf_sccp_variable_pointer3, POINTER_LENGTH)
2310 OPTIONAL_POINTER(POINTER_LENGTH)
2312 assoc = get_sccp_assoc(pinfo, msg_offset, slr, dlr, message_type);
2314 dissect_sccp_variable_parameter(tvb, pinfo, sccp_tree, tree,
2315 PARAMETER_CALLED_PARTY_ADDRESS,
2317 dissect_sccp_variable_parameter(tvb, pinfo, sccp_tree, tree,
2318 PARAMETER_CALLING_PARTY_ADDRESS,
2320 dissect_sccp_variable_parameter(tvb, pinfo, sccp_tree, tree, PARAMETER_DATA,
2324 case SCCP_MSG_TYPE_LUDT:
2325 pinfo->sccp_info = sccp_msg = new_ud_msg(pinfo,message_type);
2326 if (decode_mtp3_standard != ANSI_STANDARD)
2328 offset += dissect_sccp_parameter(tvb, pinfo, sccp_tree, tree,
2329 PARAMETER_CLASS, offset,
2330 PROTOCOL_CLASS_LENGTH);
2331 offset += dissect_sccp_parameter(tvb, pinfo, sccp_tree, tree,
2332 PARAMETER_HOP_COUNTER, offset,
2333 HOP_COUNTER_LENGTH);
2335 VARIABLE_POINTER(variable_pointer1, hf_sccp_variable_pointer1, POINTER_LENGTH_LONG)
2336 VARIABLE_POINTER(variable_pointer2, hf_sccp_variable_pointer2, POINTER_LENGTH_LONG)
2337 VARIABLE_POINTER(variable_pointer3, hf_sccp_variable_pointer3, POINTER_LENGTH_LONG)
2338 OPTIONAL_POINTER(POINTER_LENGTH_LONG)
2340 assoc = get_sccp_assoc(pinfo, msg_offset, slr, dlr, message_type);
2342 dissect_sccp_variable_parameter(tvb, pinfo, sccp_tree, tree,
2343 PARAMETER_CALLED_PARTY_ADDRESS,
2345 dissect_sccp_variable_parameter(tvb, pinfo, sccp_tree, tree,
2346 PARAMETER_CALLING_PARTY_ADDRESS,
2348 dissect_sccp_variable_parameter(tvb, pinfo, sccp_tree, tree,
2349 PARAMETER_LONG_DATA, variable_pointer3);
2351 dissect_sccp_unknown_message(tvb, sccp_tree);
2354 case SCCP_MSG_TYPE_LUDTS:
2355 pinfo->sccp_info = sccp_msg = new_ud_msg(pinfo,message_type);
2356 if (decode_mtp3_standard != ANSI_STANDARD)
2358 offset += dissect_sccp_parameter(tvb, pinfo, sccp_tree, tree,
2359 PARAMETER_RETURN_CAUSE, offset,
2360 RETURN_CAUSE_LENGTH);
2361 offset += dissect_sccp_parameter(tvb, pinfo, sccp_tree, tree,
2362 PARAMETER_HOP_COUNTER, offset,
2363 HOP_COUNTER_LENGTH);
2365 VARIABLE_POINTER(variable_pointer1, hf_sccp_variable_pointer1, POINTER_LENGTH_LONG)
2366 VARIABLE_POINTER(variable_pointer2, hf_sccp_variable_pointer2, POINTER_LENGTH_LONG)
2367 VARIABLE_POINTER(variable_pointer3, hf_sccp_variable_pointer3, POINTER_LENGTH_LONG)
2368 OPTIONAL_POINTER(POINTER_LENGTH_LONG)
2370 assoc = get_sccp_assoc(pinfo, msg_offset, slr, dlr, message_type);
2372 dissect_sccp_variable_parameter(tvb, pinfo, sccp_tree, tree,
2373 PARAMETER_CALLED_PARTY_ADDRESS,
2375 dissect_sccp_variable_parameter(tvb, pinfo, sccp_tree, tree,
2376 PARAMETER_CALLING_PARTY_ADDRESS,
2378 dissect_sccp_variable_parameter(tvb, pinfo, sccp_tree, tree,
2379 PARAMETER_LONG_DATA, variable_pointer3);
2381 dissect_sccp_unknown_message(tvb, sccp_tree);
2385 dissect_sccp_unknown_message(tvb, sccp_tree);
2389 dissect_sccp_optional_parameters(tvb, pinfo, sccp_tree, tree,
2392 if (trace_sccp && assoc && assoc != &no_assoc) {
2393 proto_item* pi = proto_tree_add_uint(sccp_tree,hf_sccp_assoc_id,tvb,0,0,assoc->id);
2394 proto_tree* pt = proto_item_add_subtree(pi,ett_sccp_assoc);
2395 PROTO_ITEM_SET_GENERATED(pi);
2398 for(m = assoc->msgs; m ; m = m->data.co.next) {
2399 pi = proto_tree_add_uint( pt,hf_sccp_assoc_msg,tvb,0,0,m->framenum);
2401 if (assoc->payload != SCCP_PLOAD_NONE)
2402 proto_item_append_text(pi," %s", val_to_str(assoc->payload, assoc_protos, "Unknown"));
2404 if (m->data.co.label)
2405 proto_item_append_text(pi," %s", m->data.co.label);
2407 if (m->framenum == pinfo->fd->num && m->offset == msg_offset ) {
2408 tap_queue_packet(sccp_tap, pinfo, m);
2409 proto_item_append_text(pi," (current)");
2411 PROTO_ITEM_SET_GENERATED(pi);
2419 dissect_sccp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
2421 proto_item *sccp_item = NULL;
2422 proto_tree *sccp_tree = NULL;
2423 const mtp3_addr_pc_t *mtp3_addr_p;
2425 if ((pinfo->src.type == AT_SS7PC) &&
2426 ((mtp3_addr_p = (const mtp3_addr_pc_t *)pinfo->src.data)->type <= CHINESE_ITU_STANDARD))
2429 * Allow a protocol beneath to specify how the SCCP layer should be
2432 * It is possible to have multiple sets of SCCP traffic some of which is
2433 * ITU and some of which is ANSI.
2434 * An example is A-interface traffic having ANSI MTP3/ANSI SCCP/3GPP2 IOS
2435 * and at the same time ITU MTP3/ITU SCCP/ANSI TCAP/ANSI MAP.
2437 decode_mtp3_standard = mtp3_addr_p->type;
2441 decode_mtp3_standard = mtp3_standard;
2444 /* Make entry in the Protocol column on summary display */
2445 if (check_col(pinfo->cinfo, COL_PROTOCOL))
2446 switch(decode_mtp3_standard) {
2448 col_set_str(pinfo->cinfo, COL_PROTOCOL, "SCCP (Int. ITU)");
2451 col_set_str(pinfo->cinfo, COL_PROTOCOL, "SCCP (ANSI)");
2453 case CHINESE_ITU_STANDARD:
2454 col_set_str(pinfo->cinfo, COL_PROTOCOL, "SCCP (Chin. ITU)");
2456 case JAPAN_STANDARD:
2457 col_set_str(pinfo->cinfo, COL_PROTOCOL, "SCCP (Japan)");
2461 /* In the interest of speed, if "tree" is NULL, don't do any work not
2462 necessary to generate protocol tree items. */
2464 /* create the sccp protocol tree */
2465 sccp_item = proto_tree_add_item(tree, proto_sccp, tvb, 0, -1, FALSE);
2466 sccp_tree = proto_item_add_subtree(sccp_item, ett_sccp);
2469 /* Set whether message is UPLINK, DOWNLINK, or of UNKNOWN direction */
2471 if (pinfo->src.type == AT_SS7PC)
2474 * XXX - we assume that the "data" pointers of the source and destination
2475 * addresses are set to point to "mtp3_addr_pc_t" structures, so that
2476 * we can safely cast them.
2478 mtp3_addr_p = (const mtp3_addr_pc_t *)pinfo->src.data;
2480 if (sccp_source_pc_global == mtp3_addr_p->pc)
2482 pinfo->p2p_dir = P2P_DIR_SENT;
2486 /* assuming if src was SS7 PC then dst will be too */
2487 mtp3_addr_p = (const mtp3_addr_pc_t *)pinfo->dst.data;
2489 if (sccp_source_pc_global == mtp3_addr_p->pc)
2491 pinfo->p2p_dir = P2P_DIR_RECV;
2495 pinfo->p2p_dir = P2P_DIR_UNKNOWN;
2500 /* dissect the message */
2501 dissect_sccp_message(tvb, pinfo, sccp_tree, tree);
2505 static void init_sccp(void) {
2507 fragment_table_init (&sccp_xudt_msg_fragment_table);
2508 reassembled_table_init(&sccp_xudt_msg_reassembled_table);
2512 /* Register the protocol with Wireshark */
2514 proto_register_sccp(void)
2516 /* Setup list of header fields */
2517 static hf_register_info hf[] = {
2518 { &hf_sccp_message_type,
2519 { "Message Type", "sccp.message_type",
2520 FT_UINT8, BASE_HEX, VALS(sccp_message_type_values), 0x0,
2522 { &hf_sccp_variable_pointer1,
2523 { "Pointer to first Mandatory Variable parameter", "sccp.variable_pointer1",
2524 FT_UINT16, BASE_DEC, NULL, 0x0,
2526 { &hf_sccp_variable_pointer2,
2527 { "Pointer to second Mandatory Variable parameter", "sccp.variable_pointer2",
2528 FT_UINT16, BASE_DEC, NULL, 0x0,
2530 { &hf_sccp_variable_pointer3,
2531 { "Pointer to third Mandatory Variable parameter", "sccp.variable_pointer3",
2532 FT_UINT16, BASE_DEC, NULL, 0x0,
2534 { &hf_sccp_optional_pointer,
2535 { "Pointer to Optional parameter", "sccp.optional_pointer",
2536 FT_UINT16, BASE_DEC, NULL, 0x0,
2539 { "Called or Calling SubSystem Number", "sccp.ssn",
2540 FT_UINT8, BASE_DEC, VALS(sccp_ssn_values), 0x0,
2542 { &hf_sccp_gt_digits,
2543 { "Called or Calling GT Digits",
2545 FT_STRING, BASE_NONE, NULL, 0x0,
2547 { &hf_sccp_called_national_indicator,
2548 { "National Indicator", "sccp.called.ni",
2549 FT_UINT8, BASE_HEX, VALS(sccp_national_indicator_values), ANSI_NATIONAL_MASK,
2551 { &hf_sccp_called_routing_indicator,
2552 { "Routing Indicator", "sccp.called.ri",
2553 FT_UINT8, BASE_HEX, VALS(sccp_routing_indicator_values), ROUTING_INDICATOR_MASK,
2555 { &hf_sccp_called_itu_global_title_indicator,
2556 { "Global Title Indicator", "sccp.called.gti",
2557 FT_UINT8, BASE_HEX, VALS(sccp_itu_global_title_indicator_values), GTI_MASK,
2559 { &hf_sccp_called_ansi_global_title_indicator,
2560 { "Global Title Indicator", "sccp.called.gti",
2561 FT_UINT8, BASE_HEX, VALS(sccp_ansi_global_title_indicator_values), GTI_MASK,
2563 { &hf_sccp_called_itu_ssn_indicator,
2564 { "SubSystem Number Indicator", "sccp.called.ssni",
2565 FT_UINT8, BASE_HEX, VALS(sccp_ai_ssni_values), ITU_SSN_INDICATOR_MASK,
2567 { &hf_sccp_called_itu_point_code_indicator,
2568 { "Point Code Indicator", "sccp.called.pci",
2569 FT_UINT8, BASE_HEX, VALS(sccp_ai_pci_values), ITU_PC_INDICATOR_MASK,
2571 { &hf_sccp_called_ansi_ssn_indicator,
2572 { "SubSystem Number Indicator", "sccp.called.ssni",
2573 FT_UINT8, BASE_HEX, VALS(sccp_ai_ssni_values), ANSI_SSN_INDICATOR_MASK,
2575 { &hf_sccp_called_ansi_point_code_indicator,
2576 { "Point Code Indicator", "sccp.called.pci",
2577 FT_UINT8, BASE_HEX, VALS(sccp_ai_pci_values), ANSI_PC_INDICATOR_MASK,
2579 { &hf_sccp_called_ssn,
2580 { "SubSystem Number", "sccp.called.ssn",
2581 FT_UINT8, BASE_DEC, VALS(sccp_ssn_values), 0x0,
2583 { &hf_sccp_called_itu_pc,
2584 { "PC", "sccp.called.pc",
2585 FT_UINT16, BASE_DEC, NULL, ITU_PC_MASK,
2587 { &hf_sccp_called_ansi_pc,
2588 { "PC", "sccp.called.ansi_pc",
2589 FT_STRING, BASE_NONE, NULL, 0x0,
2591 { &hf_sccp_called_chinese_pc,
2592 { "PC", "sccp.called.chinese_pc",
2593 FT_STRING, BASE_NONE, NULL, 0x0,
2595 { &hf_sccp_called_japan_pc,
2596 { "PC", "sccp.called.pc",
2597 FT_UINT16, BASE_DEC, NULL, 0x0,
2599 { &hf_sccp_called_pc_network,
2601 "sccp.called.network",
2602 FT_UINT24, BASE_DEC, NULL, ANSI_NETWORK_MASK,
2604 { &hf_sccp_called_pc_cluster,
2606 "sccp.called.cluster",
2607 FT_UINT24, BASE_DEC, NULL, ANSI_CLUSTER_MASK,
2609 { &hf_sccp_called_pc_member,
2611 "sccp.called.member",
2612 FT_UINT24, BASE_DEC, NULL, ANSI_MEMBER_MASK,
2614 { &hf_sccp_called_gt_nai,
2615 { "Nature of Address Indicator",
2617 FT_UINT8, BASE_HEX, VALS(sccp_nai_values), GT_NAI_MASK,
2619 { &hf_sccp_called_gt_oe,
2620 { "Odd/Even Indicator",
2622 FT_UINT8, BASE_HEX, VALS(sccp_oe_values), GT_OE_MASK,
2624 { &hf_sccp_called_gt_tt,
2625 { "Translation Type",
2627 FT_UINT8, BASE_HEX, NULL, 0x0,
2629 { &hf_sccp_called_gt_np,
2632 FT_UINT8, BASE_HEX, VALS(sccp_np_values), GT_NP_MASK,
2634 { &hf_sccp_called_gt_es,
2635 { "Encoding Scheme",
2637 FT_UINT8, BASE_HEX, VALS(sccp_es_values), GT_ES_MASK,
2639 { &hf_sccp_called_gt_digits,
2641 "sccp.called.digits",
2642 FT_STRING, BASE_NONE, NULL, 0x0,
2644 { &hf_sccp_calling_national_indicator,
2645 { "National Indicator", "sccp.calling.ni",
2646 FT_UINT8, BASE_HEX, VALS(sccp_national_indicator_values), ANSI_NATIONAL_MASK,
2648 { &hf_sccp_calling_routing_indicator,
2649 { "Routing Indicator", "sccp.calling.ri",
2650 FT_UINT8, BASE_HEX, VALS(sccp_routing_indicator_values), ROUTING_INDICATOR_MASK,
2652 { &hf_sccp_calling_itu_global_title_indicator,
2653 { "Global Title Indicator", "sccp.calling.gti",
2654 FT_UINT8, BASE_HEX, VALS(sccp_itu_global_title_indicator_values), GTI_MASK,
2656 { &hf_sccp_calling_ansi_global_title_indicator,
2657 { "Global Title Indicator", "sccp.calling.gti",
2658 FT_UINT8, BASE_HEX, VALS(sccp_ansi_global_title_indicator_values), GTI_MASK,
2660 { &hf_sccp_calling_itu_ssn_indicator,
2661 { "SubSystem Number Indicator", "sccp.calling.ssni",
2662 FT_UINT8, BASE_HEX, VALS(sccp_ai_ssni_values), ITU_SSN_INDICATOR_MASK,
2664 { &hf_sccp_calling_itu_point_code_indicator,
2665 { "Point Code Indicator", "sccp.calling.pci",
2666 FT_UINT8, BASE_HEX, VALS(sccp_ai_pci_values), ITU_PC_INDICATOR_MASK,
2668 { &hf_sccp_calling_ansi_ssn_indicator,
2669 { "SubSystem Number Indicator", "sccp.calling.ssni",
2670 FT_UINT8, BASE_HEX, VALS(sccp_ai_ssni_values), ANSI_SSN_INDICATOR_MASK,
2672 { &hf_sccp_calling_ansi_point_code_indicator,
2673 { "Point Code Indicator", "sccp.calling.pci",
2674 FT_UINT8, BASE_HEX, VALS(sccp_ai_pci_values), ANSI_PC_INDICATOR_MASK,
2676 { &hf_sccp_calling_ssn,
2677 { "SubSystem Number", "sccp.calling.ssn",
2678 FT_UINT8, BASE_DEC, VALS(sccp_ssn_values), 0x0,
2680 { &hf_sccp_calling_itu_pc,
2681 { "PC", "sccp.calling.pc",
2682 FT_UINT16, BASE_DEC, NULL, ITU_PC_MASK,
2684 { &hf_sccp_calling_ansi_pc,
2685 { "PC", "sccp.calling.ansi_pc",
2686 FT_STRING, BASE_NONE, NULL, 0x0,
2688 { &hf_sccp_calling_chinese_pc,
2689 { "PC", "sccp.calling.chinese_pc",
2690 FT_STRING, BASE_NONE, NULL, 0x0,
2692 { &hf_sccp_calling_japan_pc,
2693 { "PC", "sccp.calling.pc",
2694 FT_UINT16, BASE_DEC, NULL, 0x0,
2696 { &hf_sccp_calling_pc_network,
2698 "sccp.calling.network",
2699 FT_UINT24, BASE_DEC, NULL, ANSI_NETWORK_MASK,
2701 { &hf_sccp_calling_pc_cluster,
2703 "sccp.calling.cluster",
2704 FT_UINT24, BASE_DEC, NULL, ANSI_CLUSTER_MASK,
2706 { &hf_sccp_calling_pc_member,
2708 "sccp.calling.member",
2709 FT_UINT24, BASE_DEC, NULL, ANSI_MEMBER_MASK,
2711 { &hf_sccp_calling_gt_nai,
2712 { "Nature of Address Indicator",
2714 FT_UINT8, BASE_HEX, VALS(sccp_nai_values), GT_NAI_MASK,
2716 { &hf_sccp_calling_gt_oe,
2717 { "Odd/Even Indicator",
2719 FT_UINT8, BASE_HEX, VALS(sccp_oe_values), GT_OE_MASK,
2721 { &hf_sccp_calling_gt_tt,
2722 { "Translation Type",
2724 FT_UINT8, BASE_HEX, NULL, 0x0,
2726 { &hf_sccp_calling_gt_np,
2729 FT_UINT8, BASE_HEX, VALS(sccp_np_values), GT_NP_MASK,
2731 { &hf_sccp_calling_gt_es,
2732 { "Encoding Scheme",
2734 FT_UINT8, BASE_HEX, VALS(sccp_es_values), GT_ES_MASK,
2736 { &hf_sccp_calling_gt_digits,
2738 "sccp.calling.digits",
2739 FT_STRING, BASE_NONE, NULL, 0x0,
2742 { "Destination Local Reference", "sccp.dlr",
2743 FT_UINT24, BASE_HEX, NULL, 0x0,
2746 { "Source Local Reference", "sccp.slr",
2747 FT_UINT24, BASE_HEX, NULL, 0x0,
2750 { "Local Reference", "sccp.lr",
2751 FT_UINT24, BASE_HEX, NULL, 0x0,
2754 { "Class", "sccp.class",
2755 FT_UINT8, BASE_HEX, NULL, CLASS_CLASS_MASK,
2757 { &hf_sccp_handling,
2758 { "Message handling", "sccp.handling",
2759 FT_UINT8, BASE_HEX, VALS(sccp_class_handling_values), CLASS_SPARE_HANDLING_MASK,
2762 { "More data", "sccp.more",
2763 FT_UINT8, BASE_HEX, VALS(sccp_segmenting_reassembling_values), SEGMENTING_REASSEMBLING_MASK,
2766 { "Receive Sequence Number", "sccp.rsn",
2767 FT_UINT8, BASE_HEX, NULL, RSN_MASK,
2769 { &hf_sccp_sequencing_segmenting_ssn,
2770 { "Sequencing Segmenting: Send Sequence Number", "sccp.sequencing_segmenting.ssn",
2771 FT_UINT8, BASE_HEX, NULL, SEND_SEQUENCE_NUMBER_MASK,
2773 { &hf_sccp_sequencing_segmenting_rsn,
2774 { "Sequencing Segmenting: Receive Sequence Number", "sccp.sequencing_segmenting.rsn",
2775 FT_UINT8, BASE_HEX, NULL, RECEIVE_SEQUENCE_NUMBER_MASK,
2777 { &hf_sccp_sequencing_segmenting_more,
2778 { "Sequencing Segmenting: More", "sccp.sequencing_segmenting.more",
2779 FT_UINT8, BASE_HEX, VALS(sccp_segmenting_reassembling_values), SEQUENCING_SEGMENTING_MORE_MASK,
2782 { "Credit", "sccp.credit",
2783 FT_UINT8, BASE_HEX, NULL, 0x0,
2785 { &hf_sccp_release_cause,
2786 { "Release Cause", "sccp.release_cause",
2787 FT_UINT8, BASE_HEX, VALS(sccp_release_cause_values), 0x0,
2789 { &hf_sccp_return_cause,
2790 { "Return Cause", "sccp.return_cause",
2791 FT_UINT8, BASE_HEX, VALS(sccp_return_cause_values), 0x0,
2793 { &hf_sccp_reset_cause,
2794 { "Reset Cause", "sccp.reset_cause",
2795 FT_UINT8, BASE_HEX, VALS(sccp_reset_cause_values), 0x0,
2797 { &hf_sccp_error_cause,
2798 { "Error Cause", "sccp.error_cause",
2799 FT_UINT8, BASE_HEX, VALS(sccp_error_cause_values), 0x0,
2801 { &hf_sccp_refusal_cause,
2802 { "Refusal Cause", "sccp.refusal_cause",
2803 FT_UINT8, BASE_HEX, VALS(sccp_refusal_cause_values), 0x0,
2805 { &hf_sccp_segmentation_first,
2806 { "Segmentation: First", "sccp.segmentation.first",
2807 FT_UINT8, BASE_HEX, VALS(sccp_segmentation_first_segment_values), SEGMENTATION_FIRST_SEGMENT_MASK,
2809 { &hf_sccp_segmentation_class,
2810 { "Segmentation: Class", "sccp.segmentation.class",
2811 FT_UINT8, BASE_HEX, VALS(sccp_segmentation_class_values), SEGMENTATION_CLASS_MASK,
2813 { &hf_sccp_segmentation_remaining,
2814 { "Segmentation: Remaining", "sccp.segmentation.remaining",
2815 FT_UINT8, BASE_HEX, NULL, SEGMENTATION_REMAINING_MASK,
2817 { &hf_sccp_segmentation_slr,
2818 { "Segmentation: Source Local Reference", "sccp.segmentation.slr",
2819 FT_UINT24, BASE_HEX, NULL, 0x0,
2821 { &hf_sccp_hop_counter,
2822 { "Hop Counter", "sccp.hops",
2823 FT_UINT8, BASE_HEX, NULL, 0x0,
2825 { &hf_sccp_importance,
2826 { "Importance", "sccp.importance",
2827 FT_UINT8, BASE_HEX, NULL, IMPORTANCE_IMPORTANCE_MASK,
2829 /* ISNI is ANSI only */
2830 { &hf_sccp_ansi_isni_mi,
2831 { "ISNI Mark for Identification Indicator", "sccp.isni.mi",
2832 FT_UINT8, BASE_HEX, VALS(sccp_isni_mark_for_id_values), ANSI_ISNI_MI_MASK,
2834 { &hf_sccp_ansi_isni_iri,
2835 { "ISNI Routing Indicator", "sccp.isni.iri",
2836 FT_UINT8, BASE_HEX, VALS(sccp_isni_iri_values), ANSI_ISNI_IRI_MASK,
2838 { &hf_sccp_ansi_isni_ti,
2839 { "ISNI Type Indicator", "sccp.isni.ti",
2840 FT_UINT8, BASE_HEX, VALS(sccp_isni_ti_values), ANSI_ISNI_TI_MASK,
2842 { &hf_sccp_ansi_isni_netspec,
2843 { "ISNI Network Specific (Type 1)", "sccp.isni.netspec",
2844 FT_UINT8, BASE_HEX, NULL, ANSI_ISNI_NETSPEC_MASK,
2846 { &hf_sccp_ansi_isni_counter,
2847 { "ISNI Counter", "sccp.isni.counter",
2848 FT_UINT8, BASE_HEX, NULL, ANSI_ISNI_COUNTER_MASK,
2850 {&hf_sccp_xudt_msg_fragments,
2851 {"Message fragments", "sccp.msg.fragments",
2852 FT_NONE, BASE_NONE, NULL, 0x00, NULL, HFILL }
2854 {&hf_sccp_xudt_msg_fragment,
2855 {"Message fragment", "sccp.msg.fragment",
2856 FT_FRAMENUM, BASE_NONE, NULL, 0x00, NULL, HFILL }
2858 {&hf_sccp_xudt_msg_fragment_overlap,
2859 {"Message fragment overlap", "sccp.msg.fragment.overlap",
2860 FT_BOOLEAN, BASE_NONE, NULL, 0x00, NULL, HFILL }
2862 {&hf_sccp_xudt_msg_fragment_overlap_conflicts,
2863 {"Message fragment overlapping with conflicting data", "sccp.msg.fragment.overlap.conflicts",
2864 FT_BOOLEAN, BASE_NONE, NULL, 0x00, NULL, HFILL }
2866 {&hf_sccp_xudt_msg_fragment_multiple_tails,
2867 {"Message has multiple tail fragments", "sccp.msg.fragment.multiple_tails",
2868 FT_BOOLEAN, BASE_NONE, NULL, 0x00, NULL, HFILL }
2870 {&hf_sccp_xudt_msg_fragment_too_long_fragment,
2871 {"Message fragment too long", "sccp.msg.fragment.too_long_fragment",
2872 FT_BOOLEAN, BASE_NONE, NULL, 0x00, NULL, HFILL }
2874 {&hf_sccp_xudt_msg_fragment_error,
2875 {"Message defragmentation error", "sccp.msg.fragment.error",
2876 FT_FRAMENUM, BASE_NONE, NULL, 0x00, NULL, HFILL }
2878 {&hf_sccp_xudt_msg_reassembled_in,
2879 {"Reassembled in", "sccp.msg.reassembled.in",
2880 FT_FRAMENUM, BASE_NONE, NULL, 0x00, NULL, HFILL }
2882 { &hf_sccp_assoc_id,
2883 { "Association ID", "sccp.assoc.id",
2884 FT_UINT32, BASE_DEC, NULL, 0x0, "", HFILL}},
2885 {&hf_sccp_assoc_msg,
2886 {"Message in frame", "sccp.assoc.msg",
2887 FT_FRAMENUM, BASE_NONE, NULL, 0x00, "", HFILL }
2892 /* Setup protocol subtree array */
2893 static gint *ett[] = {
2896 &ett_sccp_called_ai,
2897 &ett_sccp_called_pc,
2898 &ett_sccp_called_gt,
2900 &ett_sccp_calling_ai,
2901 &ett_sccp_calling_pc,
2902 &ett_sccp_calling_gt,
2903 &ett_sccp_sequencing_segmenting,
2904 &ett_sccp_segmentation,
2905 &ett_sccp_ansi_isni_routing_control,
2906 &ett_sccp_xudt_msg_fragment,
2907 &ett_sccp_xudt_msg_fragments,
2911 /* Register the protocol name and description */
2912 proto_sccp = proto_register_protocol("Signalling Connection Control Part",
2915 register_dissector("sccp", dissect_sccp, proto_sccp);
2917 /* Required function calls to register the header fields and subtrees used */
2918 proto_register_field_array(proto_sccp, hf, array_length(hf));
2919 proto_register_subtree_array(ett, array_length(ett));
2921 sccp_ssn_dissector_table = register_dissector_table("sccp.ssn", "SCCP SSN", FT_UINT8, BASE_DEC);
2923 register_heur_dissector_list("sccp", &heur_subdissector_list);
2925 sccp_module = prefs_register_protocol(proto_sccp, NULL);
2927 prefs_register_uint_preference(sccp_module, "source_pc",
2929 "The source point code (usually MSC) (to determine whether message is uplink or downlink)",
2930 16, &sccp_source_pc_global);
2932 prefs_register_bool_preference(sccp_module, "show_length", "Show length",
2933 "Show parameter length in the protocol tree",
2936 prefs_register_bool_preference(sccp_module, "defragment_xudt",
2937 "Reassemble XUDT messages",
2938 "Whether XUDT messages should be reassembled",
2939 &sccp_xudt_desegment);
2941 prefs_register_bool_preference(sccp_module, "trace_sccp",
2942 "Trace Associations",
2943 "Whether to keep infomation about messages and their associations",
2947 prefs_register_bool_preference(sccp_module, "show_more_info",
2948 "Show key parameters in Info Column",
2949 "Show SLR, DLR, and CAUSE Parameters in the Information Column of the Summary",
2954 register_init_routine(&init_sccp);
2956 assocs = se_tree_create(EMEM_TREE_TYPE_RED_BLACK, "sccp_associations");
2958 sccp_tap = register_tap("sccp");
2963 proto_reg_handoff_sccp(void)
2965 dissector_handle_t sccp_handle;
2967 sccp_handle = find_dissector("sccp");
2969 dissector_add("mtp3.service_indicator", SCCP_SI, sccp_handle);
2970 dissector_add_string("tali.opcode", "sccp", sccp_handle);
2972 data_handle = find_dissector("data");