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.ws [AT] gmail.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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
45 #include <epan/packet.h>
46 #include <epan/prefs.h>
47 #include <epan/emem.h>
48 #include <epan/reassemble.h>
49 #include <epan/asn1.h>
51 #include <epan/strutil.h>
52 #include <epan/expert.h>
55 #include "packet-mtp3.h"
56 #include "packet-tcap.h"
57 #include "packet-sccp.h"
58 #include "packet-e164.h"
59 #include "packet-e212.h"
60 #include "packet-frame.h"
62 /* function prototypes */
63 void proto_reg_handoff_sccp(void);
65 static Standard_Type decode_mtp3_standard;
67 #define SCCP_MSG_TYPE_OFFSET 0
68 #define SCCP_MSG_TYPE_LENGTH 1
69 #define POINTER_LENGTH 1
70 #define POINTER_LENGTH_LONG 2
72 #define INVALID_LR 0xffffff /* a reserved value */
74 /* Same as below but with names typed out */
75 static const value_string sccp_message_type_values[] = {
76 { SCCP_MSG_TYPE_CR, "Connection Request" },
77 { SCCP_MSG_TYPE_CC, "Connection Confirm" },
78 { SCCP_MSG_TYPE_CREF, "Connection Refused" },
79 { SCCP_MSG_TYPE_RLSD, "Released" },
80 { SCCP_MSG_TYPE_RLC, "Release Complete" },
81 { SCCP_MSG_TYPE_DT1, "Data Form 1" },
82 { SCCP_MSG_TYPE_DT2, "Data Form 2" },
83 { SCCP_MSG_TYPE_AK, "Data Acknowledgement" },
84 { SCCP_MSG_TYPE_UDT, "Unitdata" },
85 { SCCP_MSG_TYPE_UDTS, "Unitdata Service" },
86 { SCCP_MSG_TYPE_ED, "Expedited Data" },
87 { SCCP_MSG_TYPE_EA, "Expedited Data Acknowledgement" },
88 { SCCP_MSG_TYPE_RSR, "Reset Request" },
89 { SCCP_MSG_TYPE_RSC, "Reset Confirmation" },
90 { SCCP_MSG_TYPE_ERR, "Error" },
91 { SCCP_MSG_TYPE_IT, "Inactivity Timer" },
92 { SCCP_MSG_TYPE_XUDT, "Extended Unitdata" },
93 { SCCP_MSG_TYPE_XUDTS, "Extended Unitdata Service" },
94 { SCCP_MSG_TYPE_LUDT, "Long Unitdata" },
95 { SCCP_MSG_TYPE_LUDTS, "Long Unitdata Service" },
98 /* Same as above but in acronym form (for the Info column) */
99 const value_string sccp_message_type_acro_values[] = {
100 { SCCP_MSG_TYPE_CR, "CR" },
101 { SCCP_MSG_TYPE_CC, "CC" },
102 { SCCP_MSG_TYPE_CREF, "CREF" },
103 { SCCP_MSG_TYPE_RLSD, "RLSD" },
104 { SCCP_MSG_TYPE_RLC, "RLC" },
105 { SCCP_MSG_TYPE_DT1, "DT1" },
106 { SCCP_MSG_TYPE_DT2, "DT2" },
107 { SCCP_MSG_TYPE_AK, "AK" },
108 { SCCP_MSG_TYPE_UDT, "UDT" },
109 { SCCP_MSG_TYPE_UDTS, "UDTS" },
110 { SCCP_MSG_TYPE_ED, "ED" },
111 { SCCP_MSG_TYPE_EA, "EA" },
112 { SCCP_MSG_TYPE_RSR, "RSR" },
113 { SCCP_MSG_TYPE_RSC, "RSC" },
114 { SCCP_MSG_TYPE_ERR, "ERR" },
115 { SCCP_MSG_TYPE_IT, "IT" },
116 { SCCP_MSG_TYPE_XUDT, "XUDT" },
117 { SCCP_MSG_TYPE_XUDTS, "XUDTS" },
118 { SCCP_MSG_TYPE_LUDT, "LUDT" },
119 { SCCP_MSG_TYPE_LUDTS, "LUDTS" },
122 #define PARAMETER_LENGTH_LENGTH 1
123 #define PARAMETER_LONG_DATA_LENGTH_LENGTH 2
124 #define PARAMETER_TYPE_LENGTH 1
126 #define PARAMETER_END_OF_OPTIONAL_PARAMETERS 0x00
127 #define PARAMETER_DESTINATION_LOCAL_REFERENCE 0x01
128 #define PARAMETER_SOURCE_LOCAL_REFERENCE 0x02
129 #define PARAMETER_CALLED_PARTY_ADDRESS 0x03
130 #define PARAMETER_CALLING_PARTY_ADDRESS 0x04
131 #define PARAMETER_CLASS 0x05
132 #define PARAMETER_SEGMENTING_REASSEMBLING 0x06
133 #define PARAMETER_RECEIVE_SEQUENCE_NUMBER 0x07
134 #define PARAMETER_SEQUENCING_SEGMENTING 0x08
135 #define PARAMETER_CREDIT 0x09
136 #define PARAMETER_RELEASE_CAUSE 0x0a
137 #define PARAMETER_RETURN_CAUSE 0x0b
138 #define PARAMETER_RESET_CAUSE 0x0c
139 #define PARAMETER_ERROR_CAUSE 0x0d
140 #define PARAMETER_REFUSAL_CAUSE 0x0e
141 #define PARAMETER_DATA 0x0f
142 #define PARAMETER_SEGMENTATION 0x10
143 #define PARAMETER_HOP_COUNTER 0x11
144 /* Importance is ITU only */
145 #define PARAMETER_IMPORTANCE 0x12
146 #define PARAMETER_LONG_DATA 0x13
147 /* ISNI is ANSI only */
148 #define PARAMETER_ISNI 0xfa
150 static const value_string sccp_parameter_values[] = {
151 { PARAMETER_END_OF_OPTIONAL_PARAMETERS, "End of Optional Parameters" },
152 { PARAMETER_DESTINATION_LOCAL_REFERENCE, "Destination Local Reference" },
153 { PARAMETER_SOURCE_LOCAL_REFERENCE, "Source Local Reference" },
154 { PARAMETER_CALLED_PARTY_ADDRESS, "Called Party Address" },
155 { PARAMETER_CALLING_PARTY_ADDRESS, "Calling Party Address" },
156 { PARAMETER_CLASS, "Protocol Class" },
157 { PARAMETER_SEGMENTING_REASSEMBLING, "Segmenting/Reassembling" },
158 { PARAMETER_RECEIVE_SEQUENCE_NUMBER, "Receive Sequence Number" },
159 { PARAMETER_SEQUENCING_SEGMENTING, "Sequencing/Segmenting" },
160 { PARAMETER_CREDIT, "Credit" },
161 { PARAMETER_RELEASE_CAUSE, "Release Cause" },
162 { PARAMETER_RETURN_CAUSE, "Return Cause" },
163 { PARAMETER_RESET_CAUSE, "Reset Cause" },
164 { PARAMETER_ERROR_CAUSE, "Error Cause" },
165 { PARAMETER_REFUSAL_CAUSE, "Refusal Cause" },
166 { PARAMETER_DATA, "Data" },
167 { PARAMETER_SEGMENTATION, "Segmentation" },
168 { PARAMETER_HOP_COUNTER, "Hop Counter" },
169 { PARAMETER_IMPORTANCE, "Importance (ITU)" },
170 { PARAMETER_LONG_DATA, "Long Data" },
171 { PARAMETER_ISNI, "Intermediate Signaling Network Identification (ANSI)" },
175 #define END_OF_OPTIONAL_PARAMETERS_LENGTH 1
176 #define DESTINATION_LOCAL_REFERENCE_LENGTH 3
177 #define SOURCE_LOCAL_REFERENCE_LENGTH 3
178 #define PROTOCOL_CLASS_LENGTH 1
179 #define RECEIVE_SEQUENCE_NUMBER_LENGTH 1
180 #define CREDIT_LENGTH 1
181 #define RELEASE_CAUSE_LENGTH 1
182 #define RETURN_CAUSE_LENGTH 1
183 #define RESET_CAUSE_LENGTH 1
184 #define ERROR_CAUSE_LENGTH 1
185 #define REFUSAL_CAUSE_LENGTH 1
186 #define HOP_COUNTER_LENGTH 1
187 #define IMPORTANCE_LENGTH 1
190 /* Parts of the Called and Calling Address parameters */
191 /* Address Indicator */
192 #define ADDRESS_INDICATOR_LENGTH 1
193 #define ITU_RESERVED_MASK 0x80
194 #define ANSI_NATIONAL_MASK 0x80
195 #define ROUTING_INDICATOR_MASK 0x40
196 #define GTI_MASK 0x3C
198 #define ITU_SSN_INDICATOR_MASK 0x02
199 #define ITU_PC_INDICATOR_MASK 0x01
200 #define ANSI_PC_INDICATOR_MASK 0x02
201 #define ANSI_SSN_INDICATOR_MASK 0x01
203 static const value_string sccp_ansi_national_indicator_values[] = {
204 { 0x0, "Address coded to International standard" },
205 { 0x1, "Address coded to National standard" },
208 #define ROUTE_ON_GT 0x0
209 #define ROUTE_ON_SSN 0x1
210 #define ROUTING_INDICATOR_SHIFT 6
211 static const value_string sccp_routing_indicator_values[] = {
212 { ROUTE_ON_GT, "Route on GT" },
213 { ROUTE_ON_SSN, "Route on SSN" },
216 #define AI_GTI_NO_GT 0x0
217 #define ITU_AI_GTI_NAI 0x1
218 #define AI_GTI_TT 0x2
219 #define ITU_AI_GTI_TT_NP_ES 0x3
220 #define ITU_AI_GTI_TT_NP_ES_NAI 0x4
221 static const value_string sccp_itu_global_title_indicator_values[] = {
222 { AI_GTI_NO_GT, "No Global Title" },
223 { ITU_AI_GTI_NAI, "Nature of Address Indicator only" },
224 { AI_GTI_TT, "Translation Type only" },
225 { ITU_AI_GTI_TT_NP_ES, "Translation Type, Numbering Plan, and Encoding Scheme included" },
226 { ITU_AI_GTI_TT_NP_ES_NAI, "Translation Type, Numbering Plan, Encoding Scheme, and Nature of Address Indicator included" },
229 /* #define AI_GTI_NO_GT 0x0 */
230 #define ANSI_AI_GTI_TT_NP_ES 0x1
231 /* #define AI_GTI_TT 0x2 */
232 static const value_string sccp_ansi_global_title_indicator_values[] = {
233 { AI_GTI_NO_GT, "No Global Title" },
234 { ANSI_AI_GTI_TT_NP_ES, "Translation Type, Numbering Plan, and Encoding Scheme included" },
235 { AI_GTI_TT, "Translation Type only" },
238 static const value_string sccp_ai_pci_values[] = {
239 { 0x1, "Point Code present" },
240 { 0x0, "Point Code not present" },
243 static const value_string sccp_ai_ssni_values[] = {
244 { 0x1, "SSN present" },
245 { 0x0, "SSN not present" },
248 #define ADDRESS_SSN_LENGTH 1
249 #define INVALID_SSN 0xff
250 /* Some values from 3GPP TS 23.003 */
251 /* Japan TTC and NTT define a lot of SSNs, some of which conflict with
252 * these. They are not added for now.
254 static const value_string sccp_ssn_values[] = {
255 { 0x00, "SSN not known/not used" },
256 { 0x01, "SCCP management" },
257 { 0x02, "Reserved for ITU-T allocation" },
258 { 0x03, "ISDN User Part" },
259 { 0x04, "OMAP (Operation, Maintenance, and Administration Part)" },
260 { 0x05, "MAP (Mobile Application Part)" },
261 { 0x06, "HLR (Home Location Register)" },
262 { 0x07, "VLR (Visitor Location Register)" },
263 { 0x08, "MSC (Mobile Switching Center)" },
264 { 0x09, "EIC/EIR (Equipment Identifier Center/Equipment Identification Register)" },
265 { 0x0a, "AUC/AC (Authentication Center)" },
266 { 0x0b, "ISDN supplementary services (ITU only)" },
267 { 0x0c, "Reserved for international use (ITU only)" },
268 { 0x0d, "Broadband ISDN edge-to-edge applications (ITU only)" },
269 { 0x0e, "TC test responder (ITU only)" },
270 /* The following national network subsystem numbers have been allocated for use within and
271 * between GSM/UMTS networks:
275 { 0x91, "GMLC(MAP)" },
277 { 0x93, "gsmSCF (MAP) or IM-SSF (MAP) or Presence Network Agent" },
278 { 0x94, "SIWF (MAP)" },
279 { 0x95, "SGSN (MAP)" },
280 { 0x96, "GGSN (MAP)" },
281 /* The following national network subsystem numbers have been allocated for use within GSM/UMTS networks:*/
283 { 0xfa, "BSC (BSSAP-LE)" },
284 { 0xfb, "MSC (BSSAP-LE)" },
285 { 0xfc, "IOS or SMLC (BSSAP-LE)" },
286 { 0xfd, "BSS O&M (A interface)" },
287 { 0xfe, "BSSAP/BSAP" },
291 /* * * * * * * * * * * * * * * * *
292 * Global Title: ITU GTI == 0001 *
293 * * * * * * * * * * * * * * * * */
294 #define GT_NAI_MASK 0x7F
295 #define GT_NAI_LENGTH 1
296 #define GT_NAI_UNKNOWN 0x00
297 #define GT_NAI_SUBSCRIBER_NUMBER 0x01
298 #define GT_NAI_RESERVED_NATIONAL 0x02
299 #define GT_NAI_NATIONAL_SIG_NUM 0x03
300 #define GT_NAI_INTERNATIONAL_NUM 0x04
301 static const value_string sccp_nai_values[] = {
302 { GT_NAI_UNKNOWN, "NAI unknown" },
303 { GT_NAI_SUBSCRIBER_NUMBER, "Subscriber Number" },
304 { GT_NAI_RESERVED_NATIONAL, "Reserved for national use" },
305 { GT_NAI_NATIONAL_SIG_NUM, "National significant number" },
306 { GT_NAI_INTERNATIONAL_NUM, "International number" },
310 #define GT_OE_MASK 0x80
313 static const value_string sccp_oe_values[] = {
314 { GT_OE_EVEN, "Even number of address signals" },
315 { GT_OE_ODD, "Odd number of address signals" },
318 const value_string sccp_address_signal_values[] = {
338 /* * * * * * * * * * * * * * * * * * * * *
339 * Global Title: ITU and ANSI GTI == 0010 *
340 * * * * * * * * * * * * * * * * * * * * */
341 #define GT_TT_LENGTH 1
344 /* * * * * * * * * * * * * * * * * * * * * * * * * *
345 * Global Title: ITU GTI == 0011, ANSI GTI == 0001 *
346 * * * * * * * * * * * * * * * * * * * * * * * * * */
347 #define GT_NP_MASK 0xf0
348 #define GT_NP_SHIFT 4
349 #define GT_NP_ES_LENGTH 1
350 #define GT_NP_UNKNOWN 0x00
351 #define GT_NP_ISDN 0x01
352 #define GT_NP_GENERIC_RESERVED 0x02
353 #define GT_NP_DATA 0x03
354 #define GT_NP_TELEX 0x04
355 #define GT_NP_MARITIME_MOBILE 0x05
356 #define GT_NP_LAND_MOBILE 0x06
357 #define GT_NP_ISDN_MOBILE 0x07
358 #define GT_NP_PRIVATE_NETWORK 0x0e
359 #define GT_NP_RESERVED 0x0f
360 static const value_string sccp_np_values[] = {
361 { GT_NP_UNKNOWN, "Unknown" },
362 { GT_NP_ISDN, "ISDN/telephony" },
363 { GT_NP_GENERIC_RESERVED, "Generic (ITU)/Reserved (ANSI)" },
364 { GT_NP_DATA, "Data" },
365 { GT_NP_TELEX, "Telex" },
366 { GT_NP_MARITIME_MOBILE, "Maritime mobile" },
367 { GT_NP_LAND_MOBILE, "Land mobile" },
368 { GT_NP_ISDN_MOBILE, "ISDN/mobile" },
369 { GT_NP_PRIVATE_NETWORK, "Private network or network-specific" },
370 { GT_NP_RESERVED, "Reserved" },
373 #define GT_ES_MASK 0x0f
374 #define GT_ES_UNKNOWN 0x0
375 #define GT_ES_BCD_ODD 0x1
376 #define GT_ES_BCD_EVEN 0x2
377 #define GT_ES_NATIONAL 0x3
378 #define GT_ES_RESERVED 0xf
379 static const value_string sccp_es_values[] = {
380 { GT_ES_UNKNOWN, "Unknown" },
381 { GT_ES_BCD_ODD, "BCD, odd number of digits" },
382 { GT_ES_BCD_EVEN, "BCD, even number of digits" },
383 { GT_ES_NATIONAL, "National specific" },
384 { GT_ES_RESERVED, "Reserved (ITU)/Spare (ANSI)" },
387 /* Address signals above */
390 /* * * * * * * * * * * * * * * * *
391 * Global Title: ITU GTI == 0100 *
392 * * * * * * * * * * * * * * * * */
396 /* Address signals above */
399 #define CLASS_CLASS_MASK 0xf
400 #define CLASS_SPARE_HANDLING_MASK 0xf0
401 #define CLASS_SPARE_HANDLING_SHIFT 4
402 static const value_string sccp_class_handling_values [] = {
403 { 0x0, "No special options" },
404 { 0x8, "Return message on error" },
408 #define SEGMENTING_REASSEMBLING_LENGTH 1
409 #define SEGMENTING_REASSEMBLING_MASK 0x01
410 #define NO_MORE_DATA 0
412 /* This is also used by sequencing-segmenting parameter */
413 static const value_string sccp_segmenting_reassembling_values [] = {
414 { NO_MORE_DATA, "No more data" },
415 { MORE_DATA, "More data" },
419 #define RECEIVE_SEQUENCE_NUMBER_LENGTH 1
420 #define RSN_MASK 0xfe
422 #define SEQUENCING_SEGMENTING_LENGTH 2
423 #define SEQUENCING_SEGMENTING_SSN_LENGTH 1
424 #define SEQUENCING_SEGMENTING_RSN_LENGTH 1
425 #define SEND_SEQUENCE_NUMBER_MASK 0xfe
426 #define RECEIVE_SEQUENCE_NUMBER_MASK 0xfe
427 #define SEQUENCING_SEGMENTING_MORE_MASK 0x01
430 #define CREDIT_LENGTH 1
432 #define RELEASE_CAUSE_LENGTH 1
433 const value_string sccp_release_cause_values [] = {
434 { 0x00, "End user originated" },
435 { 0x01, "End user congestion" },
436 { 0x02, "End user failure" },
437 { 0x03, "SCCP user originated" },
438 { 0x04, "Remote procedure error" },
439 { 0x05, "Inconsistent connection data" },
440 { 0x06, "Access failure" },
441 { 0x07, "Access congestion" },
442 { 0x08, "Subsystem failure" },
443 { 0x09, "Subsystem congestion" },
444 { 0x0a, "MTP failure" },
445 { 0x0b, "Network congestion" },
446 { 0x0c, "Expiration of reset timer" },
447 { 0x0d, "Expiration of receive inactivity timer" },
448 { 0x0e, "Reserved" },
449 { 0x0f, "Unqualified" },
450 { 0x10, "SCCP failure (ITU only)" },
454 #define RETURN_CAUSE_LENGTH 1
455 const value_string sccp_return_cause_values [] = {
456 { 0x00, "No translation for an address of such nature" },
457 { 0x01, "No translation for this specific address" },
458 { 0x02, "Subsystem congestion" },
459 { 0x03, "Subsystem failure" },
460 { 0x04, "Unequipped failure" },
461 { 0x05, "MTP failure" },
462 { 0x06, "Network congestion" },
463 { 0x07, "Unqualified" },
464 { 0x08, "Error in message transport" },
465 { 0x09, "Error in local processing" },
466 { 0x0a, "Destination cannot perform reassembly" },
467 { 0x0b, "SCCP failure" },
468 { 0x0c, "Hop counter violation" },
469 { 0x0d, "Segmentation not supported" },
470 { 0x0e, "Segmentation failure" },
471 { 0xf7, "Message change failure (ANSI only)" },
472 { 0xf8, "Invalid INS routing request (ANSI only)" },
473 { 0xf9, "Invalid ISNI routing request (ANSI only)"},
474 { 0xfa, "Unauthorized message (ANSI only)" },
475 { 0xfb, "Message incompatibility (ANSI only)" },
476 { 0xfc, "Cannot perform ISNI constrained routing (ANSI only)" },
477 { 0xfd, "Redundant ISNI constrained routing (ANSI only)" },
478 { 0xfe, "Unable to perform ISNI identification (ANSI only)" },
482 #define RESET_CAUSE_LENGTH 1
483 const value_string sccp_reset_cause_values [] = {
484 { 0x00, "End user originated" },
485 { 0x01, "SCCP user originated" },
486 { 0x02, "Message out of order - incorrect send sequence number" },
487 { 0x03, "Message out of order - incorrect receive sequence number" },
488 { 0x04, "Remote procedure error - message out of window" },
489 { 0x05, "Remote procedure error - incorrect send sequence number after (re)initialization" },
490 { 0x06, "Remote procedure error - general" },
491 { 0x07, "Remote end user operational" },
492 { 0x08, "Network operational" },
493 { 0x09, "Access operational" },
494 { 0x0a, "Network congestion" },
495 { 0x0b, "Reserved (ITU)/Not obtainable (ANSI)" },
496 { 0x0c, "Unqualified" },
500 #define ERROR_CAUSE_LENGTH 1
501 const value_string sccp_error_cause_values [] = {
502 { 0x00, "Local Reference Number (LRN) mismatch - unassigned destination LRN" },
503 { 0x01, "Local Reference Number (LRN) mismatch - inconsistent source LRN" },
504 { 0x02, "Point code mismatch" },
505 { 0x03, "Service class mismatch" },
506 { 0x04, "Unqualified" },
510 #define REFUSAL_CAUSE_LENGTH 1
511 const value_string sccp_refusal_cause_values [] = {
512 { 0x00, "End user originated" },
513 { 0x01, "End user congestion" },
514 { 0x02, "End user failure" },
515 { 0x03, "SCCP user originated" },
516 { 0x04, "Destination address unknown" },
517 { 0x05, "Destination inaccessible" },
518 { 0x06, "Network resource - QOS not available/non-transient" },
519 { 0x07, "Network resource - QOS not available/transient" },
520 { 0x08, "Access failure" },
521 { 0x09, "Access congestion" },
522 { 0x0a, "Subsystem failure" },
523 { 0x0b, "Subsystem congestion" },
524 { 0x0c, "Expiration of connection establishment timer" },
525 { 0x0d, "Incompatible user data" },
526 { 0x0e, "Reserved" },
527 { 0x0f, "Unqualified" },
528 { 0x10, "Hop counter violation" },
529 { 0x11, "SCCP failure (ITU only)" },
530 { 0x12, "No translation for an address of such nature" },
531 { 0x13, "Unequipped user" },
535 #define SEGMENTATION_LENGTH 4
536 #define SEGMENTATION_FIRST_SEGMENT_MASK 0x80
537 #define SEGMENTATION_CLASS_MASK 0x40
538 #define SEGMENTATION_SPARE_MASK 0x30
539 #define SEGMENTATION_REMAINING_MASK 0x0f
540 static const value_string sccp_segmentation_first_segment_values [] = {
541 { 1, "First segment" },
542 { 0, "Not first segment" },
544 static const value_string sccp_segmentation_class_values [] = {
545 { 0, "Class 0 selected" },
546 { 1, "Class 1 selected" },
550 #define HOP_COUNTER_LENGTH 1
552 #define IMPORTANCE_LENGTH 1
553 #define IMPORTANCE_IMPORTANCE_MASK 0x7
556 #define ANSI_ISNI_ROUTING_CONTROL_LENGTH 1
557 #define ANSI_ISNI_MI_MASK 0x01
558 #define ANSI_ISNI_IRI_MASK 0x06
559 #define ANSI_ISNI_RES_MASK 0x08
560 #define ANSI_ISNI_TI_MASK 0x10
561 #define ANSI_ISNI_TI_SHIFT 4
562 #define ANSI_ISNI_COUNTER_MASK 0xe0
563 #define ANSI_ISNI_NETSPEC_MASK 0x03
565 static const value_string sccp_isni_mark_for_id_values [] = {
566 { 0x0, "Do not identify networks" },
567 { 0x1, "Identify networks" },
570 static const value_string sccp_isni_iri_values [] = {
571 { 0x0, "Neither constrained nor suggested ISNI routing" },
572 { 0x1, "Constrained ISNI routing" },
573 { 0x2, "Reserved for suggested ISNI routing" },
577 #define ANSI_ISNI_TYPE_0 0x0
578 #define ANSI_ISNI_TYPE_1 0x1
579 static const value_string sccp_isni_ti_values [] = {
580 { ANSI_ISNI_TYPE_0, "Type zero ISNI parameter format" },
581 { ANSI_ISNI_TYPE_1, "Type one ISNI parameter format" },
585 /* Initialize the protocol and registered fields */
586 static int proto_sccp = -1;
587 static int hf_sccp_message_type = -1;
588 static int hf_sccp_variable_pointer1 = -1;
589 static int hf_sccp_variable_pointer2 = -1;
590 static int hf_sccp_variable_pointer3 = -1;
591 static int hf_sccp_optional_pointer = -1;
592 static int hf_sccp_param_length = -1;
593 static int hf_sccp_ssn = -1;
594 static int hf_sccp_gt_digits = -1;
596 /* Called Party address */
597 static int hf_sccp_called_ansi_national_indicator = -1;
598 static int hf_sccp_called_itu_natl_use_bit = -1;
599 static int hf_sccp_called_routing_indicator = -1;
600 static int hf_sccp_called_itu_global_title_indicator = -1;
601 static int hf_sccp_called_ansi_global_title_indicator = -1;
602 static int hf_sccp_called_itu_ssn_indicator = -1;
603 static int hf_sccp_called_itu_point_code_indicator = -1;
604 static int hf_sccp_called_ansi_ssn_indicator = -1;
605 static int hf_sccp_called_ansi_point_code_indicator = -1;
606 static int hf_sccp_called_ssn = -1;
607 static int hf_sccp_called_pc_member = -1;
608 static int hf_sccp_called_pc_cluster = -1;
609 static int hf_sccp_called_pc_network = -1;
610 static int hf_sccp_called_ansi_pc = -1;
611 static int hf_sccp_called_chinese_pc = -1;
612 static int hf_sccp_called_itu_pc = -1;
613 static int hf_sccp_called_japan_pc = -1;
614 static int hf_sccp_called_gt_nai = -1;
615 static int hf_sccp_called_gt_oe = -1;
616 static int hf_sccp_called_gt_tt = -1;
617 static int hf_sccp_called_gt_np = -1;
618 static int hf_sccp_called_gt_es = -1;
619 static int hf_sccp_called_gt_digits = -1;
620 static int hf_sccp_called_gt_digits_length = -1;
622 /* Calling party address */
623 static int hf_sccp_calling_ansi_national_indicator = -1;
624 static int hf_sccp_calling_itu_natl_use_bit = -1;
625 static int hf_sccp_calling_routing_indicator = -1;
626 static int hf_sccp_calling_itu_global_title_indicator = -1;
627 static int hf_sccp_calling_ansi_global_title_indicator = -1;
628 static int hf_sccp_calling_itu_ssn_indicator = -1;
629 static int hf_sccp_calling_itu_point_code_indicator = -1;
630 static int hf_sccp_calling_ansi_ssn_indicator = -1;
631 static int hf_sccp_calling_ansi_point_code_indicator = -1;
632 static int hf_sccp_calling_ssn = -1;
633 static int hf_sccp_calling_pc_member = -1;
634 static int hf_sccp_calling_pc_cluster = -1;
635 static int hf_sccp_calling_pc_network = -1;
636 static int hf_sccp_calling_ansi_pc = -1;
637 static int hf_sccp_calling_chinese_pc = -1;
638 static int hf_sccp_calling_itu_pc = -1;
639 static int hf_sccp_calling_japan_pc = -1;
640 static int hf_sccp_calling_gt_nai = -1;
641 static int hf_sccp_calling_gt_oe = -1;
642 static int hf_sccp_calling_gt_tt = -1;
643 static int hf_sccp_calling_gt_np = -1;
644 static int hf_sccp_calling_gt_es = -1;
645 static int hf_sccp_calling_gt_digits = -1;
646 static int hf_sccp_calling_gt_digits_length = -1;
648 /* Other parameter values */
649 static int hf_sccp_dlr = -1;
650 static int hf_sccp_slr = -1;
651 static int hf_sccp_lr = -1;
652 static int hf_sccp_class = -1;
653 static int hf_sccp_handling = -1;
654 static int hf_sccp_more = -1;
655 static int hf_sccp_rsn = -1;
656 static int hf_sccp_sequencing_segmenting_ssn = -1;
657 static int hf_sccp_sequencing_segmenting_rsn = -1;
658 static int hf_sccp_sequencing_segmenting_more = -1;
659 static int hf_sccp_credit = -1;
660 static int hf_sccp_release_cause = -1;
661 static int hf_sccp_return_cause = -1;
662 static int hf_sccp_reset_cause = -1;
663 static int hf_sccp_error_cause = -1;
664 static int hf_sccp_refusal_cause = -1;
665 static int hf_sccp_segmentation_first = -1;
666 static int hf_sccp_segmentation_class = -1;
667 static int hf_sccp_segmentation_remaining = -1;
668 static int hf_sccp_segmentation_slr = -1;
669 static int hf_sccp_hop_counter = -1;
670 static int hf_sccp_importance = -1;
671 static int hf_sccp_ansi_isni_mi = -1;
672 static int hf_sccp_ansi_isni_iri = -1;
673 static int hf_sccp_ansi_isni_ti = -1;
674 static int hf_sccp_ansi_isni_netspec = -1;
675 static int hf_sccp_ansi_isni_counter = -1;
676 static int hf_sccp_ansi_isni_network = -1;
677 static int hf_sccp_ansi_isni_cluster = -1;
678 static int hf_sccp_xudt_msg_fragments = -1;
679 static int hf_sccp_xudt_msg_fragment = -1;
680 static int hf_sccp_xudt_msg_fragment_overlap = -1;
681 static int hf_sccp_xudt_msg_fragment_overlap_conflicts = -1;
682 static int hf_sccp_xudt_msg_fragment_multiple_tails = -1;
683 static int hf_sccp_xudt_msg_fragment_too_long_fragment = -1;
684 static int hf_sccp_xudt_msg_fragment_error = -1;
685 static int hf_sccp_xudt_msg_fragment_count = -1;
686 static int hf_sccp_xudt_msg_reassembled_in = -1;
687 static int hf_sccp_xudt_msg_reassembled_length = -1;
688 static int hf_sccp_assoc_msg = -1;
689 static int hf_sccp_assoc_id = -1;
691 /* Initialize the subtree pointers */
692 static gint ett_sccp = -1;
693 static gint ett_sccp_called = -1;
694 static gint ett_sccp_called_ai = -1;
695 static gint ett_sccp_called_pc = -1;
696 static gint ett_sccp_called_gt = -1;
697 static gint ett_sccp_called_gt_digits = -1;
698 static gint ett_sccp_calling = -1;
699 static gint ett_sccp_calling_ai = -1;
700 static gint ett_sccp_calling_pc = -1;
701 static gint ett_sccp_calling_gt = -1;
702 static gint ett_sccp_calling_gt_digits = -1;
703 static gint ett_sccp_sequencing_segmenting = -1;
704 static gint ett_sccp_segmentation = -1;
705 static gint ett_sccp_ansi_isni_routing_control = -1;
706 static gint ett_sccp_xudt_msg_fragment = -1;
707 static gint ett_sccp_xudt_msg_fragments = -1;
708 static gint ett_sccp_assoc = -1;
710 /* Declarations to desegment XUDT Messages */
711 static gboolean sccp_xudt_desegment = TRUE;
712 static gboolean show_key_params = FALSE;
713 static gboolean set_addresses = FALSE;
715 static int sccp_tap = -1;
718 static const fragment_items sccp_xudt_msg_frag_items = {
719 /* Fragment subtrees */
720 &ett_sccp_xudt_msg_fragment,
721 &ett_sccp_xudt_msg_fragments,
722 /* Fragment fields */
723 &hf_sccp_xudt_msg_fragments,
724 &hf_sccp_xudt_msg_fragment,
725 &hf_sccp_xudt_msg_fragment_overlap,
726 &hf_sccp_xudt_msg_fragment_overlap_conflicts,
727 &hf_sccp_xudt_msg_fragment_multiple_tails,
728 &hf_sccp_xudt_msg_fragment_too_long_fragment,
729 &hf_sccp_xudt_msg_fragment_error,
730 &hf_sccp_xudt_msg_fragment_count,
731 /* Reassembled in field */
732 &hf_sccp_xudt_msg_reassembled_in,
733 /* Reassembled length field */
734 &hf_sccp_xudt_msg_reassembled_length,
735 /* Reassembled data field */
738 "SCCP XUDT Message fragments"
741 static reassembly_table sccp_xudt_msg_reassembly_table;
744 #define SCCP_USER_DATA 0
745 #define SCCP_USER_TCAP 1
746 #define SCCP_USER_RANAP 2
747 #define SCCP_USER_BSSAP 3
748 #define SCCP_USER_GSMMAP 4
749 #define SCCP_USER_CAMEL 5
750 #define SCCP_USER_INAP 6
752 typedef struct _sccp_user_t {
758 dissector_handle_t *handlep;
761 static sccp_user_t *sccp_users;
762 static guint num_sccp_users;
764 static dissector_handle_t data_handle;
765 static dissector_handle_t tcap_handle;
766 static dissector_handle_t ranap_handle;
767 static dissector_handle_t bssap_handle;
768 static dissector_handle_t gsmmap_handle;
769 static dissector_handle_t camel_handle;
770 static dissector_handle_t inap_handle;
771 static dissector_handle_t default_handle;
773 static const char *default_payload = NULL;
775 static const value_string sccp_users_vals[] = {
776 { SCCP_USER_DATA, "Data"},
777 { SCCP_USER_TCAP, "TCAP"},
778 { SCCP_USER_RANAP, "RANAP"},
779 { SCCP_USER_BSSAP, "BSSAP"},
780 { SCCP_USER_GSMMAP, "GSM MAP"},
781 { SCCP_USER_CAMEL, "CAMEL"},
782 { SCCP_USER_INAP, "INAP"},
787 * Here are the global variables associated with
788 * the various user definable characteristics of the dissection
790 static guint32 sccp_source_pc_global = 0;
791 static gboolean sccp_show_length = FALSE;
793 static module_t *sccp_module;
794 static heur_dissector_list_t heur_subdissector_list;
796 /* Keep track of SSN value of current message so if/when we get to the data
797 * parameter, we can call appropriate sub-dissector. TODO: can this info
798 * be stored elsewhere?
801 static guint8 message_type = 0;
802 static guint dlr = 0;
803 static guint slr = 0;
805 static dissector_table_t sccp_ssn_dissector_table;
807 static emem_tree_t *assocs = NULL;
808 static sccp_assoc_info_t *assoc;
809 static sccp_msg_info_t *sccp_msg;
810 static sccp_assoc_info_t no_assoc = {0,0,0,0,0,FALSE,FALSE,NULL,NULL,SCCP_PLOAD_NONE,NULL,NULL,NULL,0};
811 static gboolean trace_sccp = FALSE;
812 static guint32 next_assoc_id = 0;
814 static const value_string assoc_protos[] = {
815 { SCCP_PLOAD_BSSAP, "BSSAP" },
816 { SCCP_PLOAD_RANAP, "RANAP" },
820 #define is_connectionless(m) \
821 ( m == SCCP_MSG_TYPE_UDT || m == SCCP_MSG_TYPE_UDTS \
822 || m == SCCP_MSG_TYPE_XUDT|| m == SCCP_MSG_TYPE_XUDTS \
823 || m == SCCP_MSG_TYPE_LUDT|| m == SCCP_MSG_TYPE_LUDTS)
825 #define RETURN_FALSE \
827 /*g_warning("Frame %d not protocol %d @ line %d", frame_num, my_mtp3_standard, __LINE__);*/ \
832 sccp_called_calling_looks_valid(guint32 frame_num _U_, tvbuff_t *tvb, guint8 my_mtp3_standard, gboolean is_co)
834 guint8 ai, ri, gti, ssni, pci;
835 guint8 len_needed = 1; /* need at least the Address Indicator */
836 guint len = tvb_length(tvb);
838 ai = tvb_get_guint8(tvb, 0);
839 if ((my_mtp3_standard == ANSI_STANDARD) && ((ai & ANSI_NATIONAL_MASK) == 0))
842 gti = (ai & GTI_MASK) >> GTI_SHIFT;
843 if (my_mtp3_standard == ANSI_STANDARD) {
851 ri = (ai & ROUTING_INDICATOR_MASK) >> ROUTING_INDICATOR_SHIFT;
852 if (my_mtp3_standard == ANSI_STANDARD) {
853 pci = ai & ANSI_PC_INDICATOR_MASK;
854 ssni = ai & ANSI_SSN_INDICATOR_MASK;
856 ssni = ai & ITU_SSN_INDICATOR_MASK;
857 pci = ai & ITU_PC_INDICATOR_MASK;
860 /* Route on SSN with no SSN? */
861 if ((ri == ROUTE_ON_SSN) && (ssni == 0))
864 /* Route on GT with no GT? */
865 if ((ri == ROUTE_ON_GT) && (gti == AI_GTI_NO_GT))
868 /* GT routed and connection-oriented (Class-2)?
869 * Yes, that's theoretically possible, but it's not used.
871 if ((ri == ROUTE_ON_GT) && is_co)
875 len_needed += ADDRESS_SSN_LENGTH;
877 if (my_mtp3_standard == ANSI_STANDARD ||
878 my_mtp3_standard == CHINESE_ITU_STANDARD)
879 len_needed += ANSI_PC_LENGTH;
881 len_needed += ITU_PC_LENGTH;
886 if (len_needed > len)
893 looks_like_valid_sccp(guint32 frame_num _U_, tvbuff_t *tvb, guint8 my_mtp3_standard)
896 guint8 msgtype, msg_class, cause;
897 guint called_ptr = 0;
898 guint calling_ptr = 0;
901 guint8 pointer_length = POINTER_LENGTH;
902 guint len = tvb_length(tvb);
904 /* Ensure we can do some basic checks without throwing an exception.
905 * Accesses beyond this length need to check the length first because
906 * we don't want to throw an exception in here...
911 msgtype = tvb_get_guint8(tvb, SCCP_MSG_TYPE_OFFSET);
912 if (!try_val_to_str(msgtype, sccp_message_type_acro_values)) {
915 offset = SCCP_MSG_TYPE_LENGTH;
918 case SCCP_MSG_TYPE_UDT:
919 case SCCP_MSG_TYPE_XUDT:
920 case SCCP_MSG_TYPE_LUDT:
921 case SCCP_MSG_TYPE_UDTS:
922 case SCCP_MSG_TYPE_XUDTS:
923 case SCCP_MSG_TYPE_LUDTS:
925 if (msgtype == SCCP_MSG_TYPE_XUDT || msgtype == SCCP_MSG_TYPE_XUDTS) {
926 if (SCCP_MSG_TYPE_LENGTH +
927 PROTOCOL_CLASS_LENGTH + /* or Cause for XUDTS */
932 POINTER_LENGTH > len)
936 if (msgtype == SCCP_MSG_TYPE_LUDT || msgtype == SCCP_MSG_TYPE_LUDTS) {
937 if (SCCP_MSG_TYPE_LENGTH +
938 PROTOCOL_CLASS_LENGTH + /* or Cause for LUDTS */
940 POINTER_LENGTH_LONG +
941 POINTER_LENGTH_LONG +
942 POINTER_LENGTH_LONG +
943 POINTER_LENGTH_LONG > len)
946 pointer_length = POINTER_LENGTH_LONG;
949 if (msgtype == SCCP_MSG_TYPE_UDT || msgtype == SCCP_MSG_TYPE_XUDT ||
950 msgtype == SCCP_MSG_TYPE_LUDT) {
952 msg_class = tvb_get_guint8(tvb, offset) & CLASS_CLASS_MASK;
955 offset += PROTOCOL_CLASS_LENGTH;
958 if (msgtype == SCCP_MSG_TYPE_XUDT || msgtype == SCCP_MSG_TYPE_LUDT)
959 offset += HOP_COUNTER_LENGTH;
961 if (msgtype == SCCP_MSG_TYPE_UDTS ||
962 msgtype == SCCP_MSG_TYPE_XUDTS ||
963 msgtype == SCCP_MSG_TYPE_LUDTS) {
965 cause = tvb_get_guint8(tvb, offset);
966 if (!try_val_to_str(cause, sccp_return_cause_values))
968 offset += RETURN_CAUSE_LENGTH;
971 if (msgtype == SCCP_MSG_TYPE_XUDTS || msgtype == SCCP_MSG_TYPE_LUDTS)
972 offset += HOP_COUNTER_LENGTH;
974 if (msgtype == SCCP_MSG_TYPE_LUDT || msgtype == SCCP_MSG_TYPE_LUDTS)
975 called_ptr = tvb_get_letohs(tvb, offset);
977 called_ptr = tvb_get_guint8(tvb, offset);
978 if (called_ptr == 0) /* Mandatory variable parameters must be present */
980 called_ptr += offset;
981 offset += pointer_length;
983 if (msgtype == SCCP_MSG_TYPE_LUDT || msgtype == SCCP_MSG_TYPE_LUDTS)
984 calling_ptr = tvb_get_letohs(tvb, offset);
986 calling_ptr = tvb_get_guint8(tvb, offset);
987 if (calling_ptr == 0) /* Mandatory variable parameters must be present */
989 calling_ptr += offset;
990 offset += pointer_length;
992 if (msgtype == SCCP_MSG_TYPE_LUDT || msgtype == SCCP_MSG_TYPE_LUDTS)
993 data_ptr = tvb_get_letohs(tvb, offset);
995 data_ptr = tvb_get_guint8(tvb, offset);
996 if (data_ptr == 0) /* Mandatory variable parameters must be present */
999 offset += pointer_length;
1001 if (msgtype == SCCP_MSG_TYPE_XUDT || msgtype == SCCP_MSG_TYPE_XUDTS) {
1002 opt_ptr = tvb_get_guint8(tvb, offset);
1003 offset += POINTER_LENGTH;
1004 } else if (msgtype == SCCP_MSG_TYPE_LUDT || msgtype == SCCP_MSG_TYPE_LUDTS) {
1005 opt_ptr = tvb_get_letohs(tvb, offset);
1006 offset += POINTER_LENGTH_LONG;
1009 if (msgtype == SCCP_MSG_TYPE_LUDT || msgtype == SCCP_MSG_TYPE_LUDTS) {
1010 /* Long pointers count from the 2nd (MSB) octet of the pointer */
1018 /* Check that the variable pointers are within bounds */
1019 if (called_ptr > len || calling_ptr > len || data_ptr > len)
1022 /* Check that the lengths of the variable parameters are within bounds */
1023 if (tvb_get_guint8(tvb, called_ptr)+called_ptr > len ||
1024 tvb_get_guint8(tvb, calling_ptr)+calling_ptr > len)
1026 if (msgtype == SCCP_MSG_TYPE_LUDT || msgtype == SCCP_MSG_TYPE_LUDTS) {
1027 if (tvb_get_letohs(tvb, data_ptr)+data_ptr > len)
1030 if (tvb_get_guint8(tvb, data_ptr)+data_ptr > len)
1035 case SCCP_MSG_TYPE_CR:
1037 offset += DESTINATION_LOCAL_REFERENCE_LENGTH;
1039 /* Class is only the lower 4 bits, but the upper 4 bits are spare
1040 * in Class-2. Don't mask them off so the below comparison also
1041 * fails if any of those spare bits are set.
1043 msg_class = tvb_get_guint8(tvb, offset);
1048 case SCCP_MSG_TYPE_CC:
1050 if (len < SCCP_MSG_TYPE_LENGTH
1051 + DESTINATION_LOCAL_REFERENCE_LENGTH
1052 + SOURCE_LOCAL_REFERENCE_LENGTH
1053 + PROTOCOL_CLASS_LENGTH
1057 offset += DESTINATION_LOCAL_REFERENCE_LENGTH;
1058 offset += SOURCE_LOCAL_REFERENCE_LENGTH;
1060 /* Class is only the lower 4 bits, but the upper 4 bits are spare
1061 * in Class-2. Don't mask them off so the below comparison also
1062 * fails if any of those spare bits are set.
1064 msg_class = tvb_get_guint8(tvb, offset);
1067 offset += PROTOCOL_CLASS_LENGTH;
1069 opt_ptr = tvb_get_guint8(tvb, offset);
1070 offset += POINTER_LENGTH;
1072 /* If the pointer isn't 0 (no optional parameters) or 1 (optional
1073 * parameter starts immediately after the pointer) then what would
1074 * be between the pointer and the parameter?
1079 /* If there are no optional parameters, are we at the end of the
1082 if ((opt_ptr == 0) && (offset != len))
1086 case SCCP_MSG_TYPE_CREF:
1088 offset += DESTINATION_LOCAL_REFERENCE_LENGTH;
1090 cause = tvb_get_guint8(tvb, offset);
1091 if (!try_val_to_str(cause, sccp_refusal_cause_values))
1093 offset += REFUSAL_CAUSE_LENGTH;
1095 opt_ptr = tvb_get_guint8(tvb, offset);
1096 offset += POINTER_LENGTH;
1098 /* If the pointer isn't 0 (no optional parameters) or 1 (optional
1099 * parameter starts immediately after the pointer) then what would
1100 * be between the pointer and the parameter?
1105 /* If there are no optional parameters, are we at the end of the
1108 if ((opt_ptr == 0) && (offset != len))
1112 case SCCP_MSG_TYPE_RLSD:
1114 if (len < SCCP_MSG_TYPE_LENGTH
1115 + DESTINATION_LOCAL_REFERENCE_LENGTH
1116 + SOURCE_LOCAL_REFERENCE_LENGTH
1117 + RELEASE_CAUSE_LENGTH
1121 offset += DESTINATION_LOCAL_REFERENCE_LENGTH;
1122 offset += SOURCE_LOCAL_REFERENCE_LENGTH;
1124 cause = tvb_get_guint8(tvb, offset);
1125 if (!try_val_to_str(cause, sccp_release_cause_values))
1127 offset += RELEASE_CAUSE_LENGTH;
1129 opt_ptr = tvb_get_guint8(tvb, offset);
1130 offset += POINTER_LENGTH;
1132 /* If the pointer isn't 0 (no optional parameters) or 1 (optional
1133 * parameter starts immediately after the pointer) then what would
1134 * be between the pointer and the parameter?
1139 /* If there are no optional parameters, are we at the end of the
1142 if ((opt_ptr == 0) && (offset != len))
1146 case SCCP_MSG_TYPE_RLC:
1148 if (len != SCCP_MSG_TYPE_LENGTH
1149 + DESTINATION_LOCAL_REFERENCE_LENGTH
1150 + SOURCE_LOCAL_REFERENCE_LENGTH)
1154 case SCCP_MSG_TYPE_ERR:
1156 if (len != SCCP_MSG_TYPE_LENGTH
1157 + DESTINATION_LOCAL_REFERENCE_LENGTH
1158 + ERROR_CAUSE_LENGTH)
1161 offset += DESTINATION_LOCAL_REFERENCE_LENGTH;
1163 cause = tvb_get_guint8(tvb, offset);
1164 if (!try_val_to_str(cause, sccp_error_cause_values))
1168 case SCCP_MSG_TYPE_DT1:
1170 if (len < SCCP_MSG_TYPE_LENGTH
1171 + DESTINATION_LOCAL_REFERENCE_LENGTH
1172 + SEGMENTING_REASSEMBLING_LENGTH
1174 + PARAMETER_LENGTH_LENGTH
1175 + 1) /* At least 1 byte of payload */
1177 offset += DESTINATION_LOCAL_REFERENCE_LENGTH;
1179 /* Are any of the spare bits in set? */
1180 if (tvb_get_guint8(tvb, offset) & ~SEGMENTING_REASSEMBLING_MASK)
1182 offset += SEGMENTING_REASSEMBLING_LENGTH;
1184 data_ptr = tvb_get_guint8(tvb, offset) + offset;
1185 /* Verify the data pointer is within bounds */
1188 offset += POINTER_LENGTH;
1190 /* Verify the data length uses the rest of the message */
1191 if (tvb_get_guint8(tvb, data_ptr) + offset + 1U != len)
1195 case SCCP_MSG_TYPE_IT:
1197 if (len < SCCP_MSG_TYPE_LENGTH
1198 + DESTINATION_LOCAL_REFERENCE_LENGTH
1199 + SOURCE_LOCAL_REFERENCE_LENGTH
1200 + PROTOCOL_CLASS_LENGTH
1201 + SEQUENCING_SEGMENTING_LENGTH
1205 offset += DESTINATION_LOCAL_REFERENCE_LENGTH;
1206 offset += SOURCE_LOCAL_REFERENCE_LENGTH;
1208 /* Class is only the lower 4 bits, but the upper 4 bits are spare
1209 * in Class-2. Don't mask them off so the below comparison also
1210 * fails if any of those spare bits are set.
1212 msg_class = tvb_get_guint8(tvb, offset);
1215 offset += PROTOCOL_CLASS_LENGTH;
1218 case SCCP_MSG_TYPE_AK:
1219 case SCCP_MSG_TYPE_DT2:
1220 case SCCP_MSG_TYPE_EA:
1221 case SCCP_MSG_TYPE_ED:
1222 case SCCP_MSG_TYPE_RSC:
1223 case SCCP_MSG_TYPE_RSR:
1224 /* Class-3 is never actually used in the real world */
1229 DISSECTOR_ASSERT_NOT_REACHED();
1233 guint8 param_len = tvb_get_guint8(tvb, called_ptr);
1234 tvbuff_t *param_tvb;
1238 param_tvb = tvb_new_subset(tvb, called_ptr+1, param_len, param_len);
1240 if (!sccp_called_calling_looks_valid(frame_num, param_tvb, my_mtp3_standard, !is_connectionless(msgtype)))
1245 guint8 param_len = tvb_get_guint8(tvb, calling_ptr);
1246 tvbuff_t *param_tvb;
1250 param_tvb = tvb_new_subset(tvb, calling_ptr+1, param_len, param_len);
1252 if (!sccp_called_calling_looks_valid(frame_num, param_tvb, my_mtp3_standard, !is_connectionless(msgtype)))
1259 opt_ptr += offset-1; /* (offset was already incremented) */
1261 /* Check that the optional pointer is within bounds */
1265 opt_param = tvb_get_guint8(tvb, opt_ptr);
1266 /* Check if the (1st) optional parameter tag is valid */
1267 if (!try_val_to_str(opt_param, sccp_parameter_values))
1270 /* Check that the (1st) parameter length is within bounds */
1271 if ((opt_param != PARAMETER_END_OF_OPTIONAL_PARAMETERS) &&
1272 ((opt_ptr+1U) <= len) &&
1273 ((tvb_get_guint8(tvb, opt_ptr+1U)+offset) > len))
1276 /* If we're at the end of the parameters, are we also at the end of the
1279 if ((opt_param == PARAMETER_END_OF_OPTIONAL_PARAMETERS) && ((opt_ptr+1U) != len))
1286 static sccp_assoc_info_t *
1287 new_assoc(guint32 calling, guint32 called)
1289 sccp_assoc_info_t *a = se_new0(sccp_assoc_info_t);
1291 a->id = next_assoc_id++;
1292 a->calling_dpc = calling;
1293 a->called_dpc = called;
1294 a->calling_ssn = INVALID_SSN;
1295 a->called_ssn = INVALID_SSN;
1298 a->payload = SCCP_PLOAD_NONE;
1299 a->calling_party = NULL;
1300 a->called_party = NULL;
1301 a->extra_info = NULL;
1307 reset_sccp_assoc(void)
1313 get_sccp_assoc(packet_info *pinfo, guint offset, guint32 src_lr, guint32 dst_lr, guint msg_type)
1316 address *opc = &(pinfo->src);
1317 address *dpc = &(pinfo->dst);
1318 guint framenum = PINFO_FD_NUM(pinfo);
1323 opck = opc->type == AT_SS7PC ? mtp3_pc_hash((const mtp3_addr_pc_t *)opc->data) : g_str_hash(ep_address_to_str(opc));
1324 dpck = dpc->type == AT_SS7PC ? mtp3_pc_hash((const mtp3_addr_pc_t *)dpc->data) : g_str_hash(ep_address_to_str(dpc));
1328 case SCCP_MSG_TYPE_CR:
1330 /* CR contains the opc,dpc,dlr key of backward messages swapped as dpc,opc,slr */
1331 emem_tree_key_t bw_key[] = {
1338 if (! ( assoc = (sccp_assoc_info_t *)se_tree_lookup32_array(assocs,bw_key) ) && ! PINFO_FD_VISITED(pinfo) ) {
1339 assoc = new_assoc(opck, dpck);
1340 se_tree_insert32_array(assocs, bw_key, assoc);
1341 assoc->has_bw_key = TRUE;
1344 pinfo->p2p_dir = P2P_DIR_SENT;
1348 case SCCP_MSG_TYPE_CC:
1350 emem_tree_key_t fw_key[] = {
1351 {1, &dpck}, {1, &opck}, {1, &src_lr}, {0, NULL}
1353 emem_tree_key_t bw_key[] = {
1354 {1, &opck}, {1, &dpck}, {1, &dst_lr}, {0, NULL}
1357 if ( ( assoc = (sccp_assoc_info_t *)se_tree_lookup32_array(assocs, bw_key) ) ) {
1361 if ( (assoc = (sccp_assoc_info_t *)se_tree_lookup32_array(assocs, fw_key) ) ) {
1365 assoc = new_assoc(dpck,opck);
1369 pinfo->p2p_dir = P2P_DIR_RECV;
1371 if ( ! PINFO_FD_VISITED(pinfo) && ! assoc->has_bw_key ) {
1372 se_tree_insert32_array(assocs, bw_key, assoc);
1373 assoc->has_bw_key = TRUE;
1376 if ( ! PINFO_FD_VISITED(pinfo) && ! assoc->has_fw_key ) {
1377 se_tree_insert32_array(assocs, fw_key, assoc);
1378 assoc->has_fw_key = TRUE;
1383 case SCCP_MSG_TYPE_RLC:
1385 emem_tree_key_t bw_key[] = {
1386 {1, &dpck}, {1, &opck}, {1, &src_lr}, {0, NULL}
1388 emem_tree_key_t fw_key[] = {
1389 {1, &opck}, {1, &dpck}, {1, &dst_lr}, {0, NULL}
1391 if ( ( assoc = (sccp_assoc_info_t *)se_tree_lookup32_array(assocs, bw_key) ) ) {
1395 if ( (assoc = (sccp_assoc_info_t *)se_tree_lookup32_array(assocs, fw_key) ) ) {
1399 assoc = new_assoc(dpck, opck);
1403 pinfo->p2p_dir = P2P_DIR_SENT;
1405 if ( ! PINFO_FD_VISITED(pinfo) && ! assoc->has_bw_key ) {
1406 se_tree_insert32_array(assocs, bw_key, assoc);
1407 assoc->has_bw_key = TRUE;
1410 if ( ! PINFO_FD_VISITED(pinfo) && ! assoc->has_fw_key ) {
1411 se_tree_insert32_array(assocs, fw_key, assoc);
1412 assoc->has_fw_key = TRUE;
1418 emem_tree_key_t key[] = {
1419 {1, &opck}, {1, &dpck}, {1, &dst_lr}, {0, NULL}
1422 assoc = (sccp_assoc_info_t *)se_tree_lookup32_array(assocs, key);
1425 if (assoc->calling_dpc == dpck) {
1426 pinfo->p2p_dir = P2P_DIR_RECV;
1428 pinfo->p2p_dir = P2P_DIR_SENT;
1436 if (assoc && trace_sccp) {
1437 if ( ! PINFO_FD_VISITED(pinfo)) {
1438 sccp_msg_info_t *msg = se_new0(sccp_msg_info_t);
1439 msg->framenum = framenum;
1440 msg->offset = offset;
1441 msg->data.co.next = NULL;
1442 msg->data.co.assoc = assoc;
1443 msg->data.co.label = NULL;
1444 msg->data.co.comment = NULL;
1445 msg->type = msg_type;
1449 for (m = assoc->msgs; m->data.co.next; m = m->data.co.next) ;
1450 m->data.co.next = msg;
1455 assoc->curr_msg = msg;
1461 for (m = assoc->msgs; m; m = m->data.co.next) {
1462 if ((m->framenum == framenum) && (m->offset == offset)) {
1463 assoc->curr_msg = m;
1470 return assoc ? assoc : &no_assoc;
1475 dissect_sccp_unknown_message(tvbuff_t *message_tvb, proto_tree *sccp_tree)
1477 guint32 message_length;
1479 message_length = tvb_length(message_tvb);
1481 proto_tree_add_text(sccp_tree, message_tvb, 0, message_length,
1482 "Unknown message (%u byte%s)",
1483 message_length, plurality(message_length, "", "s"));
1487 dissect_sccp_unknown_param(tvbuff_t *tvb, proto_tree *tree, guint8 type, guint length)
1489 proto_tree_add_text(tree, tvb, 0, length, "Unknown parameter 0x%x (%u byte%s)",
1490 type, length, plurality(length, "", "s"));
1494 dissect_sccp_dlr_param(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint length)
1496 proto_item *lr_item, *expert_item;
1499 expert_item = proto_tree_add_text(tree, tvb, 0, length, "Wrong length indicated. Expected 3, got %u", length);
1500 expert_add_info_format(pinfo, expert_item, PI_MALFORMED, PI_ERROR, "Wrong length indicated. Expected 3, got %u", length);
1501 PROTO_ITEM_SET_GENERATED(expert_item);
1505 dlr = tvb_get_letoh24(tvb, 0);
1506 proto_tree_add_uint(tree, hf_sccp_dlr, tvb, 0, length, dlr);
1507 lr_item = proto_tree_add_uint(tree, hf_sccp_lr, tvb, 0, length, dlr);
1508 PROTO_ITEM_SET_HIDDEN(lr_item);
1510 if (show_key_params)
1511 col_append_fstr(pinfo->cinfo, COL_INFO, "DLR=%d ", dlr);
1515 dissect_sccp_slr_param(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint length)
1517 proto_item *lr_item, *expert_item;
1520 expert_item = proto_tree_add_text(tree, tvb, 0, length, "Wrong length indicated. Expected 3, got %u", length);
1521 expert_add_info_format(pinfo, expert_item, PI_MALFORMED, PI_ERROR, "Wrong length indicated. Expected 3, got %u", length);
1522 PROTO_ITEM_SET_GENERATED(expert_item);
1526 slr = tvb_get_letoh24(tvb, 0);
1527 proto_tree_add_uint(tree, hf_sccp_slr, tvb, 0, length, slr);
1528 lr_item = proto_tree_add_uint(tree, hf_sccp_lr, tvb, 0, length, slr);
1529 PROTO_ITEM_SET_HIDDEN(lr_item);
1531 if (show_key_params)
1532 col_append_fstr(pinfo->cinfo, COL_INFO, "SLR=%d ", slr);
1536 dissect_sccp_gt_address_information(tvbuff_t *tvb, packet_info *pinfo,
1537 proto_tree *tree, guint length,
1538 gboolean even_length, gboolean called,
1539 gboolean route_on_gt)
1542 guint8 odd_signal, even_signal;
1543 proto_item *digits_item;
1544 proto_tree *digits_tree;
1547 gt_digits = (char *)ep_alloc0(GT_MAX_SIGNALS+1);
1549 while (offset < length) {
1550 odd_signal = tvb_get_guint8(tvb, offset) & GT_ODD_SIGNAL_MASK;
1551 even_signal = tvb_get_guint8(tvb, offset) & GT_EVEN_SIGNAL_MASK;
1552 even_signal >>= GT_EVEN_SIGNAL_SHIFT;
1554 g_strlcat(gt_digits, val_to_str(odd_signal, sccp_address_signal_values,
1555 "Unknown: %d"), GT_MAX_SIGNALS+1);
1557 /* If the last signal is NOT filler */
1558 if (offset != (length - 1) || even_length == TRUE)
1559 g_strlcat(gt_digits, val_to_str(even_signal, sccp_address_signal_values,
1560 "Unknown: %d"), GT_MAX_SIGNALS+1);
1562 offset += GT_SIGNAL_LENGTH;
1565 if (is_connectionless(message_type) && sccp_msg) {
1566 guint8 **gt_ptr = called ? &(sccp_msg->data.ud.called_gt) : &(sccp_msg->data.ud.calling_gt);
1568 *gt_ptr = (guint8 *)ep_strdup(gt_digits);
1571 digits_item = proto_tree_add_string(tree, called ? hf_sccp_called_gt_digits
1572 : hf_sccp_calling_gt_digits,
1573 tvb, 0, length, gt_digits);
1574 digits_tree = proto_item_add_subtree(digits_item, called ? ett_sccp_called_gt_digits
1575 : ett_sccp_calling_gt_digits);
1577 if (set_addresses && route_on_gt) {
1579 SET_ADDRESS(&pinfo->dst, AT_STRINGZ, 1+(int)strlen(gt_digits), gt_digits);
1581 SET_ADDRESS(&pinfo->src, AT_STRINGZ, 1+(int)strlen(gt_digits), gt_digits);
1585 proto_tree_add_string(digits_tree, hf_sccp_gt_digits, tvb, 0, length, gt_digits);
1586 proto_tree_add_uint(digits_tree, called ? hf_sccp_called_gt_digits_length
1587 : hf_sccp_calling_gt_digits_length,
1588 tvb, 0, length, (guint32)strlen(gt_digits));
1594 dissect_sccp_global_title(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint length,
1595 guint8 gti, gboolean route_on_gt, gboolean called)
1597 proto_item *gt_item;
1598 proto_tree *gt_tree;
1599 proto_tree *digits_tree;
1600 tvbuff_t *signals_tvb;
1602 guint8 odd_even, nai = 0, np = 0, es;
1603 gboolean even = TRUE;
1605 /* Shift GTI to where we can work with it */
1608 gt_item = proto_tree_add_text(tree, tvb, offset, length,
1609 "Global Title 0x%x (%u byte%s)",
1610 gti, length, plurality(length,"", "s"));
1611 gt_tree = proto_item_add_subtree(gt_item, called ? ett_sccp_called_gt
1612 : ett_sccp_calling_gt);
1614 /* Decode Transation Type (if present) */
1615 if ((gti == AI_GTI_TT) ||
1616 ((decode_mtp3_standard != ANSI_STANDARD) &&
1617 ((gti == ITU_AI_GTI_TT_NP_ES) || (gti == ITU_AI_GTI_TT_NP_ES_NAI))) ||
1618 ((decode_mtp3_standard == ANSI_STANDARD) && (gti == ANSI_AI_GTI_TT_NP_ES))) {
1620 proto_tree_add_item(gt_tree, called ? hf_sccp_called_gt_tt
1621 : hf_sccp_calling_gt_tt,
1622 tvb, offset, GT_TT_LENGTH, ENC_NA);
1623 offset += GT_TT_LENGTH;
1626 if (gti == AI_GTI_TT) {
1627 /* Protocol doesn't tell us, so we ASSUME even... */
1631 /* Decode Numbering Plan and Encoding Scheme (if present) */
1632 if (((decode_mtp3_standard != ANSI_STANDARD) &&
1633 ((gti == ITU_AI_GTI_TT_NP_ES) || (gti == ITU_AI_GTI_TT_NP_ES_NAI))) ||
1634 ((decode_mtp3_standard == ANSI_STANDARD) && (gti == ANSI_AI_GTI_TT_NP_ES))) {
1636 np = tvb_get_guint8(tvb, offset) & GT_NP_MASK;
1637 proto_tree_add_uint(gt_tree, called ? hf_sccp_called_gt_np
1638 : hf_sccp_calling_gt_np,
1639 tvb, offset, GT_NP_ES_LENGTH, np);
1641 es = tvb_get_guint8(tvb, offset) & GT_ES_MASK;
1642 proto_tree_add_uint(gt_tree, called ? hf_sccp_called_gt_es
1643 : hf_sccp_calling_gt_es,
1644 tvb, offset, GT_NP_ES_LENGTH, es);
1646 even = (es == GT_ES_BCD_EVEN) ? TRUE : FALSE;
1648 offset += GT_NP_ES_LENGTH;
1651 /* Decode Nature of Address Indicator (if present) */
1652 if ((decode_mtp3_standard != ANSI_STANDARD) &&
1653 ((gti == ITU_AI_GTI_NAI) || (gti == ITU_AI_GTI_TT_NP_ES_NAI))) {
1655 /* Decode Odd/Even Indicator (if present) */
1656 if (gti == ITU_AI_GTI_NAI) {
1657 odd_even = tvb_get_guint8(tvb, offset) & GT_OE_MASK;
1658 proto_tree_add_uint(gt_tree, called ? hf_sccp_called_gt_oe
1659 : hf_sccp_calling_gt_oe,
1660 tvb, offset, GT_NAI_LENGTH, odd_even);
1661 even = (odd_even == GT_OE_EVEN) ? TRUE : FALSE;
1664 nai = tvb_get_guint8(tvb, offset) & GT_NAI_MASK;
1665 proto_tree_add_uint(gt_tree, called ? hf_sccp_called_gt_nai
1666 : hf_sccp_calling_gt_nai,
1667 tvb, offset, GT_NAI_LENGTH, nai);
1669 offset += GT_NAI_LENGTH;
1672 /* Decode address signal(s) */
1673 if (length < offset)
1676 signals_tvb = tvb_new_subset(tvb, offset, (length - offset),
1679 digits_tree = dissect_sccp_gt_address_information(signals_tvb, pinfo, gt_tree,
1681 even, called, route_on_gt);
1683 /* Display the country code (if we can) */
1684 switch (np >> GT_NP_SHIFT) {
1686 case GT_NP_ISDN_MOBILE:
1687 if (nai == GT_NAI_INTERNATIONAL_NUM) {
1688 dissect_e164_cc(signals_tvb, digits_tree, 0, TRUE);
1691 case GT_NP_LAND_MOBILE:
1692 dissect_e212_mcc_mnc_in_address(signals_tvb, pinfo, digits_tree, 0);
1700 dissect_sccp_3byte_pc(tvbuff_t *tvb, proto_tree *call_tree, guint offset,
1705 if (decode_mtp3_standard == ANSI_STANDARD)
1708 hf_pc = hf_sccp_called_ansi_pc;
1710 hf_pc = hf_sccp_calling_ansi_pc;
1711 } else /* CHINESE_ITU_STANDARD */ {
1713 hf_pc = hf_sccp_called_chinese_pc;
1715 hf_pc = hf_sccp_calling_chinese_pc;
1718 /* create and fill the PC tree */
1719 dissect_mtp3_3byte_pc(tvb, offset, call_tree,
1720 called ? ett_sccp_called_pc : ett_sccp_calling_pc,
1722 called ? hf_sccp_called_pc_network : hf_sccp_calling_pc_network,
1723 called ? hf_sccp_called_pc_cluster : hf_sccp_calling_pc_cluster,
1724 called ? hf_sccp_called_pc_member : hf_sccp_calling_pc_member,
1727 return(offset + ANSI_PC_LENGTH);
1730 /* FUNCTION dissect_sccp_called_calling_param():
1731 * Dissect the Calling or Called Party Address parameters.
1733 * The boolean 'called' describes whether this function is decoding a
1734 * called (TRUE) or calling (FALSE) party address. There is simply too
1735 * much code in this function to have 2 copies of it (one for called, one
1738 * NOTE: this function is called even when (!tree) so that we can get
1739 * the SSN and subsequently call subdissectors (if and when there's a data
1740 * parameter). Realistically we should put if (!tree)'s around a lot of the
1741 * code, but I think that would make it unreadable--and the expense of not
1742 * doing so does not appear to be very high.
1745 dissect_sccp_called_calling_param(tvbuff_t *tvb, proto_tree *tree, packet_info *pinfo,
1746 guint length, gboolean called)
1748 proto_item *call_item = 0, *call_ai_item = 0, *item, *hidden_item, *expert_item;
1749 proto_tree *call_tree = 0, *call_ai_tree = 0;
1751 guint8 national = 0xFFU, routing_ind, gti, pci, ssni, ssn;
1753 dissector_handle_t ssn_dissector = NULL, tcap_ssn_dissector = NULL;
1754 const char *ssn_dissector_short_name = NULL;
1755 const char *tcap_ssn_dissector_short_name = NULL;
1757 call_item = proto_tree_add_text(tree, tvb, 0, length,
1758 "%s Party address (%u byte%s)",
1759 called ? "Called" : "Calling", length,
1760 plurality(length, "", "s"));
1761 call_tree = proto_item_add_subtree(call_item, called ? ett_sccp_called : ett_sccp_calling);
1763 call_ai_item = proto_tree_add_text(call_tree, tvb, 0,
1764 ADDRESS_INDICATOR_LENGTH,
1765 "Address Indicator");
1766 call_ai_tree = proto_item_add_subtree(call_ai_item, called ? ett_sccp_called_ai : ett_sccp_calling_ai);
1768 if (decode_mtp3_standard == ANSI_STANDARD) {
1769 national = tvb_get_guint8(tvb, 0) & ANSI_NATIONAL_MASK;
1770 expert_item = proto_tree_add_uint(call_ai_tree, called ? hf_sccp_called_ansi_national_indicator
1771 : hf_sccp_calling_ansi_national_indicator,
1772 tvb, 0, ADDRESS_INDICATOR_LENGTH, national);
1774 expert_add_info_format(pinfo, expert_item, PI_MALFORMED, PI_WARN, "Address is coded to "
1775 "international standards. This doesn't normally happen in ANSI "
1778 guint8 natl_use_bit = tvb_get_guint8(tvb, 0) & ITU_RESERVED_MASK;
1780 proto_tree_add_uint(call_ai_tree, called ? hf_sccp_called_itu_natl_use_bit
1781 : hf_sccp_calling_itu_natl_use_bit,
1782 tvb, 0, ADDRESS_INDICATOR_LENGTH, natl_use_bit);
1785 routing_ind = tvb_get_guint8(tvb, 0) & ROUTING_INDICATOR_MASK;
1786 proto_tree_add_uint(call_ai_tree, called ? hf_sccp_called_routing_indicator : hf_sccp_calling_routing_indicator,
1787 tvb, 0, ADDRESS_INDICATOR_LENGTH, routing_ind);
1788 /* Only shift off the other bits after adding the item */
1789 routing_ind >>= ROUTING_INDICATOR_SHIFT;
1791 gti = tvb_get_guint8(tvb, 0) & GTI_MASK;
1793 if (decode_mtp3_standard == ITU_STANDARD ||
1794 decode_mtp3_standard == CHINESE_ITU_STANDARD ||
1795 decode_mtp3_standard == JAPAN_STANDARD ||
1798 proto_tree_add_uint(call_ai_tree,
1799 called ? hf_sccp_called_itu_global_title_indicator : hf_sccp_calling_itu_global_title_indicator,
1800 tvb, 0, ADDRESS_INDICATOR_LENGTH, gti);
1802 ssni = tvb_get_guint8(tvb, 0) & ITU_SSN_INDICATOR_MASK;
1803 expert_item = proto_tree_add_uint(call_ai_tree,
1804 called ? hf_sccp_called_itu_ssn_indicator : hf_sccp_calling_itu_ssn_indicator,
1805 tvb, 0, ADDRESS_INDICATOR_LENGTH, ssni);
1806 if ((routing_ind == ROUTE_ON_SSN) && (ssni == 0)) {
1807 expert_add_info_format(pinfo, expert_item, PI_PROTOCOL, PI_WARN,
1808 "Message is routed on SSN, but SSN is not present");
1811 pci = tvb_get_guint8(tvb, 0) & ITU_PC_INDICATOR_MASK;
1812 proto_tree_add_uint(call_ai_tree, called ? hf_sccp_called_itu_point_code_indicator : hf_sccp_calling_itu_point_code_indicator,
1813 tvb, 0, ADDRESS_INDICATOR_LENGTH, pci);
1815 offset = ADDRESS_INDICATOR_LENGTH;
1817 /* Dissect PC (if present) */
1819 if (decode_mtp3_standard == ITU_STANDARD || national == 0) {
1820 if (length < offset + ITU_PC_LENGTH) {
1821 expert_item = proto_tree_add_text(call_tree, tvb, 0, -1,
1822 "Wrong length indicated (%u) should be at least %u, PC is %u octets",
1823 length, offset + ITU_PC_LENGTH, ITU_PC_LENGTH);
1824 expert_add_info_format(pinfo, expert_item, PI_MALFORMED, PI_ERROR, "Wrong length indicated");
1825 PROTO_ITEM_SET_GENERATED(expert_item);
1828 proto_tree_add_item(call_tree, called ? hf_sccp_called_itu_pc : hf_sccp_calling_itu_pc,
1829 tvb, offset, ITU_PC_LENGTH, ENC_LITTLE_ENDIAN);
1830 offset += ITU_PC_LENGTH;
1832 } else if (decode_mtp3_standard == JAPAN_STANDARD) {
1834 if (length < offset + JAPAN_PC_LENGTH) {
1835 expert_item = proto_tree_add_text(call_tree, tvb, 0, -1,
1836 "Wrong length indicated (%u) should be at least %u, PC is %u octets",
1837 length, offset + JAPAN_PC_LENGTH, JAPAN_PC_LENGTH);
1838 expert_add_info_format(pinfo, expert_item, PI_MALFORMED, PI_ERROR, "Wrong length indicated");
1839 PROTO_ITEM_SET_GENERATED(expert_item);
1842 proto_tree_add_item(call_tree, called ? hf_sccp_called_japan_pc : hf_sccp_calling_japan_pc,
1843 tvb, offset, JAPAN_PC_LENGTH, ENC_LITTLE_ENDIAN);
1845 offset += JAPAN_PC_LENGTH;
1847 } else /* CHINESE_ITU_STANDARD */ {
1849 if (length < offset + ANSI_PC_LENGTH) {
1850 expert_item = proto_tree_add_text(call_tree, tvb, 0, -1,
1851 "Wrong length indicated (%u) should be at least %u, PC is %u octets",
1852 length, offset + ANSI_PC_LENGTH, ANSI_PC_LENGTH);
1853 expert_add_info_format(pinfo, expert_item, PI_MALFORMED, PI_ERROR, "Wrong length indicated");
1854 PROTO_ITEM_SET_GENERATED(expert_item);
1857 offset = dissect_sccp_3byte_pc(tvb, call_tree, offset, called);
1862 /* Dissect SSN (if present) */
1864 ssn = tvb_get_guint8(tvb, offset);
1866 if ((routing_ind == ROUTE_ON_SSN) && (ssn == 0)) {
1867 expert_add_info_format(pinfo, expert_item, PI_PROTOCOL, PI_WARN,
1868 "Message is routed on SSN, but SSN is zero (unspecified)");
1871 if (called && assoc)
1872 assoc->called_ssn = ssn;
1874 assoc->calling_ssn = ssn;
1876 if (is_connectionless(message_type) && sccp_msg) {
1877 guint *ssn_ptr = called ? &(sccp_msg->data.ud.called_ssn) : &(sccp_msg->data.ud.calling_ssn);
1882 proto_tree_add_uint(call_tree, called ? hf_sccp_called_ssn
1883 : hf_sccp_calling_ssn,
1884 tvb, offset, ADDRESS_SSN_LENGTH, ssn);
1885 hidden_item = proto_tree_add_uint(call_tree, hf_sccp_ssn, tvb, offset,
1886 ADDRESS_SSN_LENGTH, ssn);
1887 PROTO_ITEM_SET_HIDDEN(hidden_item);
1889 offset += ADDRESS_SSN_LENGTH;
1891 /* Get the dissector handle of the dissector registered for this ssn
1892 * And print its name.
1894 ssn_dissector = dissector_get_uint_handle(sccp_ssn_dissector_table, ssn);
1896 if (ssn_dissector) {
1897 ssn_dissector_short_name = dissector_handle_get_short_name(ssn_dissector);
1899 if (ssn_dissector_short_name) {
1900 item = proto_tree_add_text(call_tree, tvb, offset - 1, ADDRESS_SSN_LENGTH,
1901 "Linked to %s", ssn_dissector_short_name);
1902 PROTO_ITEM_SET_GENERATED(item);
1904 if (g_ascii_strncasecmp("TCAP", ssn_dissector_short_name, 4)== 0) {
1905 tcap_ssn_dissector = get_itu_tcap_subdissector(ssn);
1907 if (tcap_ssn_dissector) {
1908 tcap_ssn_dissector_short_name = dissector_handle_get_short_name(tcap_ssn_dissector);
1909 proto_item_append_text(item,", TCAP SSN linked to %s", tcap_ssn_dissector_short_name);
1913 } /* ssn_dissector */
1916 /* Dissect GT (if present) */
1917 if (gti != AI_GTI_NO_GT) {
1918 if (length < offset)
1921 gt_tvb = tvb_new_subset(tvb, offset, (length - offset),
1923 dissect_sccp_global_title(gt_tvb, pinfo, call_tree, (length - offset), gti,
1924 (routing_ind == ROUTE_ON_GT), called);
1927 } else if (decode_mtp3_standard == ANSI_STANDARD) {
1929 proto_tree_add_uint(call_ai_tree, called ? hf_sccp_called_ansi_global_title_indicator
1930 : hf_sccp_calling_ansi_global_title_indicator,
1931 tvb, 0, ADDRESS_INDICATOR_LENGTH, gti);
1933 pci = tvb_get_guint8(tvb, 0) & ANSI_PC_INDICATOR_MASK;
1934 proto_tree_add_uint(call_ai_tree, called ? hf_sccp_called_ansi_point_code_indicator
1935 : hf_sccp_calling_ansi_point_code_indicator,
1936 tvb, 0, ADDRESS_INDICATOR_LENGTH, pci);
1938 ssni = tvb_get_guint8(tvb, 0) & ANSI_SSN_INDICATOR_MASK;
1939 expert_item = proto_tree_add_uint(call_ai_tree, called ? hf_sccp_called_ansi_ssn_indicator
1940 : hf_sccp_calling_ansi_ssn_indicator,
1941 tvb, 0, ADDRESS_INDICATOR_LENGTH, ssni);
1942 if ((routing_ind == ROUTE_ON_SSN) && (ssni == 0)) {
1943 expert_add_info_format(pinfo, expert_item, PI_PROTOCOL, PI_WARN,
1944 "Message is routed on SSN, but SSN is not present");
1947 offset = ADDRESS_INDICATOR_LENGTH;
1949 /* Dissect SSN (if present) */
1951 ssn = tvb_get_guint8(tvb, offset);
1953 if ((routing_ind == ROUTE_ON_SSN) && (ssn == 0)) {
1954 expert_add_info_format(pinfo, expert_item, PI_PROTOCOL, PI_WARN,
1955 "Message is routed on SSN, but SSN is zero (unspecified)");
1958 if (called && assoc) {
1959 assoc->called_ssn = ssn;
1961 assoc->calling_ssn = ssn;
1964 if (is_connectionless(message_type) && sccp_msg) {
1965 guint *ssn_ptr = called ? &(sccp_msg->data.ud.called_ssn) : &(sccp_msg->data.ud.calling_ssn);
1970 proto_tree_add_uint(call_tree, called ? hf_sccp_called_ssn
1971 : hf_sccp_calling_ssn,
1972 tvb, offset, ADDRESS_SSN_LENGTH, ssn);
1973 hidden_item = proto_tree_add_uint(call_tree, hf_sccp_ssn, tvb, offset,
1974 ADDRESS_SSN_LENGTH, ssn);
1975 PROTO_ITEM_SET_HIDDEN(hidden_item);
1977 offset += ADDRESS_SSN_LENGTH;
1980 /* Dissect PC (if present) */
1982 offset = dissect_sccp_3byte_pc(tvb, call_tree, offset, called);
1985 /* Dissect GT (if present) */
1986 if (gti != AI_GTI_NO_GT) {
1987 if (length < offset)
1989 gt_tvb = tvb_new_subset(tvb, offset, (length - offset),
1991 dissect_sccp_global_title(gt_tvb, pinfo, call_tree, (length - offset), gti,
1992 (routing_ind == ROUTE_ON_GT), called);
2000 dissect_sccp_called_param(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint length)
2002 dissect_sccp_called_calling_param(tvb, tree, pinfo, length, TRUE);
2006 dissect_sccp_calling_param(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint length)
2008 dissect_sccp_called_calling_param(tvb, tree, pinfo, length, FALSE);
2012 dissect_sccp_class_param(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint length)
2016 gboolean invalid_class = FALSE;
2019 pi = proto_tree_add_text(tree, tvb, 0, length, "Wrong length indicated. Expected 1, got %u", length);
2020 expert_add_info_format(pinfo, pi, PI_MALFORMED, PI_ERROR, "Wrong length indicated. Expected 1, got %u", length);
2021 PROTO_ITEM_SET_GENERATED(pi);
2025 msg_class = tvb_get_guint8(tvb, 0) & CLASS_CLASS_MASK;
2026 pi = proto_tree_add_uint(tree, hf_sccp_class, tvb, 0, length, msg_class);
2028 switch (message_type) {
2029 case SCCP_MSG_TYPE_DT1:
2031 invalid_class = TRUE;
2033 case SCCP_MSG_TYPE_DT2:
2034 case SCCP_MSG_TYPE_AK:
2035 case SCCP_MSG_TYPE_ED:
2036 case SCCP_MSG_TYPE_EA:
2037 case SCCP_MSG_TYPE_RSR:
2038 case SCCP_MSG_TYPE_RSC:
2040 invalid_class = TRUE;
2042 case SCCP_MSG_TYPE_CR:
2043 case SCCP_MSG_TYPE_CC:
2044 case SCCP_MSG_TYPE_CREF:
2045 case SCCP_MSG_TYPE_RLSD:
2046 case SCCP_MSG_TYPE_RLC:
2047 case SCCP_MSG_TYPE_ERR:
2048 case SCCP_MSG_TYPE_IT:
2049 if ((msg_class != 2) && (msg_class != 3))
2050 invalid_class = TRUE;
2052 case SCCP_MSG_TYPE_UDT:
2053 case SCCP_MSG_TYPE_UDTS:
2054 case SCCP_MSG_TYPE_XUDT:
2055 case SCCP_MSG_TYPE_XUDTS:
2056 case SCCP_MSG_TYPE_LUDT:
2057 case SCCP_MSG_TYPE_LUDTS:
2058 if ((msg_class != 0) && (msg_class != 1))
2059 invalid_class = TRUE;
2064 expert_add_info_format(pinfo, pi, PI_MALFORMED, PI_ERROR, "Unexpected message class for this message type");
2066 if (msg_class == 0 || msg_class == 1) {
2067 guint8 handling = tvb_get_guint8(tvb, 0) & CLASS_SPARE_HANDLING_MASK;
2069 pi = proto_tree_add_item(tree, hf_sccp_handling, tvb, 0, length, ENC_NA);
2070 handling >>= CLASS_SPARE_HANDLING_SHIFT;
2072 if (try_val_to_str(handling, sccp_class_handling_values) == NULL) {
2073 expert_add_info_format(pinfo, pi, PI_MALFORMED, PI_ERROR, "Invalid message handling");
2079 dissect_sccp_segmenting_reassembling_param(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint length)
2082 proto_item *expert_item;
2083 expert_item = proto_tree_add_text(tree, tvb, 0, length, "Wrong length indicated. Expected 1, got %u", length);
2084 expert_add_info_format(pinfo, expert_item, PI_MALFORMED, PI_ERROR, "Wrong length indicated. Expected 1, got %u", length);
2085 PROTO_ITEM_SET_GENERATED(expert_item);
2089 proto_tree_add_item(tree, hf_sccp_more, tvb, 0, length, ENC_BIG_ENDIAN);
2093 dissect_sccp_receive_sequence_number_param(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint length)
2098 proto_item *expert_item;
2099 expert_item = proto_tree_add_text(tree, tvb, 0, length, "Wrong length indicated. Expected 1, got %u", length);
2100 expert_add_info_format(pinfo, expert_item, PI_MALFORMED, PI_ERROR, "Wrong length indicated. Expected 1, got %u", length);
2101 PROTO_ITEM_SET_GENERATED(expert_item);
2105 rsn = tvb_get_guint8(tvb, 0) >> 1;
2106 proto_tree_add_uint(tree, hf_sccp_rsn, tvb, 0, length, rsn);
2110 dissect_sccp_sequencing_segmenting_param(tvbuff_t *tvb, proto_tree *tree, guint length)
2113 proto_item *param_item;
2114 proto_tree *param_tree;
2116 ssn = tvb_get_guint8(tvb, 0) >> 1;
2117 rsn = tvb_get_guint8(tvb, SEQUENCING_SEGMENTING_SSN_LENGTH) >> 1;
2119 param_item = proto_tree_add_text(tree, tvb, 0, length, "%s",
2120 val_to_str(PARAMETER_SEQUENCING_SEGMENTING,
2121 sccp_parameter_values, "Unknown: %d"));
2122 param_tree = proto_item_add_subtree(param_item,
2123 ett_sccp_sequencing_segmenting);
2125 proto_tree_add_uint(param_tree, hf_sccp_sequencing_segmenting_ssn, tvb, 0,
2126 SEQUENCING_SEGMENTING_SSN_LENGTH, ssn);
2127 proto_tree_add_uint(param_tree, hf_sccp_sequencing_segmenting_rsn, tvb,
2128 SEQUENCING_SEGMENTING_SSN_LENGTH,
2129 SEQUENCING_SEGMENTING_RSN_LENGTH, rsn);
2130 proto_tree_add_item(param_tree, hf_sccp_sequencing_segmenting_more, tvb,
2131 SEQUENCING_SEGMENTING_SSN_LENGTH,
2132 SEQUENCING_SEGMENTING_RSN_LENGTH, ENC_NA);
2136 dissect_sccp_credit_param(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint length)
2139 proto_item *expert_item;
2140 expert_item = proto_tree_add_text(tree, tvb, 0, length, "Wrong length indicated. Expected 1, got %u", length);
2141 expert_add_info_format(pinfo, expert_item, PI_MALFORMED, PI_ERROR,
2142 "Wrong length indicated. Expected 1, got %u", length);
2143 PROTO_ITEM_SET_GENERATED(expert_item);
2147 proto_tree_add_item(tree, hf_sccp_credit, tvb, 0, length, ENC_NA);
2151 dissect_sccp_release_cause_param(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint length)
2156 proto_item *expert_item;
2157 expert_item = proto_tree_add_text(tree, tvb, 0, length,
2158 "Wrong length indicated. Expected 1, got %u", length);
2159 expert_add_info_format(pinfo, expert_item, PI_MALFORMED, PI_ERROR,
2160 "Wrong length indicated. Expected 1, got %u", length);
2161 PROTO_ITEM_SET_GENERATED(expert_item);
2165 cause = tvb_get_guint8(tvb, 0);
2166 proto_tree_add_uint(tree, hf_sccp_release_cause, tvb, 0, length, cause);
2168 if (show_key_params)
2169 col_append_fstr(pinfo->cinfo, COL_INFO, "Cause=%d ", cause);
2173 dissect_sccp_return_cause_param(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint length)
2178 proto_item *expert_item;
2179 expert_item = proto_tree_add_text(tree, tvb, 0, length, "Wrong length indicated. Expected 1, got %u", length);
2180 expert_add_info_format(pinfo, expert_item, PI_MALFORMED, PI_ERROR,
2181 "Wrong length indicated. Expected 1, got %u", length);
2182 PROTO_ITEM_SET_GENERATED(expert_item);
2186 cause = tvb_get_guint8(tvb, 0);
2187 proto_tree_add_uint(tree, hf_sccp_return_cause, tvb, 0, length, cause);
2189 if (show_key_params)
2190 col_append_fstr(pinfo->cinfo, COL_INFO, "Cause=%d ", cause);
2194 dissect_sccp_reset_cause_param(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint length)
2199 proto_item *expert_item;
2200 expert_item = proto_tree_add_text(tree, tvb, 0, length, "Wrong length indicated. Expected 1, got %u", length);
2201 expert_add_info_format(pinfo, expert_item, PI_MALFORMED, PI_ERROR,
2202 "Wrong length indicated. Expected 1, got %u", length);
2203 PROTO_ITEM_SET_GENERATED(expert_item);
2207 cause = tvb_get_guint8(tvb, 0);
2208 proto_tree_add_uint(tree, hf_sccp_reset_cause, tvb, 0, length, cause);
2210 if (show_key_params)
2211 col_append_fstr(pinfo->cinfo, COL_INFO, "Cause=%d ", cause);
2215 dissect_sccp_error_cause_param(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint length)
2220 proto_item *expert_item;
2221 expert_item = proto_tree_add_text(tree, tvb, 0, length, "Wrong length indicated. Expected 1, got %u", length);
2222 expert_add_info_format(pinfo, expert_item, PI_MALFORMED, PI_ERROR, "Wrong length indicated. Expected 1, got %u", length);
2223 PROTO_ITEM_SET_GENERATED(expert_item);
2227 cause = tvb_get_guint8(tvb, 0);
2228 proto_tree_add_uint(tree, hf_sccp_error_cause, tvb, 0, length, cause);
2230 if (show_key_params)
2231 col_append_fstr(pinfo->cinfo, COL_INFO, "Cause=%d ", cause);
2235 dissect_sccp_refusal_cause_param(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint length)
2240 proto_item *expert_item;
2241 expert_item = proto_tree_add_text(tree, tvb, 0, length, "Wrong length indicated. Expected 1, got %u", length);
2242 expert_add_info_format(pinfo, expert_item, PI_MALFORMED, PI_ERROR, "Wrong length indicated. Expected 1, got %u", length);
2243 PROTO_ITEM_SET_GENERATED(expert_item);
2247 cause = tvb_get_guint8(tvb, 0);
2248 proto_tree_add_uint(tree, hf_sccp_refusal_cause, tvb, 0, length, cause);
2250 if (show_key_params)
2251 col_append_fstr(pinfo->cinfo, COL_INFO, "Cause=%d ", cause);
2255 /* This function is used for both data and long data (ITU only) parameters */
2257 dissect_sccp_data_param(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
2259 guint8 ssn = INVALID_SSN;
2260 guint8 other_ssn = INVALID_SSN;
2261 const mtp3_addr_pc_t *dpc = NULL;
2262 const mtp3_addr_pc_t *opc = NULL;
2264 if ((trace_sccp) && (assoc && assoc != &no_assoc)) {
2265 pinfo->sccp_info = assoc->curr_msg;
2267 pinfo->sccp_info = NULL;
2271 switch (pinfo->p2p_dir) {
2273 ssn = assoc->calling_ssn;
2274 other_ssn = assoc->called_ssn;
2275 dpc = (const mtp3_addr_pc_t*)pinfo->dst.data;
2276 opc = (const mtp3_addr_pc_t*)pinfo->src.data;
2279 ssn = assoc->called_ssn;
2280 other_ssn = assoc->calling_ssn;
2281 dpc = (const mtp3_addr_pc_t*)pinfo->src.data;
2282 opc = (const mtp3_addr_pc_t*)pinfo->dst.data;
2285 ssn = assoc->called_ssn;
2286 other_ssn = assoc->calling_ssn;
2287 dpc = (const mtp3_addr_pc_t*)pinfo->dst.data;
2288 opc = (const mtp3_addr_pc_t*)pinfo->src.data;
2294 if ((num_sccp_users) && (pinfo->src.type == AT_SS7PC)) {
2296 dissector_handle_t handle = NULL;
2297 gboolean uses_tcap = FALSE;
2299 for (i=0; i < num_sccp_users; i++) {
2300 sccp_user_t *u = &(sccp_users[i]);
2302 if (!dpc || dpc->ni != u->ni) continue;
2304 if (value_is_in_range(u->called_ssn, ssn) && value_is_in_range(u->called_pc, dpc->pc) ) {
2305 handle = *(u->handlep);
2306 uses_tcap = u->uses_tcap;
2308 } else if (value_is_in_range(u->called_ssn, other_ssn) && opc && value_is_in_range(u->called_pc, opc->pc) ) {
2309 handle = *(u->handlep);
2310 uses_tcap = u->uses_tcap;
2317 call_tcap_dissector(handle, tvb, pinfo, tree);
2319 call_dissector(handle, tvb, pinfo, tree);
2326 if ((ssn != INVALID_SSN) && dissector_try_uint(sccp_ssn_dissector_table, ssn, tvb, pinfo, tree)) {
2330 if ((other_ssn != INVALID_SSN) && dissector_try_uint(sccp_ssn_dissector_table, other_ssn, tvb, pinfo, tree)) {
2334 /* try heuristic subdissector list to see if there are any takers */
2335 if (dissector_try_heuristic(heur_subdissector_list, tvb, pinfo, tree, NULL)) {
2339 /* try user default subdissector */
2340 if (default_handle) {
2341 call_dissector(default_handle, tvb, pinfo, tree);
2345 /* No sub-dissection occurred, treat it as raw data */
2346 call_dissector(data_handle, tvb, pinfo, tree);
2351 dissect_sccp_segmentation_param(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint length)
2353 proto_item *param_item;
2354 proto_tree *param_tree;
2356 param_item = proto_tree_add_text(tree, tvb, 0, length, "%s",
2357 val_to_str(PARAMETER_SEGMENTATION,
2358 sccp_parameter_values, "Unknown: %d"));
2359 param_tree = proto_item_add_subtree(param_item, ett_sccp_segmentation);
2361 proto_tree_add_item(param_tree, hf_sccp_segmentation_first, tvb, 0, 1, ENC_NA);
2362 proto_tree_add_item(param_tree, hf_sccp_segmentation_class, tvb, 0, 1, ENC_NA);
2363 proto_tree_add_item(param_tree, hf_sccp_segmentation_remaining, tvb, 0, 1, ENC_NA);
2365 if (length-1 != 3) {
2366 proto_item *expert_item;
2367 expert_item = proto_tree_add_text(tree, tvb, 0, length-1, "Wrong length indicated. Expected 3, got %u", length-1);
2368 expert_add_info_format(pinfo, expert_item, PI_MALFORMED, PI_ERROR, "Wrong length indicated. Expected 3, got %u", length-1);
2369 PROTO_ITEM_SET_GENERATED(expert_item);
2373 proto_tree_add_item(param_tree, hf_sccp_segmentation_slr, tvb, 1, length-1, ENC_LITTLE_ENDIAN);
2377 dissect_sccp_hop_counter_param(tvbuff_t *tvb, proto_tree *tree, guint length)
2381 hops = tvb_get_guint8(tvb, 0);
2382 proto_tree_add_uint(tree, hf_sccp_hop_counter, tvb, 0, length, hops);
2386 dissect_sccp_importance_param(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint length)
2389 proto_item *expert_item;
2390 expert_item = proto_tree_add_text(tree, tvb, 0, length, "Wrong length indicated. Expected 1, got %u", length);
2391 expert_add_info_format(pinfo, expert_item, PI_MALFORMED, PI_ERROR, "Wrong length indicated. Expected 1, got %u", length);
2392 PROTO_ITEM_SET_GENERATED(expert_item);
2396 proto_tree_add_item(tree, hf_sccp_importance, tvb, 0, length, ENC_NA);
2400 dissect_sccp_isni_param(tvbuff_t *tvb, proto_tree *tree, guint length)
2404 proto_item *param_item;
2405 proto_tree *param_tree;
2407 /* Create a subtree for ISNI Routing Control */
2408 param_item = proto_tree_add_text(tree, tvb, offset, ANSI_ISNI_ROUTING_CONTROL_LENGTH,
2409 "ISNI Routing Control");
2410 param_tree = proto_item_add_subtree(param_item,
2411 ett_sccp_ansi_isni_routing_control);
2413 proto_tree_add_item(param_tree, hf_sccp_ansi_isni_mi, tvb, offset,
2414 ANSI_ISNI_ROUTING_CONTROL_LENGTH, ENC_NA);
2416 proto_tree_add_item(param_tree, hf_sccp_ansi_isni_iri, tvb, offset,
2417 ANSI_ISNI_ROUTING_CONTROL_LENGTH, ENC_NA);
2419 ti = tvb_get_guint8(tvb, offset) & ANSI_ISNI_TI_MASK;
2420 proto_tree_add_uint(param_tree, hf_sccp_ansi_isni_ti, tvb, offset,
2421 ANSI_ISNI_ROUTING_CONTROL_LENGTH, ti);
2423 proto_tree_add_item(param_tree, hf_sccp_ansi_isni_counter, tvb, offset,
2424 ANSI_ISNI_ROUTING_CONTROL_LENGTH, ENC_NA);
2426 offset += ANSI_ISNI_ROUTING_CONTROL_LENGTH;
2428 if ((ti >> ANSI_ISNI_TI_SHIFT) == ANSI_ISNI_TYPE_1) {
2429 proto_tree_add_uint(param_tree, hf_sccp_ansi_isni_netspec, tvb, offset,
2430 ANSI_ISNI_ROUTING_CONTROL_LENGTH, ti);
2431 offset += ANSI_ISNI_ROUTING_CONTROL_LENGTH;
2434 while (offset < length) {
2436 proto_tree_add_item(tree, hf_sccp_ansi_isni_network, tvb, offset,
2437 ANSI_NCM_LENGTH, ENC_NA);
2440 proto_tree_add_item(tree, hf_sccp_ansi_isni_cluster, tvb, offset,
2441 ANSI_NCM_LENGTH, ENC_NA);
2447 /* FUNCTION dissect_sccp_parameter():
2448 * Dissect a parameter given its type, offset into tvb, and length.
2451 dissect_sccp_parameter(tvbuff_t *tvb, packet_info *pinfo, proto_tree *sccp_tree,
2452 proto_tree *tree, guint8 parameter_type, guint16 offset,
2453 guint16 parameter_length)
2455 tvbuff_t *parameter_tvb;
2457 switch (parameter_type) {
2458 case PARAMETER_CALLED_PARTY_ADDRESS:
2459 case PARAMETER_CALLING_PARTY_ADDRESS:
2460 case PARAMETER_DATA:
2461 case PARAMETER_LONG_DATA:
2462 case PARAMETER_SOURCE_LOCAL_REFERENCE:
2463 case PARAMETER_DESTINATION_LOCAL_REFERENCE:
2464 case PARAMETER_RELEASE_CAUSE:
2465 case PARAMETER_RETURN_CAUSE:
2466 case PARAMETER_RESET_CAUSE:
2467 case PARAMETER_ERROR_CAUSE:
2468 case PARAMETER_REFUSAL_CAUSE:
2470 /* These parameters must be dissected even if !sccp_tree (so that
2471 * assoc information can be created).
2476 if (!sccp_tree) return(parameter_length);
2480 parameter_tvb = tvb_new_subset(tvb, offset, parameter_length, parameter_length);
2482 switch (parameter_type) {
2484 case PARAMETER_END_OF_OPTIONAL_PARAMETERS:
2485 proto_tree_add_text(sccp_tree, tvb, offset, parameter_length,
2489 case PARAMETER_DESTINATION_LOCAL_REFERENCE:
2490 dissect_sccp_dlr_param(parameter_tvb, pinfo, sccp_tree, parameter_length);
2493 case PARAMETER_SOURCE_LOCAL_REFERENCE:
2494 dissect_sccp_slr_param(parameter_tvb, pinfo, sccp_tree, parameter_length);
2497 case PARAMETER_CALLED_PARTY_ADDRESS:
2498 dissect_sccp_called_param(parameter_tvb, pinfo, sccp_tree, parameter_length);
2501 case PARAMETER_CALLING_PARTY_ADDRESS:
2502 dissect_sccp_calling_param(parameter_tvb, pinfo, sccp_tree, parameter_length);
2505 case PARAMETER_CLASS:
2506 dissect_sccp_class_param(parameter_tvb, pinfo, sccp_tree, parameter_length);
2509 case PARAMETER_SEGMENTING_REASSEMBLING:
2510 dissect_sccp_segmenting_reassembling_param(parameter_tvb, pinfo, sccp_tree,
2514 case PARAMETER_RECEIVE_SEQUENCE_NUMBER:
2515 dissect_sccp_receive_sequence_number_param(parameter_tvb, pinfo, sccp_tree,
2519 case PARAMETER_SEQUENCING_SEGMENTING:
2520 dissect_sccp_sequencing_segmenting_param(parameter_tvb, sccp_tree,
2524 case PARAMETER_CREDIT:
2525 dissect_sccp_credit_param(parameter_tvb, pinfo, sccp_tree, parameter_length);
2528 case PARAMETER_RELEASE_CAUSE:
2529 dissect_sccp_release_cause_param(parameter_tvb, pinfo, sccp_tree, parameter_length);
2532 case PARAMETER_RETURN_CAUSE:
2533 dissect_sccp_return_cause_param(parameter_tvb, pinfo, sccp_tree, parameter_length);
2536 case PARAMETER_RESET_CAUSE:
2537 dissect_sccp_reset_cause_param(parameter_tvb, pinfo, sccp_tree, parameter_length);
2540 case PARAMETER_ERROR_CAUSE:
2541 dissect_sccp_error_cause_param(parameter_tvb, pinfo, sccp_tree, parameter_length);
2544 case PARAMETER_REFUSAL_CAUSE:
2545 dissect_sccp_refusal_cause_param(parameter_tvb, pinfo, sccp_tree, parameter_length);
2548 case PARAMETER_DATA:
2549 dissect_sccp_data_param(parameter_tvb, pinfo, tree);
2551 /* TODO? Re-adjust length of SCCP item since it may be sub-dissected */
2552 /* sccp_length = proto_item_get_len(sccp_item);
2553 * sccp_length -= parameter_length;
2554 * proto_item_set_len(sccp_item, sccp_length);
2558 case PARAMETER_SEGMENTATION:
2559 dissect_sccp_segmentation_param(parameter_tvb, pinfo, sccp_tree, parameter_length);
2562 case PARAMETER_HOP_COUNTER:
2563 dissect_sccp_hop_counter_param(parameter_tvb, sccp_tree, parameter_length);
2566 case PARAMETER_IMPORTANCE:
2567 if (decode_mtp3_standard != ANSI_STANDARD)
2568 dissect_sccp_importance_param(parameter_tvb, pinfo, sccp_tree, parameter_length);
2570 dissect_sccp_unknown_param(parameter_tvb, sccp_tree, parameter_type,
2574 case PARAMETER_LONG_DATA:
2575 dissect_sccp_data_param(parameter_tvb, pinfo, tree);
2578 case PARAMETER_ISNI:
2579 if (decode_mtp3_standard != ANSI_STANDARD)
2580 dissect_sccp_unknown_param(parameter_tvb, sccp_tree, parameter_type,
2583 dissect_sccp_isni_param(parameter_tvb, sccp_tree, parameter_length);
2587 dissect_sccp_unknown_param(parameter_tvb, sccp_tree, parameter_type,
2592 return(parameter_length);
2595 /* FUNCTION dissect_sccp_variable_parameter():
2596 * Dissect a variable parameter given its type and offset into tvb. Length
2597 * of the parameter is gotten from tvb[0].
2598 * Length returned is sum of (length + parameter).
2601 dissect_sccp_variable_parameter(tvbuff_t *tvb, packet_info *pinfo,
2602 proto_tree *sccp_tree, proto_tree *tree,
2603 guint8 parameter_type, guint16 offset)
2605 guint16 parameter_length;
2606 guint8 length_length;
2609 if (parameter_type != PARAMETER_LONG_DATA) {
2610 parameter_length = tvb_get_guint8(tvb, offset);
2611 length_length = PARAMETER_LENGTH_LENGTH;
2613 /* Long data parameter has 16 bit length */
2614 parameter_length = tvb_get_letohs(tvb, offset);
2615 length_length = PARAMETER_LONG_DATA_LENGTH_LENGTH;
2618 pi = proto_tree_add_uint_format(sccp_tree, hf_sccp_param_length, tvb, offset,
2619 length_length, parameter_length, "%s length: %d",
2620 val_to_str(parameter_type, sccp_parameter_values,
2623 if (!sccp_show_length) {
2624 /* The user doesn't want to see it... */
2625 PROTO_ITEM_SET_HIDDEN(pi);
2628 offset += length_length;
2630 dissect_sccp_parameter(tvb, pinfo, sccp_tree, tree, parameter_type, offset,
2633 return(parameter_length + length_length);
2636 /* FUNCTION dissect_sccp_optional_parameters():
2637 * Dissect all the optional parameters given the start of the optional
2638 * parameters into tvb. Parameter types and lengths are read from tvb.
2641 dissect_sccp_optional_parameters(tvbuff_t *tvb, packet_info *pinfo,
2642 proto_tree *sccp_tree, proto_tree *tree,
2645 guint8 parameter_type;
2647 while ((parameter_type = tvb_get_guint8(tvb, offset)) !=
2648 PARAMETER_END_OF_OPTIONAL_PARAMETERS) {
2650 offset += PARAMETER_TYPE_LENGTH;
2651 offset += dissect_sccp_variable_parameter(tvb, pinfo, sccp_tree, tree,
2652 parameter_type, offset);
2655 /* Process end of optional parameters */
2656 dissect_sccp_parameter(tvb, pinfo, sccp_tree, tree, parameter_type, offset,
2657 END_OF_OPTIONAL_PARAMETERS_LENGTH);
2661 static sccp_msg_info_t *
2662 new_ud_msg(packet_info *pinfo, guint32 msg_type _U_)
2664 sccp_msg_info_t *m = ep_new0(sccp_msg_info_t);
2665 m->framenum = PINFO_FD_NUM(pinfo);
2666 m->data.ud.calling_gt = NULL;
2667 m->data.ud.called_gt = NULL;
2669 register_frame_end_routine(pinfo, reset_sccp_assoc);
2674 dissect_sccp_message(tvbuff_t *tvb, packet_info *pinfo, proto_tree *sccp_tree,
2677 guint16 variable_pointer1 = 0, variable_pointer2 = 0, variable_pointer3 = 0;
2678 guint16 optional_pointer = 0, orig_opt_ptr = 0;
2680 gboolean save_fragmented;
2681 tvbuff_t *new_tvb = NULL;
2682 fragment_data *frag_msg = NULL;
2683 guint32 source_local_ref = 0;
2685 guint msg_offset = tvb_offset_from_real_beginning(tvb);
2687 /* Macro for getting pointer to mandatory variable parameters */
2688 #define VARIABLE_POINTER(var, hf_var, ptr_size) \
2690 if (ptr_size == POINTER_LENGTH) \
2691 var = tvb_get_guint8(tvb, offset); \
2693 var = tvb_get_letohs(tvb, offset); \
2694 proto_tree_add_uint(sccp_tree, hf_var, tvb, \
2695 offset, ptr_size, var); \
2697 if (ptr_size == POINTER_LENGTH_LONG) \
2699 offset += ptr_size; \
2702 /* Macro for getting pointer to optional parameters */
2703 #define OPTIONAL_POINTER(ptr_size) \
2705 if (ptr_size == POINTER_LENGTH) \
2706 orig_opt_ptr = optional_pointer = tvb_get_guint8(tvb, offset); \
2708 orig_opt_ptr = optional_pointer = tvb_get_letohs(tvb, offset); \
2709 proto_tree_add_uint(sccp_tree, hf_sccp_optional_pointer, tvb, \
2710 offset, ptr_size, optional_pointer); \
2711 optional_pointer += offset; \
2712 if (ptr_size == POINTER_LENGTH_LONG) \
2713 optional_pointer += 1; \
2714 offset += ptr_size; \
2718 /* Extract the message type; all other processing is based on this */
2719 message_type = tvb_get_guint8(tvb, SCCP_MSG_TYPE_OFFSET);
2720 offset = SCCP_MSG_TYPE_LENGTH;
2722 /* Do not change col_add_fstr() to col_append_fstr() here: we _want_
2723 * this call to overwrite whatever's currently in the INFO column (e.g.,
2724 * "DATA" from the SCTP dissector).
2726 * If there's something there that should not be overwritten, whoever
2727 * put that info there should call col_set_fence() to protect it.
2729 col_add_fstr(pinfo->cinfo, COL_INFO, "%s ",
2730 val_to_str(message_type, sccp_message_type_acro_values, "Unknown: %d"));
2733 /* add the message type to the protocol tree */
2734 proto_tree_add_uint(sccp_tree, hf_sccp_message_type, tvb,
2735 SCCP_MSG_TYPE_OFFSET, SCCP_MSG_TYPE_LENGTH, message_type);
2739 /* Starting a new message dissection; clear the global assoc, SLR, and DLR values */
2744 no_assoc.calling_dpc = 0;
2745 no_assoc.called_dpc = 0;
2746 no_assoc.calling_ssn = INVALID_SSN;
2747 no_assoc.called_ssn = INVALID_SSN;
2748 no_assoc.has_fw_key = FALSE;
2749 no_assoc.has_bw_key = FALSE;
2750 no_assoc.payload = SCCP_PLOAD_NONE;
2751 no_assoc.called_party = NULL;
2752 no_assoc.calling_party = NULL;
2753 no_assoc.extra_info = NULL;
2755 switch (message_type) {
2756 case SCCP_MSG_TYPE_CR:
2757 /* TTC and NTT (Japan) say that the connection-oriented messages are
2758 * deleted (not standardized), but they appear to be used anyway, so
2759 * we'll dissect it...
2761 offset += dissect_sccp_parameter(tvb, pinfo, sccp_tree, tree,
2762 PARAMETER_SOURCE_LOCAL_REFERENCE,
2763 offset, SOURCE_LOCAL_REFERENCE_LENGTH);
2764 offset += dissect_sccp_parameter(tvb, pinfo, sccp_tree, tree,
2765 PARAMETER_CLASS, offset,
2766 PROTOCOL_CLASS_LENGTH);
2767 assoc = get_sccp_assoc(pinfo, msg_offset, slr, dlr, message_type);
2769 VARIABLE_POINTER(variable_pointer1, hf_sccp_variable_pointer1, POINTER_LENGTH);
2770 OPTIONAL_POINTER(POINTER_LENGTH);
2772 dissect_sccp_variable_parameter(tvb, pinfo, sccp_tree, tree,
2773 PARAMETER_CALLED_PARTY_ADDRESS,
2777 case SCCP_MSG_TYPE_CC:
2778 /* TODO: connection has been established; theoretically we could keep
2779 * keep track of the SLR/DLR with the called/calling from the CR and
2780 * track the connection (e.g., on subsequent messages regarding this
2781 * SLR we could set the global vars "call*_ssn" so data could get
2784 offset += dissect_sccp_parameter(tvb, pinfo, sccp_tree, tree,
2785 PARAMETER_DESTINATION_LOCAL_REFERENCE,
2787 DESTINATION_LOCAL_REFERENCE_LENGTH);
2788 offset += dissect_sccp_parameter(tvb, pinfo, sccp_tree, tree,
2789 PARAMETER_SOURCE_LOCAL_REFERENCE,
2790 offset, SOURCE_LOCAL_REFERENCE_LENGTH);
2792 assoc = get_sccp_assoc(pinfo, msg_offset, slr, dlr, message_type);
2794 offset += dissect_sccp_parameter(tvb, pinfo, sccp_tree, tree,
2795 PARAMETER_CLASS, offset,
2796 PROTOCOL_CLASS_LENGTH);
2797 OPTIONAL_POINTER(POINTER_LENGTH);
2800 case SCCP_MSG_TYPE_CREF:
2801 offset += dissect_sccp_parameter(tvb, pinfo, sccp_tree, tree,
2802 PARAMETER_DESTINATION_LOCAL_REFERENCE,
2804 DESTINATION_LOCAL_REFERENCE_LENGTH);
2806 assoc = get_sccp_assoc(pinfo, msg_offset, slr, dlr, message_type);
2808 offset += dissect_sccp_parameter(tvb, pinfo, sccp_tree, tree,
2809 PARAMETER_REFUSAL_CAUSE, offset,
2810 REFUSAL_CAUSE_LENGTH);
2811 OPTIONAL_POINTER(POINTER_LENGTH);
2814 case SCCP_MSG_TYPE_RLSD:
2815 offset += dissect_sccp_parameter(tvb, pinfo, sccp_tree, tree,
2816 PARAMETER_DESTINATION_LOCAL_REFERENCE,
2818 DESTINATION_LOCAL_REFERENCE_LENGTH);
2819 offset += dissect_sccp_parameter(tvb, pinfo, sccp_tree, tree,
2820 PARAMETER_SOURCE_LOCAL_REFERENCE,
2821 offset, SOURCE_LOCAL_REFERENCE_LENGTH);
2823 assoc = get_sccp_assoc(pinfo, msg_offset, slr, dlr, message_type);
2825 offset += dissect_sccp_parameter(tvb, pinfo, sccp_tree, tree,
2826 PARAMETER_RELEASE_CAUSE, offset,
2827 RELEASE_CAUSE_LENGTH);
2829 OPTIONAL_POINTER(POINTER_LENGTH);
2830 assoc = get_sccp_assoc(pinfo, msg_offset, slr, dlr, message_type);
2833 case SCCP_MSG_TYPE_RLC:
2834 offset += dissect_sccp_parameter(tvb, pinfo, sccp_tree, tree,
2835 PARAMETER_DESTINATION_LOCAL_REFERENCE,
2837 DESTINATION_LOCAL_REFERENCE_LENGTH);
2838 offset += dissect_sccp_parameter(tvb, pinfo, sccp_tree, tree,
2839 PARAMETER_SOURCE_LOCAL_REFERENCE,
2840 offset, SOURCE_LOCAL_REFERENCE_LENGTH);
2842 assoc = get_sccp_assoc(pinfo, msg_offset, slr, dlr, message_type);
2845 case SCCP_MSG_TYPE_DT1:
2846 source_local_ref = tvb_get_letoh24(tvb, offset);
2847 offset += dissect_sccp_parameter(tvb, pinfo, sccp_tree, tree,
2848 PARAMETER_DESTINATION_LOCAL_REFERENCE,
2850 DESTINATION_LOCAL_REFERENCE_LENGTH);
2852 assoc = get_sccp_assoc(pinfo, msg_offset, slr, dlr, message_type);
2854 more = tvb_get_guint8(tvb, offset) & SEGMENTING_REASSEMBLING_MASK;
2856 offset += dissect_sccp_parameter(tvb, pinfo, sccp_tree, tree,
2857 PARAMETER_SEGMENTING_REASSEMBLING,
2858 offset, SEGMENTING_REASSEMBLING_LENGTH);
2859 VARIABLE_POINTER(variable_pointer1, hf_sccp_variable_pointer1, POINTER_LENGTH);
2862 if (!sccp_xudt_desegment) {
2863 proto_tree_add_text(sccp_tree, tvb, variable_pointer1,
2864 tvb_get_guint8(tvb, variable_pointer1)+1,
2866 dissect_sccp_variable_parameter(tvb, pinfo, sccp_tree, tree,
2867 PARAMETER_DATA, variable_pointer1);
2870 save_fragmented = pinfo->fragmented;
2871 pinfo->fragmented = TRUE;
2872 frag_msg = fragment_add_seq_next(&sccp_xudt_msg_reassembly_table,
2873 tvb, variable_pointer1 + 1,
2875 source_local_ref, /* ID for fragments belonging together */
2877 tvb_get_guint8(tvb,variable_pointer1), /* fragment length - to the end */
2878 more); /* More fragments? */
2880 new_tvb = process_reassembled_data(tvb, variable_pointer1 + 1, pinfo,
2881 "Reassembled SCCP", frag_msg,
2882 &sccp_xudt_msg_frag_items, NULL,
2885 if (frag_msg && frag_msg->next) { /* Reassembled */
2886 col_append_str(pinfo->cinfo, COL_INFO, "(Message reassembled) ");
2887 } else if (more) { /* Not last packet of reassembled message */
2888 col_append_str(pinfo->cinfo, COL_INFO, "(Message fragment) ");
2891 pinfo->fragmented = save_fragmented;
2894 dissect_sccp_data_param(new_tvb, pinfo, tree);
2897 /* End reassemble */
2900 case SCCP_MSG_TYPE_DT2:
2901 offset += dissect_sccp_parameter(tvb, pinfo, sccp_tree, tree,
2902 PARAMETER_DESTINATION_LOCAL_REFERENCE,
2904 DESTINATION_LOCAL_REFERENCE_LENGTH);
2906 assoc = get_sccp_assoc(pinfo, msg_offset, slr, dlr, message_type);
2908 offset += dissect_sccp_parameter(tvb, pinfo, sccp_tree, tree,
2909 PARAMETER_SEQUENCING_SEGMENTING, offset,
2910 SEQUENCING_SEGMENTING_LENGTH);
2913 case SCCP_MSG_TYPE_AK:
2914 offset += dissect_sccp_parameter(tvb, pinfo, sccp_tree, tree,
2915 PARAMETER_DESTINATION_LOCAL_REFERENCE,
2917 DESTINATION_LOCAL_REFERENCE_LENGTH);
2919 assoc = get_sccp_assoc(pinfo, msg_offset, slr, dlr, message_type);
2921 offset += dissect_sccp_parameter(tvb, pinfo, sccp_tree, tree,
2922 PARAMETER_RECEIVE_SEQUENCE_NUMBER,
2923 offset, RECEIVE_SEQUENCE_NUMBER_LENGTH);
2924 offset += dissect_sccp_parameter(tvb, pinfo, sccp_tree, tree,
2925 PARAMETER_CREDIT, offset, CREDIT_LENGTH);
2928 case SCCP_MSG_TYPE_UDT:
2929 pinfo->sccp_info = sccp_msg = new_ud_msg(pinfo,message_type);
2931 offset += dissect_sccp_parameter(tvb, pinfo, sccp_tree, tree,
2932 PARAMETER_CLASS, offset,
2933 PROTOCOL_CLASS_LENGTH);
2934 VARIABLE_POINTER(variable_pointer1, hf_sccp_variable_pointer1, POINTER_LENGTH);
2935 VARIABLE_POINTER(variable_pointer2, hf_sccp_variable_pointer2, POINTER_LENGTH);
2936 VARIABLE_POINTER(variable_pointer3, hf_sccp_variable_pointer3, POINTER_LENGTH);
2938 assoc = get_sccp_assoc(pinfo, msg_offset, slr, dlr, message_type);
2940 dissect_sccp_variable_parameter(tvb, pinfo, sccp_tree, tree,
2941 PARAMETER_CALLED_PARTY_ADDRESS,
2943 dissect_sccp_variable_parameter(tvb, pinfo, sccp_tree, tree,
2944 PARAMETER_CALLING_PARTY_ADDRESS,
2947 dissect_sccp_variable_parameter(tvb, pinfo, sccp_tree, tree, PARAMETER_DATA,
2951 case SCCP_MSG_TYPE_UDTS:
2953 gboolean save_in_error_pkt = pinfo->flags.in_error_pkt;
2954 pinfo->flags.in_error_pkt = TRUE;
2956 pinfo->sccp_info = sccp_msg = new_ud_msg(pinfo,message_type);
2958 offset += dissect_sccp_parameter(tvb, pinfo, sccp_tree, tree,
2959 PARAMETER_RETURN_CAUSE, offset,
2960 RETURN_CAUSE_LENGTH);
2962 VARIABLE_POINTER(variable_pointer1, hf_sccp_variable_pointer1, POINTER_LENGTH);
2963 VARIABLE_POINTER(variable_pointer2, hf_sccp_variable_pointer2, POINTER_LENGTH);
2964 VARIABLE_POINTER(variable_pointer3, hf_sccp_variable_pointer3, POINTER_LENGTH);
2966 assoc = get_sccp_assoc(pinfo, msg_offset, slr, dlr, message_type);
2968 dissect_sccp_variable_parameter(tvb, pinfo, sccp_tree, tree,
2969 PARAMETER_CALLED_PARTY_ADDRESS,
2972 dissect_sccp_variable_parameter(tvb, pinfo, sccp_tree, tree,
2973 PARAMETER_CALLING_PARTY_ADDRESS,
2976 dissect_sccp_variable_parameter(tvb, pinfo, sccp_tree, tree, PARAMETER_DATA,
2978 pinfo->flags.in_error_pkt = save_in_error_pkt;
2982 case SCCP_MSG_TYPE_ED:
2983 offset += dissect_sccp_parameter(tvb, pinfo, sccp_tree, tree,
2984 PARAMETER_DESTINATION_LOCAL_REFERENCE,
2986 DESTINATION_LOCAL_REFERENCE_LENGTH);
2988 assoc = get_sccp_assoc(pinfo, msg_offset, slr, dlr, message_type);
2990 VARIABLE_POINTER(variable_pointer1, hf_sccp_variable_pointer1, POINTER_LENGTH);
2992 dissect_sccp_variable_parameter(tvb, pinfo, sccp_tree, tree, PARAMETER_DATA,
2996 case SCCP_MSG_TYPE_EA:
2997 offset += dissect_sccp_parameter(tvb, pinfo, sccp_tree, tree,
2998 PARAMETER_DESTINATION_LOCAL_REFERENCE,
3000 DESTINATION_LOCAL_REFERENCE_LENGTH);
3001 assoc = get_sccp_assoc(pinfo, msg_offset, slr, dlr, message_type);
3004 case SCCP_MSG_TYPE_RSR:
3005 offset += dissect_sccp_parameter(tvb, pinfo, sccp_tree, tree,
3006 PARAMETER_DESTINATION_LOCAL_REFERENCE,
3008 DESTINATION_LOCAL_REFERENCE_LENGTH);
3009 offset += dissect_sccp_parameter(tvb, pinfo, sccp_tree, tree,
3010 PARAMETER_SOURCE_LOCAL_REFERENCE,
3011 offset, SOURCE_LOCAL_REFERENCE_LENGTH);
3012 offset += dissect_sccp_parameter(tvb, pinfo, sccp_tree, tree,
3013 PARAMETER_RESET_CAUSE, offset,
3014 RESET_CAUSE_LENGTH);
3015 assoc = get_sccp_assoc(pinfo, msg_offset, slr, dlr, message_type);
3018 case SCCP_MSG_TYPE_RSC:
3019 offset += dissect_sccp_parameter(tvb, pinfo, sccp_tree, tree,
3020 PARAMETER_DESTINATION_LOCAL_REFERENCE,
3022 DESTINATION_LOCAL_REFERENCE_LENGTH);
3023 offset += dissect_sccp_parameter(tvb, pinfo, sccp_tree, tree,
3024 PARAMETER_SOURCE_LOCAL_REFERENCE,
3025 offset, SOURCE_LOCAL_REFERENCE_LENGTH);
3026 assoc = get_sccp_assoc(pinfo, msg_offset, slr, dlr, message_type);
3029 case SCCP_MSG_TYPE_ERR:
3030 offset += dissect_sccp_parameter(tvb, pinfo, sccp_tree, tree,
3031 PARAMETER_DESTINATION_LOCAL_REFERENCE,
3033 DESTINATION_LOCAL_REFERENCE_LENGTH);
3034 offset += dissect_sccp_parameter(tvb, pinfo, sccp_tree, tree,
3035 PARAMETER_ERROR_CAUSE, offset,
3036 ERROR_CAUSE_LENGTH);
3037 assoc = get_sccp_assoc(pinfo, msg_offset, slr, dlr, message_type);
3040 case SCCP_MSG_TYPE_IT:
3041 offset += dissect_sccp_parameter(tvb, pinfo, sccp_tree, tree,
3042 PARAMETER_DESTINATION_LOCAL_REFERENCE,
3044 DESTINATION_LOCAL_REFERENCE_LENGTH);
3045 offset += dissect_sccp_parameter(tvb, pinfo, sccp_tree, tree,
3046 PARAMETER_SOURCE_LOCAL_REFERENCE,
3047 offset, SOURCE_LOCAL_REFERENCE_LENGTH);
3048 assoc = get_sccp_assoc(pinfo, msg_offset, slr, dlr, message_type);
3049 offset += dissect_sccp_parameter(tvb, pinfo, sccp_tree, tree,
3050 PARAMETER_CLASS, offset,
3051 PROTOCOL_CLASS_LENGTH);
3052 offset += dissect_sccp_parameter(tvb, pinfo, sccp_tree, tree,
3053 PARAMETER_SEQUENCING_SEGMENTING,
3054 offset, SEQUENCING_SEGMENTING_LENGTH);
3055 offset += dissect_sccp_parameter(tvb, pinfo, sccp_tree, tree,
3056 PARAMETER_CREDIT, offset, CREDIT_LENGTH);
3059 case SCCP_MSG_TYPE_XUDT:
3060 pinfo->sccp_info = sccp_msg = new_ud_msg(pinfo,message_type);
3061 offset += dissect_sccp_parameter(tvb, pinfo, sccp_tree, tree,
3062 PARAMETER_CLASS, offset,
3063 PROTOCOL_CLASS_LENGTH);
3064 offset += dissect_sccp_parameter(tvb, pinfo, sccp_tree, tree,
3065 PARAMETER_HOP_COUNTER, offset,
3066 HOP_COUNTER_LENGTH);
3068 VARIABLE_POINTER(variable_pointer1, hf_sccp_variable_pointer1, POINTER_LENGTH);
3069 VARIABLE_POINTER(variable_pointer2, hf_sccp_variable_pointer2, POINTER_LENGTH);
3070 VARIABLE_POINTER(variable_pointer3, hf_sccp_variable_pointer3, POINTER_LENGTH);
3071 OPTIONAL_POINTER(POINTER_LENGTH);
3073 /* Optional parameters are Segmentation and Importance
3074 * NOTE 2 - Segmentation Should not be present in case of a single XUDT
3078 assoc = get_sccp_assoc(pinfo, msg_offset, slr, dlr, message_type);
3080 dissect_sccp_variable_parameter(tvb, pinfo, sccp_tree, tree,
3081 PARAMETER_CALLED_PARTY_ADDRESS,
3083 dissect_sccp_variable_parameter(tvb, pinfo, sccp_tree, tree,
3084 PARAMETER_CALLING_PARTY_ADDRESS,
3087 if (tvb_get_guint8(tvb, optional_pointer) == PARAMETER_SEGMENTATION) {
3088 if (!sccp_xudt_desegment) {
3089 proto_tree_add_text(sccp_tree, tvb, variable_pointer3, tvb_get_guint8(tvb, variable_pointer3)+1, "Segmented Data");
3092 gboolean more_frag = TRUE;
3094 /* Get the first octet of parameter Segmentation, Ch 3.17 in Q.713
3095 * Bit 8 of octet 1 is used for First segment indication
3096 * Bit 7 of octet 1 is used to keep in the message in sequence
3097 * delivery option required by the SCCP user
3098 * Bits 6 and 5 in octet 1 are spare bits.
3099 * Bits 4-1 of octet 1 are used to indicate the number of
3100 * remaining segments.
3101 * The values 0000 to 1111 are possible; the value 0000 indicates
3104 octet = tvb_get_guint8(tvb,optional_pointer+2);
3105 source_local_ref = tvb_get_letoh24(tvb, optional_pointer+3);
3107 if ((octet & 0x0f) == 0)
3110 save_fragmented = pinfo->fragmented;
3111 pinfo->fragmented = TRUE;
3112 frag_msg = fragment_add_seq_next(&sccp_xudt_msg_reassembly_table,
3113 tvb, variable_pointer3 + 1,
3115 source_local_ref, /* ID for fragments belonging together */
3117 tvb_get_guint8(tvb,variable_pointer3), /* fragment length - to the end */
3118 more_frag); /* More fragments? */
3120 if ((octet & 0x80) == 0x80) /*First segment, set number of segments*/
3121 fragment_set_tot_len(&sccp_xudt_msg_reassembly_table,
3122 pinfo, source_local_ref, NULL, (octet & 0xf));
3124 new_tvb = process_reassembled_data(tvb, variable_pointer3 + 1,
3125 pinfo, "Reassembled SCCP",
3127 &sccp_xudt_msg_frag_items,
3130 if (frag_msg) { /* Reassembled */
3131 col_append_str(pinfo->cinfo, COL_INFO,"(Message reassembled) ");
3132 } else { /* Not last packet of reassembled message */
3133 col_append_str(pinfo->cinfo, COL_INFO,"(Message fragment) ");
3136 pinfo->fragmented = save_fragmented;
3139 dissect_sccp_data_param(new_tvb, pinfo, tree);
3142 dissect_sccp_variable_parameter(tvb, pinfo, sccp_tree, tree,
3143 PARAMETER_DATA, variable_pointer3);
3147 case SCCP_MSG_TYPE_XUDTS:
3149 gboolean save_in_error_pkt = pinfo->flags.in_error_pkt;
3150 pinfo->flags.in_error_pkt = TRUE;
3152 pinfo->sccp_info = sccp_msg = new_ud_msg(pinfo,message_type);
3153 offset += dissect_sccp_parameter(tvb, pinfo, sccp_tree, tree,
3154 PARAMETER_RETURN_CAUSE, offset,
3155 RETURN_CAUSE_LENGTH);
3156 offset += dissect_sccp_parameter(tvb, pinfo, sccp_tree, tree,
3157 PARAMETER_HOP_COUNTER, offset,
3158 HOP_COUNTER_LENGTH);
3160 VARIABLE_POINTER(variable_pointer1, hf_sccp_variable_pointer1, POINTER_LENGTH);
3161 VARIABLE_POINTER(variable_pointer2, hf_sccp_variable_pointer2, POINTER_LENGTH);
3162 VARIABLE_POINTER(variable_pointer3, hf_sccp_variable_pointer3, POINTER_LENGTH);
3163 OPTIONAL_POINTER(POINTER_LENGTH);
3165 assoc = get_sccp_assoc(pinfo, msg_offset, slr, dlr, message_type);
3167 dissect_sccp_variable_parameter(tvb, pinfo, sccp_tree, tree,
3168 PARAMETER_CALLED_PARTY_ADDRESS,
3170 dissect_sccp_variable_parameter(tvb, pinfo, sccp_tree, tree,
3171 PARAMETER_CALLING_PARTY_ADDRESS,
3174 if (tvb_get_guint8(tvb, optional_pointer) == PARAMETER_SEGMENTATION) {
3175 if (!sccp_xudt_desegment) {
3176 proto_tree_add_text(sccp_tree, tvb, variable_pointer3, tvb_get_guint8(tvb, variable_pointer3)+1, "Segmented Data");
3180 gboolean more_frag = TRUE;
3183 /* Get the first octet of parameter Segmentation, Ch 3.17 in Q.713
3184 * Bit 8 of octet 1 is used for First segment indication
3185 * Bit 7 of octet 1 is used to keep in the message in sequence
3186 * delivery option required by the SCCP user
3187 * Bits 6 and 5 in octet 1 are spare bits.
3188 * Bits 4-1 of octet 1 are used to indicate the number of
3189 * remaining segments.
3190 * The values 0000 to 1111 are possible; the value 0000 indicates
3193 octet = tvb_get_guint8(tvb,optional_pointer+2);
3194 source_local_ref = tvb_get_letoh24(tvb, optional_pointer+3);
3196 if ((octet & 0x0f) == 0)
3199 save_fragmented = pinfo->fragmented;
3200 pinfo->fragmented = TRUE;
3201 frag_msg = fragment_add_seq_next(&sccp_xudt_msg_reassembly_table,
3202 tvb, variable_pointer3 + 1,
3204 source_local_ref, /* ID for fragments belonging together */
3206 tvb_get_guint8(tvb,variable_pointer3), /* fragment length - to the end */
3207 more_frag); /* More fragments? */
3209 if ((octet & 0x80) == 0x80) /*First segment, set number of segments*/
3210 fragment_set_tot_len(&sccp_xudt_msg_reassembly_table,
3211 pinfo, source_local_ref, NULL, (octet & 0xf));
3213 new_tvb = process_reassembled_data(tvb, variable_pointer3 + 1,
3214 pinfo, "Reassembled SCCP",
3216 &sccp_xudt_msg_frag_items,
3219 if (frag_msg) { /* Reassembled */
3220 col_append_str(pinfo->cinfo, COL_INFO, "(Message reassembled) ");
3221 } else { /* Not last packet of reassembled message */
3222 col_append_str(pinfo->cinfo, COL_INFO, "(Message fragment) ");
3225 pinfo->fragmented = save_fragmented;
3228 dissect_sccp_data_param(new_tvb, pinfo, tree);
3231 dissect_sccp_variable_parameter(tvb, pinfo, sccp_tree, tree,
3232 PARAMETER_DATA, variable_pointer3);
3234 pinfo->flags.in_error_pkt = save_in_error_pkt;
3237 case SCCP_MSG_TYPE_LUDT:
3238 pinfo->sccp_info = sccp_msg = new_ud_msg(pinfo,message_type);
3240 offset += dissect_sccp_parameter(tvb, pinfo, sccp_tree, tree,
3241 PARAMETER_CLASS, offset,
3242 PROTOCOL_CLASS_LENGTH);
3243 offset += dissect_sccp_parameter(tvb, pinfo, sccp_tree, tree,
3244 PARAMETER_HOP_COUNTER, offset,
3245 HOP_COUNTER_LENGTH);
3247 VARIABLE_POINTER(variable_pointer1, hf_sccp_variable_pointer1, POINTER_LENGTH_LONG);
3248 VARIABLE_POINTER(variable_pointer2, hf_sccp_variable_pointer2, POINTER_LENGTH_LONG);
3249 VARIABLE_POINTER(variable_pointer3, hf_sccp_variable_pointer3, POINTER_LENGTH_LONG);
3250 OPTIONAL_POINTER(POINTER_LENGTH_LONG);
3252 assoc = get_sccp_assoc(pinfo, msg_offset, slr, dlr, message_type);
3254 dissect_sccp_variable_parameter(tvb, pinfo, sccp_tree, tree,
3255 PARAMETER_CALLED_PARTY_ADDRESS,
3257 dissect_sccp_variable_parameter(tvb, pinfo, sccp_tree, tree,
3258 PARAMETER_CALLING_PARTY_ADDRESS,
3260 dissect_sccp_variable_parameter(tvb, pinfo, sccp_tree, tree,
3261 PARAMETER_LONG_DATA, variable_pointer3);
3264 case SCCP_MSG_TYPE_LUDTS:
3265 pinfo->sccp_info = sccp_msg = new_ud_msg(pinfo,message_type);
3266 offset += dissect_sccp_parameter(tvb, pinfo, sccp_tree, tree,
3267 PARAMETER_RETURN_CAUSE, offset,
3268 RETURN_CAUSE_LENGTH);
3269 offset += dissect_sccp_parameter(tvb, pinfo, sccp_tree, tree,
3270 PARAMETER_HOP_COUNTER, offset,
3271 HOP_COUNTER_LENGTH);
3273 VARIABLE_POINTER(variable_pointer1, hf_sccp_variable_pointer1, POINTER_LENGTH_LONG);
3274 VARIABLE_POINTER(variable_pointer2, hf_sccp_variable_pointer2, POINTER_LENGTH_LONG);
3275 VARIABLE_POINTER(variable_pointer3, hf_sccp_variable_pointer3, POINTER_LENGTH_LONG);
3276 OPTIONAL_POINTER(POINTER_LENGTH_LONG);
3278 assoc = get_sccp_assoc(pinfo, msg_offset, slr, dlr, message_type);
3280 dissect_sccp_variable_parameter(tvb, pinfo, sccp_tree, tree,
3281 PARAMETER_CALLED_PARTY_ADDRESS,
3283 dissect_sccp_variable_parameter(tvb, pinfo, sccp_tree, tree,
3284 PARAMETER_CALLING_PARTY_ADDRESS,
3286 dissect_sccp_variable_parameter(tvb, pinfo, sccp_tree, tree,
3287 PARAMETER_LONG_DATA, variable_pointer3);
3291 dissect_sccp_unknown_message(tvb, sccp_tree);
3295 dissect_sccp_optional_parameters(tvb, pinfo, sccp_tree, tree,
3298 if (trace_sccp && assoc && (assoc != &no_assoc)) {
3299 proto_item *pi = proto_tree_add_uint(sccp_tree, hf_sccp_assoc_id, tvb, 0, 0, assoc->id);
3300 proto_tree *pt = proto_item_add_subtree(pi, ett_sccp_assoc);
3301 PROTO_ITEM_SET_GENERATED(pi);
3304 for(m = assoc->msgs; m ; m = m->data.co.next) {
3305 pi = proto_tree_add_uint(pt, hf_sccp_assoc_msg, tvb, 0, 0, m->framenum);
3307 if (assoc->payload != SCCP_PLOAD_NONE)
3308 proto_item_append_text(pi," %s", val_to_str(assoc->payload, assoc_protos, "Unknown: %d"));
3310 if (m->data.co.label)
3311 proto_item_append_text(pi," %s", m->data.co.label);
3313 if ((m->framenum == PINFO_FD_NUM(pinfo)) && (m->offset == msg_offset) ) {
3314 tap_queue_packet(sccp_tap, pinfo, m);
3315 proto_item_append_text(pi," (current)");
3317 PROTO_ITEM_SET_GENERATED(pi);
3326 dissect_sccp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
3328 proto_item *sccp_item = NULL;
3329 proto_tree *sccp_tree = NULL;
3330 const mtp3_addr_pc_t *mtp3_addr_p;
3332 if ((pinfo->src.type == AT_SS7PC) &&
3333 ((mtp3_addr_p = (const mtp3_addr_pc_t *)pinfo->src.data)->type <= CHINESE_ITU_STANDARD)) {
3335 * Allow a protocol beneath to specify how the SCCP layer should be
3338 * It is possible to have multiple sets of SCCP traffic some of which is
3339 * ITU and some of which is ANSI.
3340 * An example is A-interface traffic having ANSI MTP3/ANSI SCCP/3GPP2 IOS
3341 * and at the same time ITU MTP3/ITU SCCP/ANSI TCAP/ANSI MAP.
3343 decode_mtp3_standard = mtp3_addr_p->type;
3345 decode_mtp3_standard = (Standard_Type)mtp3_standard;
3348 /* Make entry in the Protocol column on summary display */
3349 switch (decode_mtp3_standard) {
3351 col_set_str(pinfo->cinfo, COL_PROTOCOL, "SCCP (Int. ITU)");
3354 col_set_str(pinfo->cinfo, COL_PROTOCOL, "SCCP (ANSI)");
3356 case CHINESE_ITU_STANDARD:
3357 col_set_str(pinfo->cinfo, COL_PROTOCOL, "SCCP (Chin. ITU)");
3359 case JAPAN_STANDARD:
3360 col_set_str(pinfo->cinfo, COL_PROTOCOL, "SCCP (Japan)");
3364 /* In the interest of speed, if "tree" is NULL, don't do any work not
3365 necessary to generate protocol tree items. */
3367 /* create the sccp protocol tree */
3368 sccp_item = proto_tree_add_item(tree, proto_sccp, tvb, 0, -1, ENC_NA);
3369 sccp_tree = proto_item_add_subtree(sccp_item, ett_sccp);
3372 /* Set whether message is UPLINK, DOWNLINK, or of UNKNOWN direction */
3374 if (pinfo->src.type == AT_SS7PC) {
3376 * XXX - we assume that the "data" pointers of the source and destination
3377 * addresses are set to point to "mtp3_addr_pc_t" structures, so that
3378 * we can safely cast them.
3380 mtp3_addr_p = (const mtp3_addr_pc_t *)pinfo->src.data;
3382 if (sccp_source_pc_global == mtp3_addr_p->pc) {
3383 pinfo->p2p_dir = P2P_DIR_SENT;
3385 /* assuming if src was SS7 PC then dst will be too */
3386 mtp3_addr_p = (const mtp3_addr_pc_t *)pinfo->dst.data;
3388 if (sccp_source_pc_global == mtp3_addr_p->pc)
3390 pinfo->p2p_dir = P2P_DIR_RECV;
3392 pinfo->p2p_dir = P2P_DIR_UNKNOWN;
3397 /* dissect the message */
3398 dissect_sccp_message(tvb, pinfo, sccp_tree, tree);
3402 /*** SccpUsers Table **/
3404 static struct _sccp_ul {
3407 dissector_handle_t *handlep;
3410 {SCCP_USER_DATA, FALSE, &data_handle},
3411 {SCCP_USER_TCAP, FALSE, &tcap_handle},
3412 {SCCP_USER_RANAP, FALSE, &ranap_handle},
3413 {SCCP_USER_BSSAP, FALSE, &bssap_handle},
3414 {SCCP_USER_GSMMAP, TRUE, &gsmmap_handle},
3415 {SCCP_USER_CAMEL, TRUE, &camel_handle},
3416 {SCCP_USER_INAP, TRUE, &inap_handle},
3421 sccp_users_update_cb(void *r, const char **err _U_)
3423 sccp_user_t *u = (sccp_user_t *)r;
3426 for (c=user_list; c->handlep; c++) {
3427 if (c->id == u->user) {
3428 u->uses_tcap = c->uses_tcap;
3429 u->handlep = c->handlep;
3434 u->uses_tcap = FALSE;
3435 u->handlep = &data_handle;
3439 sccp_users_copy_cb(void *n, const void *o, size_t siz _U_)
3441 const sccp_user_t *u = (const sccp_user_t *)o;
3442 sccp_user_t *un = (sccp_user_t *)n;
3446 un->uses_tcap = u->uses_tcap;
3447 un->handlep = u->handlep;
3450 un->called_pc = range_copy(u->called_pc);
3452 un->called_ssn = range_copy(u->called_ssn);
3458 sccp_users_free_cb(void *r)
3460 sccp_user_t *u = (sccp_user_t *)r;
3461 if (u->called_pc) g_free(u->called_pc);
3462 if (u->called_ssn) g_free(u->called_ssn);
3466 UAT_DEC_CB_DEF(sccp_users, ni, sccp_user_t)
3467 UAT_RANGE_CB_DEF(sccp_users, called_pc,sccp_user_t)
3468 UAT_RANGE_CB_DEF(sccp_users, called_ssn,sccp_user_t)
3469 UAT_VS_DEF(sccp_users, user, sccp_user_t, guint, SCCP_USER_DATA, "Data")
3471 /** End SccpUsersTable **/
3478 reassembly_table_init (&sccp_xudt_msg_reassembly_table,
3479 &addresses_reassembly_table_functions);
3482 /* Register the protocol with Wireshark */
3484 proto_register_sccp(void)
3486 /* Setup list of header fields */
3487 static hf_register_info hf[] = {
3488 { &hf_sccp_message_type,
3489 { "Message Type", "sccp.message_type",
3490 FT_UINT8, BASE_HEX, VALS(sccp_message_type_values), 0x0,
3493 { &hf_sccp_variable_pointer1,
3494 { "Pointer to first Mandatory Variable parameter", "sccp.variable_pointer1",
3495 FT_UINT16, BASE_DEC, NULL, 0x0,
3498 { &hf_sccp_variable_pointer2,
3499 { "Pointer to second Mandatory Variable parameter", "sccp.variable_pointer2",
3500 FT_UINT16, BASE_DEC, NULL, 0x0,
3503 { &hf_sccp_variable_pointer3,
3504 { "Pointer to third Mandatory Variable parameter", "sccp.variable_pointer3",
3505 FT_UINT16, BASE_DEC, NULL, 0x0,
3508 { &hf_sccp_optional_pointer,
3509 { "Pointer to Optional parameter", "sccp.optional_pointer",
3510 FT_UINT16, BASE_DEC, NULL, 0x0,
3513 { &hf_sccp_param_length,
3514 { "Variable parameter length", "sccp.parameter_length",
3515 FT_UINT16, BASE_DEC, NULL, 0x0,
3519 { "Called or Calling SubSystem Number", "sccp.ssn",
3520 FT_UINT8, BASE_DEC, VALS(sccp_ssn_values), 0x0,
3523 { &hf_sccp_gt_digits,
3524 { "Called or Calling GT Digits", "sccp.digits",
3525 FT_STRING, BASE_NONE, NULL, 0x0,
3528 { &hf_sccp_called_ansi_national_indicator,
3529 { "National Indicator", "sccp.called.ni",
3530 FT_UINT8, BASE_HEX, VALS(sccp_ansi_national_indicator_values), ANSI_NATIONAL_MASK,
3533 { &hf_sccp_called_itu_natl_use_bit,
3534 { "Reserved for national use", "sccp.called.reserved",
3535 FT_UINT8, BASE_HEX, NULL, ITU_RESERVED_MASK,
3538 { &hf_sccp_called_routing_indicator,
3539 { "Routing Indicator", "sccp.called.ri",
3540 FT_UINT8, BASE_HEX, VALS(sccp_routing_indicator_values), ROUTING_INDICATOR_MASK,
3543 { &hf_sccp_called_itu_global_title_indicator,
3544 { "Global Title Indicator", "sccp.called.gti",
3545 FT_UINT8, BASE_HEX, VALS(sccp_itu_global_title_indicator_values), GTI_MASK,
3548 { &hf_sccp_called_ansi_global_title_indicator,
3549 { "Global Title Indicator", "sccp.called.gti",
3550 FT_UINT8, BASE_HEX, VALS(sccp_ansi_global_title_indicator_values), GTI_MASK,
3553 { &hf_sccp_called_itu_ssn_indicator,
3554 { "SubSystem Number Indicator", "sccp.called.ssni",
3555 FT_UINT8, BASE_HEX, VALS(sccp_ai_ssni_values), ITU_SSN_INDICATOR_MASK,
3558 { &hf_sccp_called_itu_point_code_indicator,
3559 { "Point Code Indicator", "sccp.called.pci",
3560 FT_UINT8, BASE_HEX, VALS(sccp_ai_pci_values), ITU_PC_INDICATOR_MASK,
3563 { &hf_sccp_called_ansi_ssn_indicator,
3564 { "SubSystem Number Indicator", "sccp.called.ssni",
3565 FT_UINT8, BASE_HEX, VALS(sccp_ai_ssni_values), ANSI_SSN_INDICATOR_MASK,
3568 { &hf_sccp_called_ansi_point_code_indicator,
3569 { "Point Code Indicator", "sccp.called.pci",
3570 FT_UINT8, BASE_HEX, VALS(sccp_ai_pci_values), ANSI_PC_INDICATOR_MASK,
3573 { &hf_sccp_called_ssn,
3574 { "SubSystem Number", "sccp.called.ssn",
3575 FT_UINT8, BASE_DEC, VALS(sccp_ssn_values), 0x0,
3578 { &hf_sccp_called_itu_pc,
3579 { "PC", "sccp.called.pc",
3580 FT_UINT16, BASE_DEC, NULL, ITU_PC_MASK,
3583 { &hf_sccp_called_ansi_pc,
3584 { "PC", "sccp.called.ansi_pc",
3585 FT_STRING, BASE_NONE, NULL, 0x0,
3588 { &hf_sccp_called_chinese_pc,
3589 { "PC", "sccp.called.chinese_pc",
3590 FT_STRING, BASE_NONE, NULL, 0x0,
3593 { &hf_sccp_called_japan_pc,
3594 { "PC", "sccp.called.pc",
3595 FT_UINT16, BASE_DEC, NULL, 0x0,
3598 { &hf_sccp_called_pc_network,
3599 { "PC Network", "sccp.called.network",
3600 FT_UINT24, BASE_DEC, NULL, ANSI_NETWORK_MASK,
3603 { &hf_sccp_called_pc_cluster,
3604 { "PC Cluster", "sccp.called.cluster",
3605 FT_UINT24, BASE_DEC, NULL, ANSI_CLUSTER_MASK,
3608 { &hf_sccp_called_pc_member,
3609 { "PC Member", "sccp.called.member",
3610 FT_UINT24, BASE_DEC, NULL, ANSI_MEMBER_MASK,
3613 { &hf_sccp_called_gt_nai,
3614 { "Nature of Address Indicator", "sccp.called.nai",
3615 FT_UINT8, BASE_HEX, VALS(sccp_nai_values), GT_NAI_MASK,
3618 { &hf_sccp_called_gt_oe,
3619 { "Odd/Even Indicator", "sccp.called.oe",
3620 FT_UINT8, BASE_HEX, VALS(sccp_oe_values), GT_OE_MASK,
3623 { &hf_sccp_called_gt_tt,
3624 { "Translation Type", "sccp.called.tt",
3625 FT_UINT8, BASE_HEX, NULL, 0x0,
3628 { &hf_sccp_called_gt_np,
3629 { "Numbering Plan", "sccp.called.np",
3630 FT_UINT8, BASE_HEX, VALS(sccp_np_values), GT_NP_MASK,
3633 { &hf_sccp_called_gt_es,
3634 { "Encoding Scheme", "sccp.called.es",
3635 FT_UINT8, BASE_HEX, VALS(sccp_es_values), GT_ES_MASK,
3638 { &hf_sccp_called_gt_digits,
3639 { "Called Party Digits", "sccp.called.digits",
3640 FT_STRING, BASE_NONE, NULL, 0x0,
3643 { &hf_sccp_called_gt_digits_length,
3644 { "Number of Called Party Digits", "sccp.called.digits.length",
3645 FT_UINT8, BASE_DEC, NULL, 0x0,
3648 { &hf_sccp_calling_ansi_national_indicator,
3649 { "National Indicator", "sccp.calling.ni",
3650 FT_UINT8, BASE_HEX, VALS(sccp_ansi_national_indicator_values), ANSI_NATIONAL_MASK,
3653 { &hf_sccp_calling_itu_natl_use_bit,
3654 { "Reserved for national use", "sccp.calling.reserved",
3655 FT_UINT8, BASE_HEX, NULL, ITU_RESERVED_MASK,
3658 { &hf_sccp_calling_routing_indicator,
3659 { "Routing Indicator", "sccp.calling.ri",
3660 FT_UINT8, BASE_HEX, VALS(sccp_routing_indicator_values), ROUTING_INDICATOR_MASK,
3663 { &hf_sccp_calling_itu_global_title_indicator,
3664 { "Global Title Indicator", "sccp.calling.gti",
3665 FT_UINT8, BASE_HEX, VALS(sccp_itu_global_title_indicator_values), GTI_MASK,
3668 { &hf_sccp_calling_ansi_global_title_indicator,
3669 { "Global Title Indicator", "sccp.calling.gti",
3670 FT_UINT8, BASE_HEX, VALS(sccp_ansi_global_title_indicator_values), GTI_MASK,
3673 { &hf_sccp_calling_itu_ssn_indicator,
3674 { "SubSystem Number Indicator", "sccp.calling.ssni",
3675 FT_UINT8, BASE_HEX, VALS(sccp_ai_ssni_values), ITU_SSN_INDICATOR_MASK,
3678 { &hf_sccp_calling_itu_point_code_indicator,
3679 { "Point Code Indicator", "sccp.calling.pci",
3680 FT_UINT8, BASE_HEX, VALS(sccp_ai_pci_values), ITU_PC_INDICATOR_MASK,
3683 { &hf_sccp_calling_ansi_ssn_indicator,
3684 { "SubSystem Number Indicator", "sccp.calling.ssni",
3685 FT_UINT8, BASE_HEX, VALS(sccp_ai_ssni_values), ANSI_SSN_INDICATOR_MASK,
3688 { &hf_sccp_calling_ansi_point_code_indicator,
3689 { "Point Code Indicator", "sccp.calling.pci",
3690 FT_UINT8, BASE_HEX, VALS(sccp_ai_pci_values), ANSI_PC_INDICATOR_MASK,
3693 { &hf_sccp_calling_ssn,
3694 { "SubSystem Number", "sccp.calling.ssn",
3695 FT_UINT8, BASE_DEC, VALS(sccp_ssn_values), 0x0,
3698 { &hf_sccp_calling_itu_pc,
3699 { "PC", "sccp.calling.pc",
3700 FT_UINT16, BASE_DEC, NULL, ITU_PC_MASK,
3703 { &hf_sccp_calling_ansi_pc,
3704 { "PC", "sccp.calling.ansi_pc",
3705 FT_STRING, BASE_NONE, NULL, 0x0,
3708 { &hf_sccp_calling_chinese_pc,
3709 { "PC", "sccp.calling.chinese_pc",
3710 FT_STRING, BASE_NONE, NULL, 0x0,
3713 { &hf_sccp_calling_japan_pc,
3714 { "PC", "sccp.calling.pc",
3715 FT_UINT16, BASE_DEC, NULL, 0x0,
3718 { &hf_sccp_calling_pc_network,
3719 { "PC Network", "sccp.calling.network",
3720 FT_UINT24, BASE_DEC, NULL, ANSI_NETWORK_MASK,
3723 { &hf_sccp_calling_pc_cluster,
3724 { "PC Cluster", "sccp.calling.cluster",
3725 FT_UINT24, BASE_DEC, NULL, ANSI_CLUSTER_MASK,
3728 { &hf_sccp_calling_pc_member,
3729 { "PC Member", "sccp.calling.member",
3730 FT_UINT24, BASE_DEC, NULL, ANSI_MEMBER_MASK,
3733 { &hf_sccp_calling_gt_nai,
3734 { "Nature of Address Indicator", "sccp.calling.nai",
3735 FT_UINT8, BASE_HEX, VALS(sccp_nai_values), GT_NAI_MASK,
3738 { &hf_sccp_calling_gt_oe,
3739 { "Odd/Even Indicator", "sccp.calling.oe",
3740 FT_UINT8, BASE_HEX, VALS(sccp_oe_values), GT_OE_MASK,
3743 { &hf_sccp_calling_gt_tt,
3744 { "Translation Type", "sccp.calling.tt",
3745 FT_UINT8, BASE_HEX, NULL, 0x0,
3748 { &hf_sccp_calling_gt_np,
3749 { "Numbering Plan", "sccp.calling.np",
3750 FT_UINT8, BASE_HEX, VALS(sccp_np_values), GT_NP_MASK,
3753 { &hf_sccp_calling_gt_es,
3754 { "Encoding Scheme", "sccp.calling.es",
3755 FT_UINT8, BASE_HEX, VALS(sccp_es_values), GT_ES_MASK,
3758 { &hf_sccp_calling_gt_digits,
3759 { "Calling Party Digits", "sccp.calling.digits",
3760 FT_STRING, BASE_NONE, NULL, 0x0,
3763 { &hf_sccp_calling_gt_digits_length,
3764 { "Number of Calling Party Digits", "sccp.calling.digits.length",
3765 FT_UINT8, BASE_DEC, NULL, 0x0,
3769 { "Destination Local Reference", "sccp.dlr",
3770 FT_UINT24, BASE_HEX, NULL, 0x0,
3774 { "Source Local Reference", "sccp.slr",
3775 FT_UINT24, BASE_HEX, NULL, 0x0,
3779 { "Local Reference", "sccp.lr",
3780 FT_UINT24, BASE_HEX, NULL, 0x0,
3784 { "Class", "sccp.class",
3785 FT_UINT8, BASE_HEX, NULL, CLASS_CLASS_MASK,
3788 { &hf_sccp_handling,
3789 { "Message handling", "sccp.handling",
3790 FT_UINT8, BASE_HEX, VALS(sccp_class_handling_values), CLASS_SPARE_HANDLING_MASK,
3794 { "More data", "sccp.more",
3795 FT_UINT8, BASE_HEX, VALS(sccp_segmenting_reassembling_values), SEGMENTING_REASSEMBLING_MASK,
3799 { "Receive Sequence Number", "sccp.rsn",
3800 FT_UINT8, BASE_HEX, NULL, RSN_MASK,
3803 { &hf_sccp_sequencing_segmenting_ssn,
3804 { "Sequencing Segmenting: Send Sequence Number", "sccp.sequencing_segmenting.ssn",
3805 FT_UINT8, BASE_HEX, NULL, SEND_SEQUENCE_NUMBER_MASK,
3808 { &hf_sccp_sequencing_segmenting_rsn,
3809 { "Sequencing Segmenting: Receive Sequence Number", "sccp.sequencing_segmenting.rsn",
3810 FT_UINT8, BASE_HEX, NULL, RECEIVE_SEQUENCE_NUMBER_MASK,
3813 { &hf_sccp_sequencing_segmenting_more,
3814 { "Sequencing Segmenting: More", "sccp.sequencing_segmenting.more",
3815 FT_UINT8, BASE_HEX, VALS(sccp_segmenting_reassembling_values), SEQUENCING_SEGMENTING_MORE_MASK,
3819 { "Credit", "sccp.credit",
3820 FT_UINT8, BASE_HEX, NULL, 0x0,
3823 { &hf_sccp_release_cause,
3824 { "Release Cause", "sccp.release_cause",
3825 FT_UINT8, BASE_HEX, VALS(sccp_release_cause_values), 0x0,
3828 { &hf_sccp_return_cause,
3829 { "Return Cause", "sccp.return_cause",
3830 FT_UINT8, BASE_HEX, VALS(sccp_return_cause_values), 0x0,
3833 { &hf_sccp_reset_cause,
3834 { "Reset Cause", "sccp.reset_cause",
3835 FT_UINT8, BASE_HEX, VALS(sccp_reset_cause_values), 0x0,
3838 { &hf_sccp_error_cause,
3839 { "Error Cause", "sccp.error_cause",
3840 FT_UINT8, BASE_HEX, VALS(sccp_error_cause_values), 0x0,
3843 { &hf_sccp_refusal_cause,
3844 { "Refusal Cause", "sccp.refusal_cause",
3845 FT_UINT8, BASE_HEX, VALS(sccp_refusal_cause_values), 0x0,
3848 { &hf_sccp_segmentation_first,
3849 { "Segmentation: First", "sccp.segmentation.first",
3850 FT_UINT8, BASE_HEX, VALS(sccp_segmentation_first_segment_values), SEGMENTATION_FIRST_SEGMENT_MASK,
3853 { &hf_sccp_segmentation_class,
3854 { "Segmentation: Class", "sccp.segmentation.class",
3855 FT_UINT8, BASE_HEX, VALS(sccp_segmentation_class_values), SEGMENTATION_CLASS_MASK,
3858 { &hf_sccp_segmentation_remaining,
3859 { "Segmentation: Remaining", "sccp.segmentation.remaining",
3860 FT_UINT8, BASE_HEX, NULL, SEGMENTATION_REMAINING_MASK,
3863 { &hf_sccp_segmentation_slr,
3864 { "Segmentation: Source Local Reference", "sccp.segmentation.slr",
3865 FT_UINT24, BASE_HEX, NULL, 0x0,
3868 { &hf_sccp_hop_counter,
3869 { "Hop Counter", "sccp.hops",
3870 FT_UINT8, BASE_HEX, NULL, 0x0,
3873 { &hf_sccp_importance,
3874 { "Importance", "sccp.importance",
3875 FT_UINT8, BASE_HEX, NULL, IMPORTANCE_IMPORTANCE_MASK,
3878 /* ISNI is ANSI only */
3879 { &hf_sccp_ansi_isni_mi,
3880 { "ISNI Mark for Identification Indicator", "sccp.isni.mi",
3881 FT_UINT8, BASE_HEX, VALS(sccp_isni_mark_for_id_values), ANSI_ISNI_MI_MASK,
3884 { &hf_sccp_ansi_isni_iri,
3885 { "ISNI Routing Indicator", "sccp.isni.iri",
3886 FT_UINT8, BASE_HEX, VALS(sccp_isni_iri_values), ANSI_ISNI_IRI_MASK,
3889 { &hf_sccp_ansi_isni_ti,
3890 { "ISNI Type Indicator", "sccp.isni.ti",
3891 FT_UINT8, BASE_HEX, VALS(sccp_isni_ti_values), ANSI_ISNI_TI_MASK,
3894 { &hf_sccp_ansi_isni_netspec,
3895 { "ISNI Network Specific (Type 1)", "sccp.isni.netspec",
3896 FT_UINT8, BASE_HEX, NULL, ANSI_ISNI_NETSPEC_MASK,
3899 { &hf_sccp_ansi_isni_counter,
3900 { "ISNI Counter", "sccp.isni.counter",
3901 FT_UINT8, BASE_DEC, NULL, ANSI_ISNI_COUNTER_MASK,
3904 { &hf_sccp_ansi_isni_network,
3905 { "Network ID network", "sccp.isni.network",
3906 FT_UINT8, BASE_DEC, NULL, 0x0,
3909 { &hf_sccp_ansi_isni_cluster,
3910 { "Network ID cluster", "sccp.isni.cluster",
3911 FT_UINT8, BASE_DEC, NULL, 0x0,
3914 {&hf_sccp_xudt_msg_fragments,
3915 { "Message fragments", "sccp.msg.fragments",
3916 FT_NONE, BASE_NONE, NULL, 0x00,
3919 {&hf_sccp_xudt_msg_fragment,
3920 { "Message fragment", "sccp.msg.fragment",
3921 FT_FRAMENUM, BASE_NONE, NULL, 0x00,
3924 {&hf_sccp_xudt_msg_fragment_overlap,
3925 { "Message fragment overlap", "sccp.msg.fragment.overlap",
3926 FT_BOOLEAN, BASE_NONE, NULL, 0x0,
3929 {&hf_sccp_xudt_msg_fragment_overlap_conflicts,
3930 { "Message fragment overlapping with conflicting data", "sccp.msg.fragment.overlap.conflicts",
3931 FT_BOOLEAN, BASE_NONE, NULL, 0x0,
3934 {&hf_sccp_xudt_msg_fragment_multiple_tails,
3935 { "Message has multiple tail fragments", "sccp.msg.fragment.multiple_tails",
3936 FT_BOOLEAN, BASE_NONE, NULL, 0x0,
3939 {&hf_sccp_xudt_msg_fragment_too_long_fragment,
3940 { "Message fragment too long", "sccp.msg.fragment.too_long_fragment",
3941 FT_BOOLEAN, BASE_NONE, NULL, 0x0,
3944 {&hf_sccp_xudt_msg_fragment_error,
3945 { "Message defragmentation error", "sccp.msg.fragment.error",
3946 FT_FRAMENUM, BASE_NONE, NULL, 0x00,
3949 {&hf_sccp_xudt_msg_fragment_count,
3950 { "Message fragment count", "sccp.msg.fragment.count",
3951 FT_UINT32, BASE_DEC, NULL, 0x00,
3954 {&hf_sccp_xudt_msg_reassembled_in,
3955 { "Reassembled in", "sccp.msg.reassembled.in",
3956 FT_FRAMENUM, BASE_NONE, NULL, 0x00,
3959 {&hf_sccp_xudt_msg_reassembled_length,
3960 { "Reassembled SCCP length", "sccp.msg.reassembled.length",
3961 FT_UINT32, BASE_DEC, NULL, 0x00,
3964 { &hf_sccp_assoc_id,
3965 { "Association ID", "sccp.assoc.id",
3966 FT_UINT32, BASE_DEC, NULL, 0x0,
3969 {&hf_sccp_assoc_msg,
3970 { "Message in frame", "sccp.assoc.msg",
3971 FT_FRAMENUM, BASE_NONE, NULL, 0x00,
3976 /* Setup protocol subtree array */
3977 static gint *ett[] = {
3980 &ett_sccp_called_ai,
3981 &ett_sccp_called_pc,
3982 &ett_sccp_called_gt,
3983 &ett_sccp_called_gt_digits,
3985 &ett_sccp_calling_ai,
3986 &ett_sccp_calling_pc,
3987 &ett_sccp_calling_gt,
3988 &ett_sccp_calling_gt_digits,
3989 &ett_sccp_sequencing_segmenting,
3990 &ett_sccp_segmentation,
3991 &ett_sccp_ansi_isni_routing_control,
3992 &ett_sccp_xudt_msg_fragment,
3993 &ett_sccp_xudt_msg_fragments,
3998 static uat_field_t users_flds[] = {
3999 UAT_FLD_DEC(sccp_users, ni, "Network Indicator", "Network Indicator"),
4000 UAT_FLD_RANGE(sccp_users, called_pc, "Called DPCs", 0xFFFFFF, "DPCs for which this protocol is to be used"),
4001 UAT_FLD_RANGE(sccp_users, called_ssn, "Called SSNs", 255, "Called SSNs for which this protocol is to be used"),
4002 UAT_FLD_VS(sccp_users, user, "User protocol", sccp_users_vals, "The User Protocol"),
4007 uat_t *users_uat = uat_new("SCCP Users Table", sizeof(sccp_user_t),
4008 "sccp_users", TRUE, (void**) &sccp_users,
4009 &num_sccp_users, UAT_AFFECTS_DISSECTION,
4010 "ChSccpUsers", sccp_users_copy_cb,
4011 sccp_users_update_cb, sccp_users_free_cb,
4014 /* Register the protocol name and description */
4015 proto_sccp = proto_register_protocol("Signalling Connection Control Part",
4018 register_dissector("sccp", dissect_sccp, proto_sccp);
4020 /* Required function calls to register the header fields and subtrees used */
4021 proto_register_field_array(proto_sccp, hf, array_length(hf));
4022 proto_register_subtree_array(ett, array_length(ett));
4025 sccp_ssn_dissector_table = register_dissector_table("sccp.ssn", "SCCP SSN", FT_UINT8, BASE_DEC);
4027 register_heur_dissector_list("sccp", &heur_subdissector_list);
4029 sccp_module = prefs_register_protocol(proto_sccp, proto_reg_handoff_sccp);
4031 prefs_register_uint_preference(sccp_module, "source_pc",
4032 "Source PC (in hex)",
4033 "The source point code (usually MSC) (to determine whether message is uplink or downlink)",
4034 16, &sccp_source_pc_global);
4036 prefs_register_bool_preference(sccp_module, "show_length", "Show length",
4037 "Show parameter length in the protocol tree",
4040 prefs_register_bool_preference(sccp_module, "defragment_xudt",
4041 "Reassemble XUDT messages",
4042 "Whether XUDT messages should be reassembled",
4043 &sccp_xudt_desegment);
4045 prefs_register_bool_preference(sccp_module, "trace_sccp",
4046 "Trace Associations",
4047 "Whether to keep information about messages and their associations",
4051 prefs_register_bool_preference(sccp_module, "show_more_info",
4052 "Show key parameters in Info Column",
4053 "Show SLR, DLR, and CAUSE Parameters in the Information Column of the Summary",
4057 prefs_register_uat_preference(sccp_module, "users_table", "Users Table",
4058 "A table that enumerates user protocols to be used against specific PCs and SSNs",
4061 prefs_register_bool_preference(sccp_module, "set_addresses", "Set source and destination GT addresses",
4062 "Set the source and destination addresses to the GT digits (if RI=GT)."
4063 " This may affect TCAP's ability to recognize which messages belong to which TCAP session.",
4066 prefs_register_string_preference(sccp_module, "default_payload", "Default Payload",
4067 "The protocol which should be used to dissect the payload if nothing else has claimed it",
4070 register_init_routine(&init_sccp);
4072 assocs = se_tree_create(EMEM_TREE_TYPE_RED_BLACK, "sccp_associations");
4074 sccp_tap = register_tap("sccp");
4079 proto_reg_handoff_sccp(void)
4081 dissector_handle_t sccp_handle;
4083 static gboolean initialised = FALSE;
4086 sccp_handle = find_dissector("sccp");
4088 dissector_add_uint("wtap_encap", WTAP_ENCAP_SCCP, sccp_handle);
4089 dissector_add_uint("mtp3.service_indicator", MTP_SI_SCCP, sccp_handle);
4090 dissector_add_string("tali.opcode", "sccp", sccp_handle);
4092 data_handle = find_dissector("data");
4093 tcap_handle = find_dissector("tcap");
4094 ranap_handle = find_dissector("ranap");
4095 bssap_handle = find_dissector("bssap");
4096 gsmmap_handle = find_dissector("gsm_map");
4097 camel_handle = find_dissector("camel");
4098 inap_handle = find_dissector("inap");
4103 default_handle = find_dissector(default_payload);