1 /* packet-sccp.c
2 * Routines for Signalling Connection Control Part (SCCP) dissection
3 *
4 * It is hopefully compliant to:
5 * ANSI T1.112.3-2001
6 * ITU-T Q.713 7/1996
7 * YDN 038-1997 (Chinese ITU variant)
8 * JT-Q713 and NTT-Q713 (Japan)
9 *
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.
12 *
13 * Copyright 2002, Jeff Morriss <jeff.morriss.ws [AT] gmail.com>
14 *
15 * Wireshark - Network traffic analyzer
16 * By Gerald Combs <gerald@wireshark.org>
17 * Copyright 1998 Gerald Combs
18 *
19 * Copied from packet-m2pa.c
20 *
21 * SPDX-License-Identifier: GPL-2.0-or-later
22 */
23
24
25 #include "config.h"
26
27
28 #include <epan/packet.h>
29 #include <epan/prefs.h>
30 #include <epan/reassemble.h>
31 #include <epan/address_types.h>
32 #include <epan/asn1.h>
33 #include <epan/uat.h>
34 #include <epan/expert.h>
35 #include <epan/tap.h>
36 #include <epan/to_str.h>
37 #include <epan/decode_as.h>
38 #include <epan/proto_data.h>
39 #include <wiretap/wtap.h>
40 #include <wsutil/str_util.h>
41 #include "packet-mtp3.h"
42 #include "packet-tcap.h"
43 #include "packet-sccp.h"
44 #include "packet-e164.h"
45 #include "packet-e212.h"
46
47 /* function prototypes */
48 void proto_register_sccp(void);
49 void proto_reg_handoff_sccp(void);
50
51 static Standard_Type decode_mtp3_standard;
52
53 #define SCCP_MSG_TYPE_OFFSET 0
54 #define SCCP_MSG_TYPE_LENGTH 1
55 #define POINTER_LENGTH 1
56 #define POINTER_LENGTH_LONG 2
57
58 /* Same as below but with names typed out */
59 static const value_string sccp_message_type_values[] = {
60 { SCCP_MSG_TYPE_CR, "Connection Request" },
61 { SCCP_MSG_TYPE_CC, "Connection Confirm" },
62 { SCCP_MSG_TYPE_CREF, "Connection Refused" },
63 { SCCP_MSG_TYPE_RLSD, "Released" },
64 { SCCP_MSG_TYPE_RLC, "Release Complete" },
65 { SCCP_MSG_TYPE_DT1, "Data Form 1" },
66 { SCCP_MSG_TYPE_DT2, "Data Form 2" },
67 { SCCP_MSG_TYPE_AK, "Data Acknowledgement" },
68 { SCCP_MSG_TYPE_UDT, "Unitdata" },
69 { SCCP_MSG_TYPE_UDTS, "Unitdata Service" },
70 { SCCP_MSG_TYPE_ED, "Expedited Data" },
71 { SCCP_MSG_TYPE_EA, "Expedited Data Acknowledgement" },
72 { SCCP_MSG_TYPE_RSR, "Reset Request" },
73 { SCCP_MSG_TYPE_RSC, "Reset Confirmation" },
74 { SCCP_MSG_TYPE_ERR, "Error" },
75 { SCCP_MSG_TYPE_IT, "Inactivity Timer" },
76 { SCCP_MSG_TYPE_XUDT, "Extended Unitdata" },
77 { SCCP_MSG_TYPE_XUDTS, "Extended Unitdata Service" },
78 { SCCP_MSG_TYPE_LUDT, "Long Unitdata" },
79 { SCCP_MSG_TYPE_LUDTS, "Long Unitdata Service" },
80 { 0, NULL } };
81
82 /* Same as above but in acronym form (for the Info column) */
83 const value_string sccp_message_type_acro_values[] = {
84 { SCCP_MSG_TYPE_CR, "CR" },
85 { SCCP_MSG_TYPE_CC, "CC" },
86 { SCCP_MSG_TYPE_CREF, "CREF" },
87 { SCCP_MSG_TYPE_RLSD, "RLSD" },
88 { SCCP_MSG_TYPE_RLC, "RLC" },
89 { SCCP_MSG_TYPE_DT1, "DT1" },
90 { SCCP_MSG_TYPE_DT2, "DT2" },
91 { SCCP_MSG_TYPE_AK, "AK" },
92 { SCCP_MSG_TYPE_UDT, "UDT" },
93 { SCCP_MSG_TYPE_UDTS, "UDTS" },
94 { SCCP_MSG_TYPE_ED, "ED" },
95 { SCCP_MSG_TYPE_EA, "EA" },
96 { SCCP_MSG_TYPE_RSR, "RSR" },
97 { SCCP_MSG_TYPE_RSC, "RSC" },
98 { SCCP_MSG_TYPE_ERR, "ERR" },
99 { SCCP_MSG_TYPE_IT, "IT" },
100 { SCCP_MSG_TYPE_XUDT, "XUDT" },
101 { SCCP_MSG_TYPE_XUDTS, "XUDTS" },
102 { SCCP_MSG_TYPE_LUDT, "LUDT" },
103 { SCCP_MSG_TYPE_LUDTS, "LUDTS" },
104 { 0, NULL } };
105
106 #define PARAMETER_LENGTH_LENGTH 1
107 #define PARAMETER_LONG_DATA_LENGTH_LENGTH 2
108 #define PARAMETER_TYPE_LENGTH 1
109
110 #define PARAMETER_END_OF_OPTIONAL_PARAMETERS 0x00
111 #define PARAMETER_DESTINATION_LOCAL_REFERENCE 0x01
112 #define PARAMETER_SOURCE_LOCAL_REFERENCE 0x02
113 #define PARAMETER_CALLED_PARTY_ADDRESS 0x03
114 #define PARAMETER_CALLING_PARTY_ADDRESS 0x04
115 #define PARAMETER_CLASS 0x05
116 #define PARAMETER_SEGMENTING_REASSEMBLING 0x06
117 #define PARAMETER_RECEIVE_SEQUENCE_NUMBER 0x07
118 #define PARAMETER_SEQUENCING_SEGMENTING 0x08
119 #define PARAMETER_CREDIT 0x09
120 #define PARAMETER_RELEASE_CAUSE 0x0a
121 #define PARAMETER_RETURN_CAUSE 0x0b
122 #define PARAMETER_RESET_CAUSE 0x0c
123 #define PARAMETER_ERROR_CAUSE 0x0d
124 #define PARAMETER_REFUSAL_CAUSE 0x0e
125 #define PARAMETER_DATA 0x0f
126 #define PARAMETER_SEGMENTATION 0x10
127 #define PARAMETER_HOP_COUNTER 0x11
128 /* Importance is ITU only */
129 #define PARAMETER_IMPORTANCE 0x12
130 #define PARAMETER_LONG_DATA 0x13
131 /* ISNI is ANSI only */
132 #define PARAMETER_ISNI 0xfa
133
134 static const value_string sccp_parameter_values[] = {
135 { PARAMETER_END_OF_OPTIONAL_PARAMETERS, "End of Optional Parameters" },
136 { PARAMETER_DESTINATION_LOCAL_REFERENCE, "Destination Local Reference" },
137 { PARAMETER_SOURCE_LOCAL_REFERENCE, "Source Local Reference" },
138 { PARAMETER_CALLED_PARTY_ADDRESS, "Called Party Address" },
139 { PARAMETER_CALLING_PARTY_ADDRESS, "Calling Party Address" },
140 { PARAMETER_CLASS, "Protocol Class" },
141 { PARAMETER_SEGMENTING_REASSEMBLING, "Segmenting/Reassembling" },
142 { PARAMETER_RECEIVE_SEQUENCE_NUMBER, "Receive Sequence Number" },
143 { PARAMETER_SEQUENCING_SEGMENTING, "Sequencing/Segmenting" },
144 { PARAMETER_CREDIT, "Credit" },
145 { PARAMETER_RELEASE_CAUSE, "Release Cause" },
146 { PARAMETER_RETURN_CAUSE, "Return Cause" },
147 { PARAMETER_RESET_CAUSE, "Reset Cause" },
148 { PARAMETER_ERROR_CAUSE, "Error Cause" },
149 { PARAMETER_REFUSAL_CAUSE, "Refusal Cause" },
150 { PARAMETER_DATA, "Data" },
151 { PARAMETER_SEGMENTATION, "Segmentation" },
152 { PARAMETER_HOP_COUNTER, "Hop Counter" },
153 { PARAMETER_IMPORTANCE, "Importance (ITU)" },
154 { PARAMETER_LONG_DATA, "Long Data" },
155 { PARAMETER_ISNI, "Intermediate Signaling Network Identification (ANSI)" },
156 { 0, NULL } };
157
158
159 #define END_OF_OPTIONAL_PARAMETERS_LENGTH 1
160 #define DESTINATION_LOCAL_REFERENCE_LENGTH 3
161 #define SOURCE_LOCAL_REFERENCE_LENGTH 3
162 #define PROTOCOL_CLASS_LENGTH 1
163 #define RECEIVE_SEQUENCE_NUMBER_LENGTH 1
164 #define CREDIT_LENGTH 1
165 #define RELEASE_CAUSE_LENGTH 1
166 #define RETURN_CAUSE_LENGTH 1
167 #define RESET_CAUSE_LENGTH 1
168 #define ERROR_CAUSE_LENGTH 1
169 #define REFUSAL_CAUSE_LENGTH 1
170 #define HOP_COUNTER_LENGTH 1
171 #define IMPORTANCE_LENGTH 1
172
173
174 /* Parts of the Called and Calling Address parameters */
175 /* Address Indicator */
176 #define ADDRESS_INDICATOR_LENGTH 1
177 #define ITU_RESERVED_MASK 0x80
178 #define ANSI_NATIONAL_MASK 0x80
179 #define ROUTING_INDICATOR_MASK 0x40
180 #define GTI_MASK 0x3C
181 #define GTI_SHIFT 2
182 #define ITU_SSN_INDICATOR_MASK 0x02
183 #define ITU_PC_INDICATOR_MASK 0x01
184 #define ANSI_PC_INDICATOR_MASK 0x02
185 #define ANSI_SSN_INDICATOR_MASK 0x01
186
187 static const value_string sccp_ansi_national_indicator_values[] = {
188 { 0x0, "Address coded to International standard" },
189 { 0x1, "Address coded to National standard" },
190 { 0, NULL } };
191
192 #define ROUTE_ON_GT 0x0
193 #define ROUTE_ON_SSN 0x1
194 #define ROUTING_INDICATOR_SHIFT 6
195 static const value_string sccp_routing_indicator_values[] = {
196 { ROUTE_ON_GT, "Route on GT" },
197 { ROUTE_ON_SSN, "Route on SSN" },
198 { 0, NULL } };
199
200 #define AI_GTI_NO_GT 0x0
201 #define ITU_AI_GTI_NAI 0x1
202 #define AI_GTI_TT 0x2
203 #define ITU_AI_GTI_TT_NP_ES 0x3
204 #define ITU_AI_GTI_TT_NP_ES_NAI 0x4
205 static const value_string sccp_itu_global_title_indicator_values[] = {
206 { AI_GTI_NO_GT, "No Global Title" },
207 { ITU_AI_GTI_NAI, "Nature of Address Indicator only" },
208 { AI_GTI_TT, "Translation Type only" },
209 { ITU_AI_GTI_TT_NP_ES, "Translation Type, Numbering Plan, and Encoding Scheme included" },
210 { ITU_AI_GTI_TT_NP_ES_NAI, "Translation Type, Numbering Plan, Encoding Scheme, and Nature of Address Indicator included" },
211 { 0, NULL } };
212
213 /* #define AI_GTI_NO_GT 0x0 */
214 #define ANSI_AI_GTI_TT_NP_ES 0x1
215 /* #define AI_GTI_TT 0x2 */
216 static const value_string sccp_ansi_global_title_indicator_values[] = {
217 { AI_GTI_NO_GT, "No Global Title" },
218 { ANSI_AI_GTI_TT_NP_ES, "Translation Type, Numbering Plan, and Encoding Scheme included" },
219 { AI_GTI_TT, "Translation Type only" },
220 { 0, NULL } };
221
222 static const value_string sccp_ai_pci_values[] = {
223 { 0x1, "Point Code present" },
224 { 0x0, "Point Code not present" },
225 { 0, NULL } };
226
227 static const value_string sccp_ai_ssni_values[] = {
228 { 0x1, "SSN present" },
229 { 0x0, "SSN not present" },
230 { 0, NULL } };
231
232 #define ADDRESS_SSN_LENGTH 1
233 #define INVALID_SSN 0xff
234 /* Some values from 3GPP TS 23.003 */
235 /* Japan TTC and NTT define a lot of SSNs, some of which conflict with
236 * these. They are not added for now.
237 */
238 static const value_string sccp_ssn_values[] = {
239 { 0x00, "SSN not known/not used" },
240 { 0x01, "SCCP management" },
241 { 0x02, "Reserved for ITU-T allocation" },
242 { 0x03, "ISDN User Part" },
243 { 0x04, "OMAP (Operation, Maintenance, and Administration Part)" },
244 { 0x05, "MAP (Mobile Application Part)" },
245 { 0x06, "HLR (Home Location Register)" },
246 { 0x07, "VLR (Visitor Location Register)" },
247 { 0x08, "MSC (Mobile Switching Center)" },
248 { 0x09, "EIC/EIR (Equipment Identifier Center/Equipment Identification Register)" },
249 { 0x0a, "AUC/AC (Authentication Center)" },
250 { 0x0b, "ISDN supplementary services (ITU only)" },
251 { 0x0c, "Reserved for international use (ITU only)" },
252 { 0x0d, "Broadband ISDN edge-to-edge applications (ITU only)" },
253 { 0x0e, "TC test responder (ITU only)" },
254 /* The following national network subsystem numbers have been allocated for use within and
255 * between GSM/UMTS networks:
256 */
257 { 0x8e, "RANAP" },
258 { 0x8f, "RNSAP" },
259 { 0x91, "GMLC(MAP)" },
260 { 0x92, "CAP" },
261 { 0x93, "gsmSCF (MAP) or IM-SSF (MAP) or Presence Network Agent" },
262 { 0x94, "SIWF (MAP)" },
263 { 0x95, "SGSN (MAP)" },
264 { 0x96, "GGSN (MAP)" },
265 /* The following national network subsystem numbers have been allocated for use within GSM/UMTS networks:*/
266 { 0xf8, "CSS (MAP)" },
267 { 0xf9, "PCAP" },
268 { 0xfa, "BSC (BSSAP-LE)" },
269 { 0xfb, "MSC (BSSAP-LE)" },
270 { 0xfc, "IOS or SMLC (BSSAP-LE)" },
271 { 0xfd, "BSS O&M (A interface)" },
272 { 0xfe, "BSSAP/BSAP" },
273 { 0, NULL } };
274
275
276 /* * * * * * * * * * * * * * * * *
277 * Global Title: ITU GTI == 0001 *
278 * * * * * * * * * * * * * * * * */
279 #define GT_NAI_MASK 0x7F
280 #define GT_NAI_LENGTH 1
281 #define GT_NAI_UNKNOWN 0x00
282 #define GT_NAI_SUBSCRIBER_NUMBER 0x01
283 #define GT_NAI_RESERVED_NATIONAL 0x02
284 #define GT_NAI_NATIONAL_SIG_NUM 0x03
285 #define GT_NAI_INTERNATIONAL_NUM 0x04
286 static const value_string sccp_nai_values[] = {
287 { GT_NAI_UNKNOWN, "NAI unknown" },
288 { GT_NAI_SUBSCRIBER_NUMBER, "Subscriber Number" },
289 { GT_NAI_RESERVED_NATIONAL, "Reserved for national use" },
290 { GT_NAI_NATIONAL_SIG_NUM, "National significant number" },
291 { GT_NAI_INTERNATIONAL_NUM, "International number" },
292 { 0, NULL } };
293
294
295 #define GT_OE_MASK 0x80
296 #define GT_OE_EVEN 0
297 #define GT_OE_ODD 1
298 static const value_string sccp_oe_values[] = {
299 { GT_OE_EVEN, "Even number of address signals" },
300 { GT_OE_ODD, "Odd number of address signals" },
301 { 0, NULL } };
302
303 const value_string sccp_address_signal_values[] = {
304 { 0, "0" },
305 { 1, "1" },
306 { 2, "2" },
307 { 3, "3" },
308 { 4, "4" },
309 { 5, "5" },
310 { 6, "6" },
311 { 7, "7" },
312 { 8, "8" },
313 { 9, "9" },
314 { 10, "(spare)" },
315 { 11, "11" },
316 { 12, "12" },
317 { 13, "(spare)" },
318 { 14, "(spare)" },
319 { 15, "ST" },
320 { 0, NULL } };
321
322
323 /* * * * * * * * * * * * * * * * * * * * *
324 * Global Title: ITU and ANSI GTI == 0010 *
325 * * * * * * * * * * * * * * * * * * * * */
326 #define GT_TT_LENGTH 1
327
328
329 /* * * * * * * * * * * * * * * * * * * * * * * * * *
330 * Global Title: ITU GTI == 0011, ANSI GTI == 0001 *
331 * * * * * * * * * * * * * * * * * * * * * * * * * */
332 #define GT_NP_MASK 0xf0
333 #define GT_NP_SHIFT 4
334 #define GT_NP_ES_LENGTH 1
335 #define GT_NP_UNKNOWN 0x00
336 #define GT_NP_ISDN 0x01
337 #define GT_NP_GENERIC_RESERVED 0x02
338 #define GT_NP_DATA 0x03
339 #define GT_NP_TELEX 0x04
340 #define GT_NP_MARITIME_MOBILE 0x05
341 #define GT_NP_LAND_MOBILE 0x06
342 #define GT_NP_ISDN_MOBILE 0x07
343 #define GT_NP_PRIVATE_NETWORK 0x0e
344 #define GT_NP_RESERVED 0x0f
345 static const value_string sccp_np_values[] = {
346 { GT_NP_UNKNOWN, "Unknown" },
347 { GT_NP_ISDN, "ISDN/telephony" },
348 { GT_NP_GENERIC_RESERVED, "Generic (ITU)/Reserved (ANSI)" },
349 { GT_NP_DATA, "Data" },
350 { GT_NP_TELEX, "Telex" },
351 { GT_NP_MARITIME_MOBILE, "Maritime mobile" },
352 { GT_NP_LAND_MOBILE, "Land mobile" },
353 { GT_NP_ISDN_MOBILE, "ISDN/mobile" },
354 { GT_NP_PRIVATE_NETWORK, "Private network or network-specific" },
355 { GT_NP_RESERVED, "Reserved" },
356 { 0, NULL } };
357
358 #define GT_ES_MASK 0x0f
359 #define GT_ES_UNKNOWN 0x0
360 #define GT_ES_BCD_ODD 0x1
361 #define GT_ES_BCD_EVEN 0x2
362 #define GT_ES_NATIONAL 0x3
363 #define GT_ES_RESERVED 0xf
364 static const value_string sccp_es_values[] = {
365 { GT_ES_UNKNOWN, "Unknown" },
366 { GT_ES_BCD_ODD, "BCD, odd number of digits" },
367 { GT_ES_BCD_EVEN, "BCD, even number of digits" },
368 { GT_ES_NATIONAL, "National specific" },
369 { GT_ES_RESERVED, "Reserved (ITU)/Spare (ANSI)" },
370 { 0, NULL } };
371
372 /* Address signals above */
373
374
375 /* * * * * * * * * * * * * * * * *
376 * Global Title: ITU GTI == 0100 *
377 * * * * * * * * * * * * * * * * */
378 /* NP above */
379 /* ES above */
380 /* NAI above */
381 /* Address signals above */
382
383
384 #define CLASS_CLASS_MASK 0xf
385 #define CLASS_SPARE_HANDLING_MASK 0xf0
386 #define CLASS_SPARE_HANDLING_SHIFT 4
387 static const value_string sccp_class_handling_values [] = {
388 { 0x0, "No special options" },
389 { 0x8, "Return message on error" },
390 { 0, NULL } };
391
392
393 #define SEGMENTING_REASSEMBLING_LENGTH 1
394 #define SEGMENTING_REASSEMBLING_MASK 0x01
395 #define NO_MORE_DATA 0
396 #define MORE_DATA 1
397 /* This is also used by sequencing-segmenting parameter */
398 static const value_string sccp_segmenting_reassembling_values [] = {
399 { NO_MORE_DATA, "No more data" },
400 { MORE_DATA, "More data" },
401 { 0, NULL } };
402
403
404 #define RECEIVE_SEQUENCE_NUMBER_LENGTH 1
405 #define RSN_MASK 0xfe
406
407 #define SEQUENCING_SEGMENTING_LENGTH 2
408 #define SEQUENCING_SEGMENTING_SSN_LENGTH 1
409 #define SEQUENCING_SEGMENTING_RSN_LENGTH 1
410 #define SEND_SEQUENCE_NUMBER_MASK 0xfe
411 #define RECEIVE_SEQUENCE_NUMBER_MASK 0xfe
412 #define SEQUENCING_SEGMENTING_MORE_MASK 0x01
413
414
415 #define CREDIT_LENGTH 1
416
417 #define RELEASE_CAUSE_LENGTH 1
418 const value_string sccp_release_cause_values [] = {
419 { 0x00, "End user originated" },
420 { 0x01, "End user congestion" },
421 { 0x02, "End user failure" },
422 { 0x03, "SCCP user originated" },
423 { 0x04, "Remote procedure error" },
424 { 0x05, "Inconsistent connection data" },
425 { 0x06, "Access failure" },
426 { 0x07, "Access congestion" },
427 { 0x08, "Subsystem failure" },
428 { 0x09, "Subsystem congestion" },
429 { 0x0a, "MTP failure" },
430 { 0x0b, "Network congestion" },
431 { 0x0c, "Expiration of reset timer" },
432 { 0x0d, "Expiration of receive inactivity timer" },
433 { 0x0e, "Reserved" },
434 { 0x0f, "Unqualified" },
435 { 0x10, "SCCP failure (ITU only)" },
436 { 0, NULL } };
437
438
439 #define RETURN_CAUSE_LENGTH 1
440 const value_string sccp_return_cause_values [] = {
441 { 0x00, "No translation for an address of such nature" },
442 { 0x01, "No translation for this specific address" },
443 { 0x02, "Subsystem congestion" },
444 { 0x03, "Subsystem failure" },
445 { 0x04, "Unequipped failure" },
446 { 0x05, "MTP failure" },
447 { 0x06, "Network congestion" },
448 { 0x07, "Unqualified" },
449 { 0x08, "Error in message transport" },
450 { 0x09, "Error in local processing" },
451 { 0x0a, "Destination cannot perform reassembly" },
452 { 0x0b, "SCCP failure" },
453 { 0x0c, "Hop counter violation" },
454 { 0x0d, "Segmentation not supported" },
455 { 0x0e, "Segmentation failure" },
456 { 0xf7, "Message change failure (ANSI only)" },
457 { 0xf8, "Invalid INS routing request (ANSI only)" },
458 { 0xf9, "Invalid ISNI routing request (ANSI only)"},
459 { 0xfa, "Unauthorized message (ANSI only)" },
460 { 0xfb, "Message incompatibility (ANSI only)" },
461 { 0xfc, "Cannot perform ISNI constrained routing (ANSI only)" },
462 { 0xfd, "Redundant ISNI constrained routing (ANSI only)" },
463 { 0xfe, "Unable to perform ISNI identification (ANSI only)" },
464 { 0, NULL } };
465
466
467 #define RESET_CAUSE_LENGTH 1
468 const value_string sccp_reset_cause_values [] = {
469 { 0x00, "End user originated" },
470 { 0x01, "SCCP user originated" },
471 { 0x02, "Message out of order - incorrect send sequence number" },
472 { 0x03, "Message out of order - incorrect receive sequence number" },
473 { 0x04, "Remote procedure error - message out of window" },
474 { 0x05, "Remote procedure error - incorrect send sequence number after (re)initialization" },
475 { 0x06, "Remote procedure error - general" },
476 { 0x07, "Remote end user operational" },
477 { 0x08, "Network operational" },
478 { 0x09, "Access operational" },
479 { 0x0a, "Network congestion" },
480 { 0x0b, "Reserved (ITU)/Not obtainable (ANSI)" },
481 { 0x0c, "Unqualified" },
482 { 0, NULL } };
483
484
485 #define ERROR_CAUSE_LENGTH 1
486 const value_string sccp_error_cause_values [] = {
487 { 0x00, "Local Reference Number (LRN) mismatch - unassigned destination LRN" },
488 { 0x01, "Local Reference Number (LRN) mismatch - inconsistent source LRN" },
489 { 0x02, "Point code mismatch" },
490 { 0x03, "Service class mismatch" },
491 { 0x04, "Unqualified" },
492 { 0, NULL } };
493
494
495 #define REFUSAL_CAUSE_LENGTH 1
496 const value_string sccp_refusal_cause_values [] = {
497 { 0x00, "End user originated" },
498 { 0x01, "End user congestion" },
499 { 0x02, "End user failure" },
500 { 0x03, "SCCP user originated" },
501 { 0x04, "Destination address unknown" },
502 { 0x05, "Destination inaccessible" },
503 { 0x06, "Network resource - QOS not available/non-transient" },
504 { 0x07, "Network resource - QOS not available/transient" },
505 { 0x08, "Access failure" },
506 { 0x09, "Access congestion" },
507 { 0x0a, "Subsystem failure" },
508 { 0x0b, "Subsystem congestion" },
509 { 0x0c, "Expiration of connection establishment timer" },
510 { 0x0d, "Incompatible user data" },
511 { 0x0e, "Reserved" },
512 { 0x0f, "Unqualified" },
513 { 0x10, "Hop counter violation" },
514 { 0x11, "SCCP failure (ITU only)" },
515 { 0x12, "No translation for an address of such nature" },
516 { 0x13, "Unequipped user" },
517 { 0, NULL } };
518
519
520 #define SEGMENTATION_LENGTH 4
521 #define SEGMENTATION_FIRST_SEGMENT_MASK 0x80
522 #define SEGMENTATION_CLASS_MASK 0x40
523 #define SEGMENTATION_SPARE_MASK 0x30
524 #define SEGMENTATION_REMAINING_MASK 0x0f
525 static const value_string sccp_segmentation_first_segment_values [] = {
526 { 1, "First segment" },
527 { 0, "Not first segment" },
528 { 0, NULL } };
529 static const value_string sccp_segmentation_class_values [] = {
530 { 0, "Class 0 selected" },
531 { 1, "Class 1 selected" },
532 { 0, NULL } };
533
534
535 #define HOP_COUNTER_LENGTH 1
536
537 #define IMPORTANCE_LENGTH 1
538 #define IMPORTANCE_IMPORTANCE_MASK 0x7
539
540
541 #define ANSI_ISNI_ROUTING_CONTROL_LENGTH 1
542 #define ANSI_ISNI_MI_MASK 0x01
543 #define ANSI_ISNI_IRI_MASK 0x06
544 #define ANSI_ISNI_RES_MASK 0x08
545 #define ANSI_ISNI_TI_MASK 0x10
546 #define ANSI_ISNI_TI_SHIFT 4
547 #define ANSI_ISNI_COUNTER_MASK 0xe0
548 #define ANSI_ISNI_NETSPEC_MASK 0x03
549
550 static const value_string sccp_isni_mark_for_id_values [] = {
551 { 0x0, "Do not identify networks" },
552 { 0x1, "Identify networks" },
553 { 0, NULL } };
554
555 static const value_string sccp_isni_iri_values [] = {
556 { 0x0, "Neither constrained nor suggested ISNI routing" },
557 { 0x1, "Constrained ISNI routing" },
558 { 0x2, "Reserved for suggested ISNI routing" },
559 { 0x3, "Spare" },
560 { 0, NULL } };
561
562 #define ANSI_ISNI_TYPE_0 0x0
563 #define ANSI_ISNI_TYPE_1 0x1
564 static const value_string sccp_isni_ti_values [] = {
565 { ANSI_ISNI_TYPE_0, "Type zero ISNI parameter format" },
566 { ANSI_ISNI_TYPE_1, "Type one ISNI parameter format" },
567 { 0, NULL } };
568
569 /* Laded from e212 hf*/
570 static int hf_assoc_imsi = -1;
571
572 /* Initialize the protocol and registered fields */
573 static int proto_sccp = -1;
574 static int hf_sccp_message_type = -1;
575 static int hf_sccp_variable_pointer1 = -1;
576 static int hf_sccp_variable_pointer2 = -1;
577 static int hf_sccp_variable_pointer3 = -1;
578 static int hf_sccp_optional_pointer = -1;
579 static int hf_sccp_param_length = -1;
580 static int hf_sccp_ssn = -1;
581 static int hf_sccp_gt_digits = -1;
582
583 /* Called Party address */
584 static int hf_sccp_called_ansi_national_indicator = -1;
585 static int hf_sccp_called_itu_natl_use_bit = -1;
586 static int hf_sccp_called_routing_indicator = -1;
587 static int hf_sccp_called_itu_global_title_indicator = -1;
588 static int hf_sccp_called_ansi_global_title_indicator = -1;
589 static int hf_sccp_called_itu_ssn_indicator = -1;
590 static int hf_sccp_called_itu_point_code_indicator = -1;
591 static int hf_sccp_called_ansi_ssn_indicator = -1;
592 static int hf_sccp_called_ansi_point_code_indicator = -1;
593 static int hf_sccp_called_ssn = -1;
594 static int hf_sccp_called_pc_member = -1;
595 static int hf_sccp_called_pc_cluster = -1;
596 static int hf_sccp_called_pc_network = -1;
597 static int hf_sccp_called_ansi_pc = -1;
598 static int hf_sccp_called_chinese_pc = -1;
599 static int hf_sccp_called_itu_pc = -1;
600 static int hf_sccp_called_japan_pc = -1;
601 static int hf_sccp_called_gt_nai = -1;
602 static int hf_sccp_called_gt_oe = -1;
603 static int hf_sccp_called_gt_tt = -1;
604 static int hf_sccp_called_gt_np = -1;
605 static int hf_sccp_called_gt_es = -1;
606 static int hf_sccp_called_gt_digits = -1;
607 static int hf_sccp_called_gt_digits_length = -1;
608
609 /* Calling party address */
610 static int hf_sccp_calling_ansi_national_indicator = -1;
611 static int hf_sccp_calling_itu_natl_use_bit = -1;
612 static int hf_sccp_calling_routing_indicator = -1;
613 static int hf_sccp_calling_itu_global_title_indicator = -1;
614 static int hf_sccp_calling_ansi_global_title_indicator = -1;
615 static int hf_sccp_calling_itu_ssn_indicator = -1;
616 static int hf_sccp_calling_itu_point_code_indicator = -1;
617 static int hf_sccp_calling_ansi_ssn_indicator = -1;
618 static int hf_sccp_calling_ansi_point_code_indicator = -1;
619 static int hf_sccp_calling_ssn = -1;
620 static int hf_sccp_calling_pc_member = -1;
621 static int hf_sccp_calling_pc_cluster = -1;
622 static int hf_sccp_calling_pc_network = -1;
623 static int hf_sccp_calling_ansi_pc = -1;
624 static int hf_sccp_calling_chinese_pc = -1;
625 static int hf_sccp_calling_itu_pc = -1;
626 static int hf_sccp_calling_japan_pc = -1;
627 static int hf_sccp_calling_gt_nai = -1;
628 static int hf_sccp_calling_gt_oe = -1;
629 static int hf_sccp_calling_gt_tt = -1;
630 static int hf_sccp_calling_gt_np = -1;
631 static int hf_sccp_calling_gt_es = -1;
632 static int hf_sccp_calling_gt_digits = -1;
633 static int hf_sccp_calling_gt_digits_length = -1;
634
635 /* Other parameter values */
636 static int hf_sccp_dlr = -1;
637 static int hf_sccp_slr = -1;
638 static int hf_sccp_lr = -1;
639 static int hf_sccp_class = -1;
640 static int hf_sccp_handling = -1;
641 static int hf_sccp_more = -1;
642 static int hf_sccp_rsn = -1;
643 static int hf_sccp_sequencing_segmenting_ssn = -1;
644 static int hf_sccp_sequencing_segmenting_rsn = -1;
645 static int hf_sccp_sequencing_segmenting_more = -1;
646 static int hf_sccp_credit = -1;
647 static int hf_sccp_release_cause = -1;
648 static int hf_sccp_return_cause = -1;
649 static int hf_sccp_reset_cause = -1;
650 static int hf_sccp_error_cause = -1;
651 static int hf_sccp_refusal_cause = -1;
652 static int hf_sccp_segmentation_first = -1;
653 static int hf_sccp_segmentation_class = -1;
654 static int hf_sccp_segmentation_remaining = -1;
655 static int hf_sccp_segmentation_slr = -1;
656 static int hf_sccp_hop_counter = -1;
657 static int hf_sccp_importance = -1;
658 static int hf_sccp_ansi_isni_mi = -1;
659 static int hf_sccp_ansi_isni_iri = -1;
660 static int hf_sccp_ansi_isni_ti = -1;
661 static int hf_sccp_ansi_isni_netspec = -1;
662 static int hf_sccp_ansi_isni_counter = -1;
663 static int hf_sccp_ansi_isni_network = -1;
664 static int hf_sccp_ansi_isni_cluster = -1;
665 static int hf_sccp_xudt_msg_fragments = -1;
666 static int hf_sccp_xudt_msg_fragment = -1;
667 static int hf_sccp_xudt_msg_fragment_overlap = -1;
668 static int hf_sccp_xudt_msg_fragment_overlap_conflicts = -1;
669 static int hf_sccp_xudt_msg_fragment_multiple_tails = -1;
670 static int hf_sccp_xudt_msg_fragment_too_long_fragment = -1;
671 static int hf_sccp_xudt_msg_fragment_error = -1;
672 static int hf_sccp_xudt_msg_fragment_count = -1;
673 static int hf_sccp_xudt_msg_reassembled_in = -1;
674 static int hf_sccp_xudt_msg_reassembled_length = -1;
675 static int hf_sccp_assoc_msg = -1;
676 static int hf_sccp_assoc_id = -1;
677 static int hf_sccp_segmented_data = -1;
678 static int hf_sccp_linked_dissector = -1;
679 static int hf_sccp_end_optional_param = -1;
680 static int hf_sccp_unknown_message = -1;
681 static int hf_sccp_unknown_parameter = -1;
682
683 /* Initialize the subtree pointers */
684 static gint ett_sccp = -1;
685 static gint ett_sccp_called = -1;
686 static gint ett_sccp_called_ai = -1;
687 static gint ett_sccp_called_pc = -1;
688 static gint ett_sccp_called_gt = -1;
689 static gint ett_sccp_called_gt_digits = -1;
690 static gint ett_sccp_calling = -1;
691 static gint ett_sccp_calling_ai = -1;
692 static gint ett_sccp_calling_pc = -1;
693 static gint ett_sccp_calling_gt = -1;
694 static gint ett_sccp_calling_gt_digits = -1;
695 static gint ett_sccp_sequencing_segmenting = -1;
696 static gint ett_sccp_segmentation = -1;
697 static gint ett_sccp_ansi_isni_routing_control = -1;
698 static gint ett_sccp_xudt_msg_fragment = -1;
699 static gint ett_sccp_xudt_msg_fragments = -1;
700 static gint ett_sccp_assoc = -1;
701
702 static expert_field ei_sccp_wrong_length = EI_INIT;
703 static expert_field ei_sccp_international_standard_address = EI_INIT;
704 static expert_field ei_sccp_no_ssn_present = EI_INIT;
705 static expert_field ei_sccp_ssn_zero = EI_INIT;
706 static expert_field ei_sccp_class_unexpected = EI_INIT;
707 static expert_field ei_sccp_handling_invalid = EI_INIT;
708 static expert_field ei_sccp_gt_digits_missing = EI_INIT;
709
710
711 static gboolean sccp_reassemble = TRUE;
712 static gboolean show_key_params = FALSE;
713 static gboolean set_addresses = FALSE;
714 static gboolean dt1_ignore_length = FALSE;
715
716 static int ss7pc_address_type = -1;
717
718 static int sccp_tap = -1;
719
720
721 static const fragment_items sccp_xudt_msg_frag_items = {
722 /* Fragment subtrees */
723 &ett_sccp_xudt_msg_fragment,
724 &ett_sccp_xudt_msg_fragments,
725 /* Fragment fields */
726 &hf_sccp_xudt_msg_fragments,
727 &hf_sccp_xudt_msg_fragment,
728 &hf_sccp_xudt_msg_fragment_overlap,
729 &hf_sccp_xudt_msg_fragment_overlap_conflicts,
730 &hf_sccp_xudt_msg_fragment_multiple_tails,
731 &hf_sccp_xudt_msg_fragment_too_long_fragment,
732 &hf_sccp_xudt_msg_fragment_error,
733 &hf_sccp_xudt_msg_fragment_count,
734 /* Reassembled in field */
735 &hf_sccp_xudt_msg_reassembled_in,
736 /* Reassembled length field */
737 &hf_sccp_xudt_msg_reassembled_length,
738 /* Reassembled data field */
739 NULL,
740 /* Tag */
741 "SCCP XUDT Message fragments"
742 };
743
744 static reassembly_table sccp_xudt_msg_reassembly_table;
745
746
747 #define SCCP_USER_DATA 0
748 #define SCCP_USER_TCAP 1
749 #define SCCP_USER_RANAP 2
750 #define SCCP_USER_BSSAP 3
751 #define SCCP_USER_GSMMAP 4
752 #define SCCP_USER_CAMEL 5
753 #define SCCP_USER_INAP 6
754
755 typedef struct _sccp_user_t {
756 guint ni;
757 range_t *called_pc;
758 range_t *called_ssn;
759 guint user;
760 gboolean uses_tcap;
761 dissector_handle_t *handlep;
762 } sccp_user_t;
763
764 static sccp_user_t *sccp_users;
765 static guint num_sccp_users;
766
767 static dissector_handle_t sccp_handle;
768 static dissector_handle_t data_handle;
769 static dissector_handle_t tcap_handle;
770 static dissector_handle_t ranap_handle;
771 static dissector_handle_t bssap_handle;
772 static dissector_handle_t gsmmap_handle;
773 static dissector_handle_t camel_handle;
774 static dissector_handle_t inap_handle;
775 static dissector_handle_t default_handle;
776
777 static const char *default_payload = NULL;
778
779 static const value_string sccp_users_vals[] = {
780 { SCCP_USER_DATA, "Data"},
781 { SCCP_USER_TCAP, "TCAP"},
782 { SCCP_USER_RANAP, "RANAP"},
783 { SCCP_USER_BSSAP, "BSSAP"},
784 { SCCP_USER_GSMMAP, "GSM MAP"},
785 { SCCP_USER_CAMEL, "CAMEL"},
786 { SCCP_USER_INAP, "INAP"},
787 { 0, NULL }
788 };
789
790 /*
791 * Here are the global variables associated with
792 * the various user definable characteristics of the dissection
793 */
794 static guint32 sccp_source_pc_global = 0;
795 static gboolean sccp_show_length = FALSE;
796 static gboolean trace_sccp = FALSE;
797
798 static heur_dissector_list_t heur_subdissector_list;
799
800 static dissector_table_t sccp_ssn_dissector_table;
801
802 static wmem_tree_t *assocs = NULL;
803 static sccp_assoc_info_t no_assoc = { 0,0,0,INVALID_SSN,INVALID_SSN,FALSE,FALSE,NULL,NULL,SCCP_PLOAD_NONE,NULL,NULL,NULL, NULL, 0 };
804 static guint32 next_assoc_id = 0;
805
806 static const value_string assoc_protos[] = {
807 { SCCP_PLOAD_BSSAP, "BSSAP" },
808 { SCCP_PLOAD_RANAP, "RANAP" },
809 { 0, NULL }
810 };
811
812 /*
813 * Fragment reassembly helpers.
814 *
815 * SCCP data can span multiple messages. As the same local reference number is
816 * used throughout a connection, this identifier is not sufficient for
817 * identifying reassembled PDUs with multiple fragments in the same frame. For
818 * that reason, create a new identifier for each group of fragments based on the
819 * more-data indicator (M-bit) and use that in place of the local reference
820 * number.
821 *
822 * As an optimization, if fragments do not need reassembly (a single message
823 * with the M-bit set), then no surrogate ID is needed nor stored since
824 * reassembly is skipped.
825 */
826 static guint32 sccp_reassembly_id_next;
827
828 /* Maps a key to the current identifier as used in the reassembly API (first pass only). */
829 static wmem_tree_t *sccp_reassembly_ids;
830
831 /* Maps (frame number, offset) to a reassembly API identifier. */
832 static wmem_map_t *sccp_reassembly_id_map;
833
834 static guint32
sccp_reassembly_get_id_pass1(guint32 frame,guint32 offset,guint32 key,gboolean more_frags)835 sccp_reassembly_get_id_pass1(guint32 frame, guint32 offset, guint32 key, gboolean more_frags)
836 {
837 guint32 id = GPOINTER_TO_UINT(wmem_tree_lookup32(sccp_reassembly_ids, key));
838 if (!id) {
839 if (!more_frags) {
840 /* This is the last and only fragment, no need to reassembly anything. */
841 return 0;
842 }
843
844 /* This is a new fragment and "local reference", so create a new one. */
845 id = sccp_reassembly_id_next++;
846 wmem_tree_insert32(sccp_reassembly_ids, key, GUINT_TO_POINTER(id));
847 }
848 /* Save ID for second pass. */
849 guint64 *frame_offset = wmem_new(wmem_file_scope(), guint64);
850 *frame_offset = ((guint64)offset << 32) | frame;
851 wmem_map_insert(sccp_reassembly_id_map, frame_offset, GUINT_TO_POINTER(id));
852 return id;
853 }
854
855 static guint32
sccp_reassembly_get_id_pass2(guint32 frame,guint32 offset)856 sccp_reassembly_get_id_pass2(guint32 frame, guint32 offset)
857 {
858 guint64 frame_offset = ((guint64)offset << 32) | frame;
859 return GPOINTER_TO_UINT(wmem_map_lookup(sccp_reassembly_id_map, &frame_offset));
860 }
861
862 /**
863 * Returns the reassembly ID for the given frame at the given position or 0 if
864 * reassembly is not necessary.
865 */
866 static guint32
sccp_reassembly_get_id(packet_info * pinfo,guint32 offset,guint32 key,gboolean more_frags)867 sccp_reassembly_get_id(packet_info *pinfo, guint32 offset, guint32 key, gboolean more_frags)
868 {
869 if (!PINFO_FD_VISITED(pinfo)) {
870 return sccp_reassembly_get_id_pass1(pinfo->num, offset, key, more_frags);
871 } else {
872 return sccp_reassembly_get_id_pass2(pinfo->num, offset);
873 }
874 }
875
876 static tvbuff_t *
sccp_reassemble_fragments(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,guint16 length_offset,guint32 source_local_ref,gboolean more_frags)877 sccp_reassemble_fragments(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
878 guint16 length_offset, guint32 source_local_ref, gboolean more_frags)
879 {
880 gboolean save_fragmented;
881 tvbuff_t *new_tvb;
882 fragment_head *frag_msg = NULL;
883 guint fragment_len;
884 guint32 abs_offset, frags_id;
885
886 fragment_len = tvb_get_guint8(tvb, length_offset);
887 /* Assume that the absolute offset within the tvb uniquely identifies the
888 * message in this frame. */
889 abs_offset = tvb_raw_offset(tvb) + length_offset;
890 frags_id = sccp_reassembly_get_id(pinfo, abs_offset, source_local_ref, more_frags);
891 if (frags_id) {
892 /*
893 * This fragment is part of multiple fragments, reassembly is required.
894 */
895 save_fragmented = pinfo->fragmented;
896 pinfo->fragmented = TRUE;
897 frag_msg = fragment_add_seq_next(&sccp_xudt_msg_reassembly_table,
898 tvb, length_offset + 1,
899 pinfo,
900 frags_id, /* ID for fragments belonging together */
901 NULL,
902 fragment_len, /* fragment length - to the end */
903 more_frags); /* More fragments? */
904
905 if (!PINFO_FD_VISITED(pinfo) && frag_msg) {
906 /* Reassembly has finished, ensure that the next fragment gets a new ID. */
907 wmem_tree_remove32(sccp_reassembly_ids, source_local_ref);
908 }
909
910 new_tvb = process_reassembled_data(tvb, length_offset + 1, pinfo,
911 "Reassembled SCCP", frag_msg,
912 &sccp_xudt_msg_frag_items,
913 NULL, tree);
914 if (frag_msg) { /* Reassembled */
915 col_append_str(pinfo->cinfo, COL_INFO, "(Message reassembled) ");
916 } else { /* Not last packet of reassembled message */
917 col_append_str(pinfo->cinfo, COL_INFO, "(Message fragment) ");
918 }
919 pinfo->fragmented = save_fragmented;
920 } else {
921 /*
922 * There is only a single fragment, reassembly is not required.
923 */
924 new_tvb = tvb_new_subset_length(tvb, length_offset + 1, fragment_len);
925 }
926 return new_tvb;
927 }
928
929
930 #define is_connectionless(m) \
931 ( m == SCCP_MSG_TYPE_UDT || m == SCCP_MSG_TYPE_UDTS \
932 || m == SCCP_MSG_TYPE_XUDT|| m == SCCP_MSG_TYPE_XUDTS \
933 || m == SCCP_MSG_TYPE_LUDT|| m == SCCP_MSG_TYPE_LUDTS)
934
935 #define RETURN_FALSE \
936 do { \
937 /*ws_warning("Frame %d not protocol %d @ line %d", frame_num, my_mtp3_standard, __LINE__);*/ \
938 return FALSE; \
939 } while (0)
940
941
sccp_prompt(packet_info * pinfo _U_,gchar * result)942 static void sccp_prompt(packet_info *pinfo _U_, gchar* result)
943 {
944 g_snprintf(result, MAX_DECODE_AS_PROMPT_LEN, "Dissect SSN %d as",
945 GPOINTER_TO_UINT(p_get_proto_data(pinfo->pool, pinfo, proto_sccp, 0)));
946 }
947
sccp_value(packet_info * pinfo)948 static gpointer sccp_value(packet_info *pinfo)
949 {
950 return p_get_proto_data(pinfo->pool, pinfo, proto_sccp, 0);
951 }
952
953 static gboolean
sccp_called_calling_looks_valid(guint32 frame_num _U_,tvbuff_t * tvb,guint8 my_mtp3_standard,gboolean is_co)954 sccp_called_calling_looks_valid(guint32 frame_num _U_, tvbuff_t *tvb, guint8 my_mtp3_standard, gboolean is_co)
955 {
956 guint8 ai, ri, gti, ssni, pci;
957 guint8 len_needed = 1; /* need at least the Address Indicator */
958 guint len = tvb_reported_length(tvb);
959
960 ai = tvb_get_guint8(tvb, 0);
961 if ((my_mtp3_standard == ANSI_STANDARD) && ((ai & ANSI_NATIONAL_MASK) == 0))
962 RETURN_FALSE;
963
964 gti = (ai & GTI_MASK) >> GTI_SHIFT;
965 if (my_mtp3_standard == ANSI_STANDARD) {
966 if (gti > 2)
967 RETURN_FALSE;
968 } else {
969 if (gti > 4)
970 RETURN_FALSE;
971 }
972
973 ri = (ai & ROUTING_INDICATOR_MASK) >> ROUTING_INDICATOR_SHIFT;
974 if (my_mtp3_standard == ANSI_STANDARD) {
975 pci = ai & ANSI_PC_INDICATOR_MASK;
976 ssni = ai & ANSI_SSN_INDICATOR_MASK;
977 } else {
978 ssni = ai & ITU_SSN_INDICATOR_MASK;
979 pci = ai & ITU_PC_INDICATOR_MASK;
980 }
981
982 /* Route on SSN with no SSN? */
983 if ((ri == ROUTE_ON_SSN) && (ssni == 0))
984 RETURN_FALSE;
985
986 /* Route on GT with no GT? */
987 if ((ri == ROUTE_ON_GT) && (gti == AI_GTI_NO_GT))
988 RETURN_FALSE;
989
990 /* GT routed and connection-oriented (Class-2)?
991 * Yes, that's theoretically possible, but it's not used.
992 */
993 if ((ri == ROUTE_ON_GT) && is_co)
994 RETURN_FALSE;
995
996 if (ssni)
997 len_needed += ADDRESS_SSN_LENGTH;
998 if (pci) {
999 if (my_mtp3_standard == ANSI_STANDARD ||
1000 my_mtp3_standard == CHINESE_ITU_STANDARD)
1001 len_needed += ANSI_PC_LENGTH;
1002 else
1003 len_needed += ITU_PC_LENGTH;
1004 }
1005 if (gti)
1006 len_needed += 2;
1007
1008 if (len_needed > len)
1009 RETURN_FALSE;
1010
1011 return TRUE;
1012 }
1013
1014 gboolean
looks_like_valid_sccp(guint32 frame_num _U_,tvbuff_t * tvb,guint8 my_mtp3_standard)1015 looks_like_valid_sccp(guint32 frame_num _U_, tvbuff_t *tvb, guint8 my_mtp3_standard)
1016 {
1017 guint offset;
1018 guint8 msgtype, msg_class, cause;
1019 guint called_ptr = 0;
1020 guint calling_ptr = 0;
1021 guint data_ptr = 0;
1022 guint opt_ptr = 0;
1023 guint8 pointer_length = POINTER_LENGTH;
1024 guint len = tvb_captured_length(tvb);
1025
1026 /* Ensure we can do some basic checks without throwing an exception.
1027 * Accesses beyond this length need to check the length first because
1028 * we don't want to throw an exception in here...
1029 */
1030 if (len < 5)
1031 RETURN_FALSE;
1032
1033 msgtype = tvb_get_guint8(tvb, SCCP_MSG_TYPE_OFFSET);
1034 if (!try_val_to_str(msgtype, sccp_message_type_acro_values)) {
1035 RETURN_FALSE;
1036 }
1037 offset = SCCP_MSG_TYPE_LENGTH;
1038
1039 switch (msgtype) {
1040 case SCCP_MSG_TYPE_UDT:
1041 case SCCP_MSG_TYPE_XUDT:
1042 case SCCP_MSG_TYPE_LUDT:
1043 case SCCP_MSG_TYPE_UDTS:
1044 case SCCP_MSG_TYPE_XUDTS:
1045 case SCCP_MSG_TYPE_LUDTS:
1046 {
1047 if (msgtype == SCCP_MSG_TYPE_XUDT || msgtype == SCCP_MSG_TYPE_XUDTS) {
1048 if (SCCP_MSG_TYPE_LENGTH +
1049 PROTOCOL_CLASS_LENGTH + /* or Cause for XUDTS */
1050 HOP_COUNTER_LENGTH +
1051 POINTER_LENGTH +
1052 POINTER_LENGTH +
1053 POINTER_LENGTH +
1054 POINTER_LENGTH > len)
1055 RETURN_FALSE;
1056 }
1057
1058 if (msgtype == SCCP_MSG_TYPE_LUDT || msgtype == SCCP_MSG_TYPE_LUDTS) {
1059 if (SCCP_MSG_TYPE_LENGTH +
1060 PROTOCOL_CLASS_LENGTH + /* or Cause for LUDTS */
1061 HOP_COUNTER_LENGTH +
1062 POINTER_LENGTH_LONG +
1063 POINTER_LENGTH_LONG +
1064 POINTER_LENGTH_LONG +
1065 POINTER_LENGTH_LONG > len)
1066 RETURN_FALSE;
1067
1068 pointer_length = POINTER_LENGTH_LONG;
1069 }
1070
1071 if (msgtype == SCCP_MSG_TYPE_UDT || msgtype == SCCP_MSG_TYPE_XUDT ||
1072 msgtype == SCCP_MSG_TYPE_LUDT) {
1073
1074 msg_class = tvb_get_guint8(tvb, offset) & CLASS_CLASS_MASK;
1075 if (msg_class > 1)
1076 RETURN_FALSE;
1077 offset += PROTOCOL_CLASS_LENGTH;
1078 }
1079
1080 if (msgtype == SCCP_MSG_TYPE_XUDT || msgtype == SCCP_MSG_TYPE_LUDT)
1081 offset += HOP_COUNTER_LENGTH;
1082
1083 if (msgtype == SCCP_MSG_TYPE_UDTS ||
1084 msgtype == SCCP_MSG_TYPE_XUDTS ||
1085 msgtype == SCCP_MSG_TYPE_LUDTS) {
1086
1087 cause = tvb_get_guint8(tvb, offset);
1088 if (!try_val_to_str(cause, sccp_return_cause_values))
1089 RETURN_FALSE;
1090 offset += RETURN_CAUSE_LENGTH;
1091 }
1092
1093 if (msgtype == SCCP_MSG_TYPE_XUDTS || msgtype == SCCP_MSG_TYPE_LUDTS)
1094 offset += HOP_COUNTER_LENGTH;
1095
1096 if (msgtype == SCCP_MSG_TYPE_LUDT || msgtype == SCCP_MSG_TYPE_LUDTS)
1097 called_ptr = tvb_get_letohs(tvb, offset);
1098 else
1099 called_ptr = tvb_get_guint8(tvb, offset);
1100 if (called_ptr == 0) /* Mandatory variable parameters must be present */
1101 RETURN_FALSE;
1102 called_ptr += offset;
1103 offset += pointer_length;
1104
1105 if (msgtype == SCCP_MSG_TYPE_LUDT || msgtype == SCCP_MSG_TYPE_LUDTS)
1106 calling_ptr = tvb_get_letohs(tvb, offset);
1107 else
1108 calling_ptr = tvb_get_guint8(tvb, offset);
1109 if (calling_ptr == 0) /* Mandatory variable parameters must be present */
1110 RETURN_FALSE;
1111 calling_ptr += offset;
1112 offset += pointer_length;
1113
1114 if (msgtype == SCCP_MSG_TYPE_LUDT || msgtype == SCCP_MSG_TYPE_LUDTS)
1115 data_ptr = tvb_get_letohs(tvb, offset);
1116 else
1117 data_ptr = tvb_get_guint8(tvb, offset);
1118 if (data_ptr == 0) /* Mandatory variable parameters must be present */
1119 RETURN_FALSE;
1120 data_ptr += offset;
1121 offset += pointer_length;
1122
1123 if (msgtype == SCCP_MSG_TYPE_XUDT || msgtype == SCCP_MSG_TYPE_XUDTS) {
1124 opt_ptr = tvb_get_guint8(tvb, offset);
1125 offset += POINTER_LENGTH;
1126 } else if (msgtype == SCCP_MSG_TYPE_LUDT || msgtype == SCCP_MSG_TYPE_LUDTS) {
1127 opt_ptr = tvb_get_letohs(tvb, offset);
1128 offset += POINTER_LENGTH_LONG;
1129 }
1130
1131 if (msgtype == SCCP_MSG_TYPE_LUDT || msgtype == SCCP_MSG_TYPE_LUDTS) {
1132 /* Long pointers count from the 2nd (MSB) octet of the pointer */
1133 called_ptr += 1;
1134 calling_ptr += 1;
1135 data_ptr += 1;
1136 if (opt_ptr)
1137 opt_ptr += 1;
1138 }
1139
1140 /* Check that the variable pointers are within bounds */
1141 if (called_ptr > len || calling_ptr > len || data_ptr > len)
1142 RETURN_FALSE;
1143
1144 /* Check that the lengths of the variable parameters are within bounds */
1145 if (tvb_get_guint8(tvb, called_ptr)+called_ptr > len ||
1146 tvb_get_guint8(tvb, calling_ptr)+calling_ptr > len)
1147 RETURN_FALSE;
1148 if (msgtype == SCCP_MSG_TYPE_LUDT || msgtype == SCCP_MSG_TYPE_LUDTS) {
1149 if (tvb_get_letohs(tvb, data_ptr)+data_ptr > len)
1150 RETURN_FALSE;
1151 } else {
1152 if (tvb_get_guint8(tvb, data_ptr)+data_ptr > len)
1153 RETURN_FALSE;
1154 }
1155 }
1156 break;
1157 case SCCP_MSG_TYPE_CR:
1158 {
1159 if (len < SCCP_MSG_TYPE_LENGTH
1160 + DESTINATION_LOCAL_REFERENCE_LENGTH
1161 + PROTOCOL_CLASS_LENGTH
1162 + POINTER_LENGTH
1163 + POINTER_LENGTH)
1164 RETURN_FALSE;
1165
1166 offset += DESTINATION_LOCAL_REFERENCE_LENGTH;
1167
1168 /* Class is only the lower 4 bits, but the upper 4 bits are spare
1169 * in Class-2. Don't mask them off so the below comparison also
1170 * fails if any of those spare bits are set.
1171 */
1172 msg_class = tvb_get_guint8(tvb, offset);
1173 if (msg_class != 2)
1174 RETURN_FALSE;
1175
1176 offset += PROTOCOL_CLASS_LENGTH;
1177 data_ptr = tvb_get_guint8(tvb, offset);
1178 if (data_ptr == 0)
1179 RETURN_FALSE;
1180
1181 offset += POINTER_LENGTH;
1182 opt_ptr = tvb_get_guint8(tvb, offset);
1183 if (opt_ptr == 0)
1184 RETURN_FALSE;
1185
1186 offset += POINTER_LENGTH;
1187 }
1188 break;
1189 case SCCP_MSG_TYPE_CC:
1190 {
1191 if (len < SCCP_MSG_TYPE_LENGTH
1192 + DESTINATION_LOCAL_REFERENCE_LENGTH
1193 + SOURCE_LOCAL_REFERENCE_LENGTH
1194 + PROTOCOL_CLASS_LENGTH
1195 + POINTER_LENGTH)
1196 RETURN_FALSE;
1197
1198 offset += DESTINATION_LOCAL_REFERENCE_LENGTH;
1199 offset += SOURCE_LOCAL_REFERENCE_LENGTH;
1200
1201 /* Class is only the lower 4 bits, but the upper 4 bits are spare
1202 * in Class-2. Don't mask them off so the below comparison also
1203 * fails if any of those spare bits are set.
1204 */
1205 msg_class = tvb_get_guint8(tvb, offset);
1206 if (msg_class != 2)
1207 RETURN_FALSE;
1208 offset += PROTOCOL_CLASS_LENGTH;
1209
1210 opt_ptr = tvb_get_guint8(tvb, offset);
1211 offset += POINTER_LENGTH;
1212
1213 /* If the pointer isn't 0 (no optional parameters) or 1 (optional
1214 * parameter starts immediately after the pointer) then what would
1215 * be between the pointer and the parameter?
1216 */
1217 if (opt_ptr > 1)
1218 RETURN_FALSE;
1219
1220 /* If there are no optional parameters, are we at the end of the
1221 * message?
1222 */
1223 if ((opt_ptr == 0) && (offset != len))
1224 RETURN_FALSE;
1225 }
1226 break;
1227 case SCCP_MSG_TYPE_CREF:
1228 {
1229 if (len < SCCP_MSG_TYPE_LENGTH
1230 + DESTINATION_LOCAL_REFERENCE_LENGTH
1231 + REFUSAL_CAUSE_LENGTH
1232 + POINTER_LENGTH)
1233 RETURN_FALSE;
1234
1235 offset += DESTINATION_LOCAL_REFERENCE_LENGTH;
1236
1237 cause = tvb_get_guint8(tvb, offset);
1238 if (!try_val_to_str(cause, sccp_refusal_cause_values))
1239 RETURN_FALSE;
1240 offset += REFUSAL_CAUSE_LENGTH;
1241
1242 opt_ptr = tvb_get_guint8(tvb, offset);
1243 offset += POINTER_LENGTH;
1244
1245 /* If the pointer isn't 0 (no optional parameters) or 1 (optional
1246 * parameter starts immediately after the pointer) then what would
1247 * be between the pointer and the parameter?
1248 */
1249 if (opt_ptr > 1)
1250 RETURN_FALSE;
1251
1252 /* If there are no optional parameters, are we at the end of the
1253 * message?
1254 */
1255 if ((opt_ptr == 0) && (offset != len))
1256 RETURN_FALSE;
1257 }
1258 break;
1259 case SCCP_MSG_TYPE_RLSD:
1260 {
1261 if (len < SCCP_MSG_TYPE_LENGTH
1262 + DESTINATION_LOCAL_REFERENCE_LENGTH
1263 + SOURCE_LOCAL_REFERENCE_LENGTH
1264 + RELEASE_CAUSE_LENGTH
1265 + POINTER_LENGTH)
1266 RETURN_FALSE;
1267
1268 offset += DESTINATION_LOCAL_REFERENCE_LENGTH;
1269 offset += SOURCE_LOCAL_REFERENCE_LENGTH;
1270
1271 cause = tvb_get_guint8(tvb, offset);
1272 if (!try_val_to_str(cause, sccp_release_cause_values))
1273 RETURN_FALSE;
1274 offset += RELEASE_CAUSE_LENGTH;
1275
1276 opt_ptr = tvb_get_guint8(tvb, offset);
1277 offset += POINTER_LENGTH;
1278
1279 /* If the pointer isn't 0 (no optional parameters) or 1 (optional
1280 * parameter starts immediately after the pointer) then what would
1281 * be between the pointer and the parameter?
1282 */
1283 if (opt_ptr > 1)
1284 RETURN_FALSE;
1285
1286 /* If there are no optional parameters, are we at the end of the
1287 * message?
1288 */
1289 if ((opt_ptr == 0) && (offset != len))
1290 RETURN_FALSE;
1291 }
1292 break;
1293 case SCCP_MSG_TYPE_RLC:
1294 {
1295 if (len != SCCP_MSG_TYPE_LENGTH
1296 + DESTINATION_LOCAL_REFERENCE_LENGTH
1297 + SOURCE_LOCAL_REFERENCE_LENGTH)
1298 RETURN_FALSE;
1299 }
1300 break;
1301 case SCCP_MSG_TYPE_ERR:
1302 {
1303 if (len != SCCP_MSG_TYPE_LENGTH
1304 + DESTINATION_LOCAL_REFERENCE_LENGTH
1305 + ERROR_CAUSE_LENGTH)
1306 RETURN_FALSE;
1307
1308 offset += DESTINATION_LOCAL_REFERENCE_LENGTH;
1309
1310 cause = tvb_get_guint8(tvb, offset);
1311 if (!try_val_to_str(cause, sccp_error_cause_values))
1312 RETURN_FALSE;
1313 }
1314 break;
1315 case SCCP_MSG_TYPE_DT1:
1316 {
1317 if (len < SCCP_MSG_TYPE_LENGTH
1318 + DESTINATION_LOCAL_REFERENCE_LENGTH
1319 + SEGMENTING_REASSEMBLING_LENGTH
1320 + POINTER_LENGTH
1321 + PARAMETER_LENGTH_LENGTH
1322 + 1) /* At least 1 byte of payload */
1323 RETURN_FALSE;
1324 offset += DESTINATION_LOCAL_REFERENCE_LENGTH;
1325
1326 /* Are any of the spare bits in set? */
1327 if (tvb_get_guint8(tvb, offset) & ~SEGMENTING_REASSEMBLING_MASK)
1328 RETURN_FALSE;
1329 offset += SEGMENTING_REASSEMBLING_LENGTH;
1330
1331 data_ptr = tvb_get_guint8(tvb, offset) + offset;
1332 /* Verify the data pointer is within bounds */
1333 if (data_ptr > len)
1334 RETURN_FALSE;
1335 offset += POINTER_LENGTH;
1336
1337 /* Verify the data length uses the rest of the message */
1338 if (tvb_get_guint8(tvb, data_ptr) + offset + 1U != len)
1339 RETURN_FALSE;
1340 }
1341 break;
1342 case SCCP_MSG_TYPE_IT:
1343 {
1344 if (len < SCCP_MSG_TYPE_LENGTH
1345 + DESTINATION_LOCAL_REFERENCE_LENGTH
1346 + SOURCE_LOCAL_REFERENCE_LENGTH
1347 + PROTOCOL_CLASS_LENGTH
1348 + SEQUENCING_SEGMENTING_LENGTH
1349 + CREDIT_LENGTH)
1350 RETURN_FALSE;
1351
1352 offset += DESTINATION_LOCAL_REFERENCE_LENGTH;
1353 offset += SOURCE_LOCAL_REFERENCE_LENGTH;
1354
1355 /* Class is only the lower 4 bits, but the upper 4 bits are spare
1356 * in Class-2. Don't mask them off so the below comparison also
1357 * fails if any of those spare bits are set.
1358 */
1359 msg_class = tvb_get_guint8(tvb, offset);
1360 if (msg_class != 2)
1361 RETURN_FALSE;
1362 offset += PROTOCOL_CLASS_LENGTH;
1363 }
1364 break;
1365 case SCCP_MSG_TYPE_AK:
1366 case SCCP_MSG_TYPE_DT2:
1367 case SCCP_MSG_TYPE_EA:
1368 case SCCP_MSG_TYPE_ED:
1369 case SCCP_MSG_TYPE_RSC:
1370 case SCCP_MSG_TYPE_RSR:
1371 /* Class-3 is never actually used in the real world */
1372 RETURN_FALSE;
1373 break;
1374
1375 default:
1376 DISSECTOR_ASSERT_NOT_REACHED();
1377 }
1378
1379 if (called_ptr) {
1380 guint8 param_len = tvb_get_guint8(tvb, called_ptr);
1381 tvbuff_t *param_tvb;
1382
1383 if (param_len == 0)
1384 RETURN_FALSE;
1385 param_tvb = tvb_new_subset_length(tvb, called_ptr+1, param_len);
1386
1387 if (!sccp_called_calling_looks_valid(frame_num, param_tvb, my_mtp3_standard, !is_connectionless(msgtype)))
1388 RETURN_FALSE;
1389 }
1390
1391 if (calling_ptr) {
1392 guint8 param_len = tvb_get_guint8(tvb, calling_ptr);
1393 tvbuff_t *param_tvb;
1394
1395 if (param_len == 0)
1396 RETURN_FALSE;
1397 param_tvb = tvb_new_subset_length(tvb, calling_ptr+1, param_len);
1398
1399 if (!sccp_called_calling_looks_valid(frame_num, param_tvb, my_mtp3_standard, !is_connectionless(msgtype)))
1400 RETURN_FALSE;
1401 }
1402
1403 if (opt_ptr) {
1404 guint8 opt_param;
1405
1406 opt_ptr += offset-pointer_length; /* (offset was already incremented) */
1407
1408 /* Check that the optional pointer is within bounds */
1409 if (opt_ptr > len)
1410 RETURN_FALSE;
1411
1412 opt_param = tvb_get_guint8(tvb, opt_ptr);
1413 /* Check if the (1st) optional parameter tag is valid */
1414 if (!try_val_to_str(opt_param, sccp_parameter_values))
1415 RETURN_FALSE;
1416
1417 /* Check that the (1st) parameter length is within bounds */
1418 if ((opt_param != PARAMETER_END_OF_OPTIONAL_PARAMETERS) &&
1419 ((opt_ptr+1U) <= len) &&
1420 ((tvb_get_guint8(tvb, opt_ptr+1U)+offset) > len))
1421 RETURN_FALSE;
1422
1423 /* If we're at the end of the parameters, are we also at the end of the
1424 * message?
1425 */
1426 if ((opt_param == PARAMETER_END_OF_OPTIONAL_PARAMETERS) && ((opt_ptr+1U) != len))
1427 RETURN_FALSE;
1428 }
1429
1430 return TRUE;
1431 }
1432
1433 static sccp_assoc_info_t *
new_assoc(guint32 calling,guint32 called)1434 new_assoc(guint32 calling, guint32 called)
1435 {
1436 sccp_assoc_info_t *a = wmem_new0(wmem_file_scope(), sccp_assoc_info_t);
1437
1438 a->id = next_assoc_id++;
1439 a->calling_dpc = calling;
1440 a->called_dpc = called;
1441 a->calling_ssn = INVALID_SSN;
1442 a->called_ssn = INVALID_SSN;
1443 a->msgs = NULL;
1444 a->curr_msg = NULL;
1445 a->payload = SCCP_PLOAD_NONE;
1446 a->calling_party = NULL;
1447 a->called_party = NULL;
1448 a->extra_info = NULL;
1449 a->imsi = NULL;
1450
1451 return a;
1452 }
1453
1454 sccp_assoc_info_t *
get_sccp_assoc(packet_info * pinfo,guint offset,sccp_decode_context_t * value)1455 get_sccp_assoc(packet_info *pinfo, guint offset, sccp_decode_context_t* value)
1456 {
1457 guint32 opck, dpck;
1458 address *opc = &(pinfo->src);
1459 address *dpc = &(pinfo->dst);
1460 guint framenum = pinfo->num;
1461
1462 if (value->assoc)
1463 return value->assoc;
1464
1465 opck = opc->type == ss7pc_address_type ? mtp3_pc_hash((const mtp3_addr_pc_t *)opc->data) : g_str_hash(address_to_str(pinfo->pool, opc));
1466 dpck = dpc->type == ss7pc_address_type ? mtp3_pc_hash((const mtp3_addr_pc_t *)dpc->data) : g_str_hash(address_to_str(pinfo->pool, dpc));
1467
1468
1469 switch (value->message_type) {
1470 case SCCP_MSG_TYPE_CR:
1471 {
1472 /* CR contains the opc,dpc,dlr key of backward messages swapped as dpc,opc,slr */
1473 wmem_tree_key_t bw_key[4];
1474
1475 bw_key[0].length = 1;
1476 bw_key[0].key = &dpck;
1477
1478 bw_key[1].length = 1;
1479 bw_key[1].key = &opck;
1480
1481 bw_key[2].length = 1;
1482 bw_key[2].key = &value->slr;
1483
1484 bw_key[3].length = 0;
1485 bw_key[3].key = NULL;
1486
1487 if (! (value->assoc = (sccp_assoc_info_t *)wmem_tree_lookup32_array(assocs, bw_key) ) && ! PINFO_FD_VISITED(pinfo) ) {
1488 value->assoc = new_assoc(opck, dpck);
1489 wmem_tree_insert32_array(assocs, bw_key, value->assoc);
1490 value->assoc->has_bw_key = TRUE;
1491 }
1492
1493 pinfo->p2p_dir = P2P_DIR_SENT;
1494
1495 break;
1496 }
1497 case SCCP_MSG_TYPE_CC:
1498 {
1499 wmem_tree_key_t fw_key[4];
1500 wmem_tree_key_t bw_key[4];
1501
1502 fw_key[0].length = 1;
1503 fw_key[0].key = &dpck;
1504
1505 fw_key[1].length = 1;
1506 fw_key[1].key = &opck;
1507
1508 fw_key[2].length = 1;
1509 fw_key[2].key = &value->slr;
1510
1511 fw_key[3].length = 0;
1512 fw_key[3].key = NULL;
1513
1514 bw_key[0].length = 1;
1515 bw_key[0].key = &opck;
1516
1517 bw_key[1].length = 1;
1518 bw_key[1].key = &dpck;
1519
1520 bw_key[2].length = 1;
1521 bw_key[2].key = &value->dlr;
1522
1523 bw_key[3].length = 0;
1524 bw_key[3].key = NULL;
1525
1526
1527 if ( (value->assoc = (sccp_assoc_info_t *)wmem_tree_lookup32_array(assocs, bw_key) ) ) {
1528 goto got_assoc;
1529 }
1530
1531 if ( (value->assoc = (sccp_assoc_info_t *)wmem_tree_lookup32_array(assocs, fw_key) ) ) {
1532 goto got_assoc;
1533 }
1534
1535 value->assoc = new_assoc(dpck, opck);
1536
1537 got_assoc:
1538
1539 pinfo->p2p_dir = P2P_DIR_RECV;
1540
1541 if ( ! PINFO_FD_VISITED(pinfo) && ! value->assoc->has_bw_key ) {
1542 wmem_tree_insert32_array(assocs, bw_key, value->assoc);
1543 value->assoc->has_bw_key = TRUE;
1544 }
1545
1546 if ( ! PINFO_FD_VISITED(pinfo) && ! value->assoc->has_fw_key ) {
1547 wmem_tree_insert32_array(assocs, fw_key, value->assoc);
1548 value->assoc->has_fw_key = TRUE;
1549 }
1550
1551 break;
1552 }
1553 case SCCP_MSG_TYPE_IT:
1554 /* fall-through */
1555 case SCCP_MSG_TYPE_RLC:
1556 {
1557 wmem_tree_key_t fw_key[4];
1558 wmem_tree_key_t bw_key[4];
1559
1560 fw_key[0].length = 1;
1561 fw_key[0].key = &dpck;
1562
1563 fw_key[1].length = 1;
1564 fw_key[1].key = &opck;
1565
1566 fw_key[2].length = 1;
1567 fw_key[2].key = &value->slr;
1568
1569 fw_key[3].length = 0;
1570 fw_key[3].key = NULL;
1571
1572 bw_key[0].length = 1;
1573 bw_key[0].key = &opck;
1574
1575 bw_key[1].length = 1;
1576 bw_key[1].key = &dpck;
1577
1578 bw_key[2].length = 1;
1579 bw_key[2].key = &value->dlr;
1580
1581 bw_key[3].length = 0;
1582 bw_key[3].key = NULL;
1583
1584 if ( (value->assoc = (sccp_assoc_info_t *)wmem_tree_lookup32_array(assocs, bw_key) ) ) {
1585 goto got_assoc_rlc;
1586 }
1587
1588 if ( (value->assoc = (sccp_assoc_info_t *)wmem_tree_lookup32_array(assocs, fw_key) ) ) {
1589 goto got_assoc_rlc;
1590 }
1591
1592 value->assoc = new_assoc(dpck, opck);
1593
1594 got_assoc_rlc:
1595
1596 pinfo->p2p_dir = P2P_DIR_SENT;
1597
1598 if ( ! PINFO_FD_VISITED(pinfo) && ! value->assoc->has_bw_key ) {
1599 wmem_tree_insert32_array(assocs, bw_key, value->assoc);
1600 value->assoc->has_bw_key = TRUE;
1601 }
1602
1603 if ( ! PINFO_FD_VISITED(pinfo) && ! value->assoc->has_fw_key ) {
1604 wmem_tree_insert32_array(assocs, fw_key, value->assoc);
1605 value->assoc->has_fw_key = TRUE;
1606 }
1607 break;
1608 }
1609 default:
1610 {
1611 wmem_tree_key_t key[4];
1612
1613 key[0].length = 1;
1614 key[0].key = &opck;
1615
1616 key[1].length = 1;
1617 key[1].key = &dpck;
1618
1619 key[2].length = 1;
1620 key[2].key = &value->dlr;
1621
1622 key[3].length = 0;
1623 key[3].key = NULL;
1624
1625
1626 value->assoc = (sccp_assoc_info_t *)wmem_tree_lookup32_array(assocs, key);
1627
1628 if (value->assoc) {
1629 if (value->assoc->calling_dpc == dpck) {
1630 pinfo->p2p_dir = P2P_DIR_RECV;
1631 } else {
1632 pinfo->p2p_dir = P2P_DIR_SENT;
1633 }
1634 }
1635
1636 break;
1637 }
1638 }
1639
1640 if (value->assoc && trace_sccp) {
1641 if ( ! PINFO_FD_VISITED(pinfo)) {
1642 sccp_msg_info_t *msg = wmem_new0(wmem_file_scope(), sccp_msg_info_t);
1643 msg->framenum = framenum;
1644 msg->offset = offset;
1645 msg->data.co.next = NULL;
1646 msg->data.co.assoc = value->assoc;
1647 msg->data.co.label = NULL;
1648 msg->data.co.comment = NULL;
1649 msg->data.co.imsi = NULL;
1650 msg->type = value->message_type;
1651
1652 if (value->assoc->msgs) {
1653 sccp_msg_info_t *m;
1654 for (m = value->assoc->msgs; m->data.co.next; m = m->data.co.next) ;
1655 m->data.co.next = msg;
1656 } else {
1657 value->assoc->msgs = msg;
1658 }
1659
1660 value->assoc->curr_msg = msg;
1661
1662 } else {
1663
1664 sccp_msg_info_t *m;
1665
1666 for (m = value->assoc->msgs; m; m = m->data.co.next) {
1667 if (m->data.co.imsi != NULL && value->assoc->imsi == NULL) {
1668 value->assoc->imsi = wmem_strdup(wmem_epan_scope(), m->data.co.imsi);
1669 }
1670 if ((m->framenum == framenum) && (m->offset == offset)) {
1671 value->assoc->curr_msg = m;
1672 break;
1673 }
1674 }
1675 }
1676 }
1677
1678 return value->assoc ? value->assoc : &no_assoc;
1679 }
1680
1681
1682 static void
dissect_sccp_unknown_message(tvbuff_t * message_tvb,proto_tree * sccp_tree)1683 dissect_sccp_unknown_message(tvbuff_t *message_tvb, proto_tree *sccp_tree)
1684 {
1685 guint32 message_length;
1686
1687 message_length = tvb_captured_length(message_tvb);
1688
1689 proto_tree_add_bytes_format(sccp_tree, hf_sccp_unknown_message, message_tvb, 0, message_length,
1690 NULL, "Unknown message (%u byte%s)",
1691 message_length, plurality(message_length, "", "s"));
1692 }
1693
1694 static void
dissect_sccp_unknown_param(tvbuff_t * tvb,proto_tree * tree,guint8 type,guint length)1695 dissect_sccp_unknown_param(tvbuff_t *tvb, proto_tree *tree, guint8 type, guint length)
1696 {
1697 proto_tree_add_bytes_format(tree, hf_sccp_unknown_parameter, tvb, 0, length, NULL,
1698 "Unknown parameter 0x%x (%u byte%s)", type, length, plurality(length, "", "s"));
1699 }
1700
1701 static void
dissect_sccp_dlr_param(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,guint length,sccp_decode_context_t * sccp_info)1702 dissect_sccp_dlr_param(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint length, sccp_decode_context_t* sccp_info)
1703 {
1704 proto_item *lr_item;
1705
1706 if (length != 3) {
1707 proto_tree_add_expert_format(tree, pinfo, &ei_sccp_wrong_length, tvb, 0, length,
1708 "Wrong length indicated. Expected 3, got %u", length);
1709 return;
1710 }
1711
1712 sccp_info->dlr = tvb_get_letoh24(tvb, 0);
1713 proto_tree_add_uint(tree, hf_sccp_dlr, tvb, 0, length, sccp_info->dlr);
1714 lr_item = proto_tree_add_uint(tree, hf_sccp_lr, tvb, 0, length, sccp_info->dlr);
1715 proto_item_set_generated(lr_item);
1716
1717 if (show_key_params)
1718 col_append_fstr(pinfo->cinfo, COL_INFO, "DLR=%d ", sccp_info->dlr);
1719 }
1720
1721 static void
dissect_sccp_slr_param(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,guint length,sccp_decode_context_t * sccp_info)1722 dissect_sccp_slr_param(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint length, sccp_decode_context_t* sccp_info)
1723 {
1724 proto_item *lr_item;
1725
1726 if (length != 3) {
1727 proto_tree_add_expert_format(tree, pinfo, &ei_sccp_wrong_length, tvb, 0, length,
1728 "Wrong length indicated. Expected 3, got %u", length);
1729 return;
1730 }
1731
1732 sccp_info->slr = tvb_get_letoh24(tvb, 0);
1733 proto_tree_add_uint(tree, hf_sccp_slr, tvb, 0, length, sccp_info->slr);
1734 lr_item = proto_tree_add_uint(tree, hf_sccp_lr, tvb, 0, length, sccp_info->slr);
1735 proto_item_set_generated(lr_item);
1736
1737 if (show_key_params)
1738 col_append_fstr(pinfo->cinfo, COL_INFO, "SLR=%d ", sccp_info->slr);
1739 }
1740
1741 static proto_tree *
dissect_sccp_gt_address_information(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,guint length,gboolean even_length,gboolean called,sccp_decode_context_t * sccp_info)1742 dissect_sccp_gt_address_information(tvbuff_t *tvb, packet_info *pinfo,
1743 proto_tree *tree, guint length,
1744 gboolean even_length, gboolean called,
1745 sccp_decode_context_t* sccp_info)
1746 {
1747 guint offset = 0;
1748 guint8 odd_signal, even_signal;
1749 proto_item *digits_item;
1750 proto_tree *digits_tree;
1751 char *gt_digits;
1752
1753 gt_digits = (char *)wmem_alloc0(pinfo->pool, GT_MAX_SIGNALS+1);
1754
1755 while (offset < length) {
1756 odd_signal = tvb_get_guint8(tvb, offset) & GT_ODD_SIGNAL_MASK;
1757 even_signal = tvb_get_guint8(tvb, offset) & GT_EVEN_SIGNAL_MASK;
1758 even_signal >>= GT_EVEN_SIGNAL_SHIFT;
1759
1760 (void) g_strlcat(gt_digits, val_to_str(odd_signal, sccp_address_signal_values,
1761 "Unknown: %d"), GT_MAX_SIGNALS+1);
1762
1763 /* If the last signal is NOT filler */
1764 if (offset != (length - 1) || even_length == TRUE)
1765 (void) g_strlcat(gt_digits, val_to_str(even_signal, sccp_address_signal_values,
1766 "Unknown: %d"), GT_MAX_SIGNALS+1);
1767
1768 offset += GT_SIGNAL_LENGTH;
1769 }
1770
1771 if (is_connectionless(sccp_info->message_type) && sccp_info->sccp_msg) {
1772 guint8 **gt_ptr = called ? &(sccp_info->sccp_msg->data.ud.called_gt) : &(sccp_info->sccp_msg->data.ud.calling_gt);
1773
1774 *gt_ptr = (guint8 *)wmem_strdup(pinfo->pool, gt_digits);
1775 }
1776
1777 digits_item = proto_tree_add_string(tree, called ? hf_sccp_called_gt_digits
1778 : hf_sccp_calling_gt_digits,
1779 tvb, 0, length, gt_digits);
1780 digits_tree = proto_item_add_subtree(digits_item, called ? ett_sccp_called_gt_digits
1781 : ett_sccp_calling_gt_digits);
1782
1783 if (set_addresses) {
1784 if (called) {
1785 set_address(&pinfo->dst, AT_STRINGZ, 1+(int)strlen(gt_digits), gt_digits);
1786 } else {
1787 set_address(&pinfo->src, AT_STRINGZ, 1+(int)strlen(gt_digits), gt_digits);
1788 }
1789 }
1790
1791 proto_tree_add_string(digits_tree, hf_sccp_gt_digits, tvb, 0, length, gt_digits);
1792 proto_tree_add_uint(digits_tree, called ? hf_sccp_called_gt_digits_length
1793 : hf_sccp_calling_gt_digits_length,
1794 tvb, 0, length, (guint32)strlen(gt_digits));
1795
1796 return digits_tree;
1797 }
1798
1799 static void
dissect_sccp_global_title(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,guint length,guint8 gti,gboolean called,sccp_decode_context_t * sccp_info)1800 dissect_sccp_global_title(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint length,
1801 guint8 gti, gboolean called, sccp_decode_context_t* sccp_info)
1802 {
1803 proto_item *gt_item;
1804 proto_tree *gt_tree;
1805 proto_tree *digits_tree;
1806 tvbuff_t *signals_tvb;
1807 guint offset = 0;
1808 guint8 odd_even, nai = 0, np = 0, es;
1809 gboolean even = TRUE;
1810
1811 /* Shift GTI to where we can work with it */
1812 gti >>= GTI_SHIFT;
1813
1814 gt_tree = proto_tree_add_subtree_format(tree, tvb, offset, length,
1815 called ? ett_sccp_called_gt : ett_sccp_calling_gt, >_item,
1816 "Global Title 0x%x (%u byte%s)",
1817 gti, length, plurality(length,"", "s"));
1818
1819 /* Decode Transaction Type (if present) */
1820 if ((gti == AI_GTI_TT) ||
1821 ((decode_mtp3_standard != ANSI_STANDARD) &&
1822 ((gti == ITU_AI_GTI_TT_NP_ES) || (gti == ITU_AI_GTI_TT_NP_ES_NAI))) ||
1823 ((decode_mtp3_standard == ANSI_STANDARD) && (gti == ANSI_AI_GTI_TT_NP_ES))) {
1824
1825 proto_tree_add_item(gt_tree, called ? hf_sccp_called_gt_tt
1826 : hf_sccp_calling_gt_tt,
1827 tvb, offset, GT_TT_LENGTH, ENC_NA);
1828 offset += GT_TT_LENGTH;
1829 }
1830
1831 if (gti == AI_GTI_TT) {
1832 /* Protocol doesn't tell us, so we ASSUME even... */
1833 even = TRUE;
1834 }
1835
1836 /* Decode Numbering Plan and Encoding Scheme (if present) */
1837 if (((decode_mtp3_standard != ANSI_STANDARD) &&
1838 ((gti == ITU_AI_GTI_TT_NP_ES) || (gti == ITU_AI_GTI_TT_NP_ES_NAI))) ||
1839 ((decode_mtp3_standard == ANSI_STANDARD) && (gti == ANSI_AI_GTI_TT_NP_ES))) {
1840
1841 np = tvb_get_guint8(tvb, offset) & GT_NP_MASK;
1842 proto_tree_add_uint(gt_tree, called ? hf_sccp_called_gt_np
1843 : hf_sccp_calling_gt_np,
1844 tvb, offset, GT_NP_ES_LENGTH, np);
1845
1846 es = tvb_get_guint8(tvb, offset) & GT_ES_MASK;
1847 proto_tree_add_uint(gt_tree, called ? hf_sccp_called_gt_es
1848 : hf_sccp_calling_gt_es,
1849 tvb, offset, GT_NP_ES_LENGTH, es);
1850
1851 even = (es == GT_ES_BCD_EVEN) ? TRUE : FALSE;
1852
1853 offset += GT_NP_ES_LENGTH;
1854 }
1855
1856 /* Decode Nature of Address Indicator (if present) */
1857 if ((decode_mtp3_standard != ANSI_STANDARD) &&
1858 ((gti == ITU_AI_GTI_NAI) || (gti == ITU_AI_GTI_TT_NP_ES_NAI))) {
1859
1860 /* Decode Odd/Even Indicator (if present) */
1861 if (gti == ITU_AI_GTI_NAI) {
1862 odd_even = tvb_get_guint8(tvb, offset) & GT_OE_MASK;
1863 proto_tree_add_uint(gt_tree, called ? hf_sccp_called_gt_oe
1864 : hf_sccp_calling_gt_oe,
1865 tvb, offset, GT_NAI_LENGTH, odd_even);
1866 even = (odd_even == GT_OE_EVEN) ? TRUE : FALSE;
1867 }
1868
1869 nai = tvb_get_guint8(tvb, offset) & GT_NAI_MASK;
1870 proto_tree_add_uint(gt_tree, called ? hf_sccp_called_gt_nai
1871 : hf_sccp_calling_gt_nai,
1872 tvb, offset, GT_NAI_LENGTH, nai);
1873
1874 offset += GT_NAI_LENGTH;
1875 }
1876
1877 if(length == 0){
1878 expert_add_info(pinfo, gt_item, &ei_sccp_gt_digits_missing);
1879 return;
1880 }
1881
1882 /* Decode address signal(s) */
1883 if (length < offset)
1884 return;
1885
1886 signals_tvb = tvb_new_subset_length(tvb, offset, (length - offset));
1887
1888 digits_tree = dissect_sccp_gt_address_information(signals_tvb, pinfo, gt_tree,
1889 (length - offset),
1890 even, called, sccp_info);
1891
1892 /* Display the country code (if we can) */
1893 switch (np >> GT_NP_SHIFT) {
1894 case GT_NP_ISDN:
1895 case GT_NP_ISDN_MOBILE:
1896 if (nai == GT_NAI_INTERNATIONAL_NUM) {
1897 dissect_e164_cc(signals_tvb, digits_tree, 0, E164_ENC_BCD);
1898 }
1899 break;
1900 case GT_NP_LAND_MOBILE:
1901 dissect_e212_mcc_mnc_in_address(signals_tvb, pinfo, digits_tree, 0);
1902 break;
1903 default:
1904 break;
1905 }
1906 }
1907
1908 static int
dissect_sccp_3byte_pc(tvbuff_t * tvb,proto_tree * call_tree,guint offset,gboolean called)1909 dissect_sccp_3byte_pc(tvbuff_t *tvb, proto_tree *call_tree, guint offset,
1910 gboolean called)
1911 {
1912 int hf_pc;
1913
1914 if (decode_mtp3_standard == ANSI_STANDARD)
1915 {
1916 if (called)
1917 hf_pc = hf_sccp_called_ansi_pc;
1918 else
1919 hf_pc = hf_sccp_calling_ansi_pc;
1920 } else /* CHINESE_ITU_STANDARD */ {
1921 if (called)
1922 hf_pc = hf_sccp_called_chinese_pc;
1923 else
1924 hf_pc = hf_sccp_calling_chinese_pc;
1925 }
1926
1927 /* create and fill the PC tree */
1928 dissect_mtp3_3byte_pc(tvb, offset, call_tree,
1929 called ? ett_sccp_called_pc : ett_sccp_calling_pc,
1930 hf_pc,
1931 called ? hf_sccp_called_pc_network : hf_sccp_calling_pc_network,
1932 called ? hf_sccp_called_pc_cluster : hf_sccp_calling_pc_cluster,
1933 called ? hf_sccp_called_pc_member : hf_sccp_calling_pc_member,
1934 0, 0);
1935
1936 return(offset + ANSI_PC_LENGTH);
1937 }
1938
1939 /* FUNCTION dissect_sccp_called_calling_param():
1940 * Dissect the Calling or Called Party Address parameters.
1941 *
1942 * The boolean 'called' describes whether this function is decoding a
1943 * called (TRUE) or calling (FALSE) party address. There is simply too
1944 * much code in this function to have 2 copies of it (one for called, one
1945 * for calling).
1946 *
1947 * NOTE: this function is called even when (!tree) so that we can get
1948 * the SSN and subsequently call subdissectors (if and when there's a data
1949 * parameter). Realistically we should put if (!tree)'s around a lot of the
1950 * code, but I think that would make it unreadable--and the expense of not
1951 * doing so does not appear to be very high.
1952 */
1953 static void
dissect_sccp_called_calling_param(tvbuff_t * tvb,proto_tree * tree,packet_info * pinfo,guint length,gboolean called,sccp_decode_context_t * sccp_info)1954 dissect_sccp_called_calling_param(tvbuff_t *tvb, proto_tree *tree, packet_info *pinfo,
1955 guint length, gboolean called, sccp_decode_context_t* sccp_info)
1956 {
1957 proto_item *call_ai_item, *item, *hidden_item, *expert_item;
1958 proto_tree *call_tree, *call_ai_tree;
1959 guint offset;
1960 guint8 national = 0xFFU, routing_ind, gti, pci, ssni, ssn;
1961 tvbuff_t *gt_tvb;
1962 dissector_handle_t ssn_dissector = NULL, tcap_ssn_dissector = NULL;
1963 const char *ssn_dissector_short_name = NULL;
1964 const char *tcap_ssn_dissector_short_name = NULL;
1965
1966 call_tree = proto_tree_add_subtree_format(tree, tvb, 0, length,
1967 called ? ett_sccp_called : ett_sccp_calling, NULL,
1968 "%s Party address (%u byte%s)",
1969 called ? "Called" : "Calling", length,
1970 plurality(length, "", "s"));
1971
1972 call_ai_tree = proto_tree_add_subtree(call_tree, tvb, 0,
1973 ADDRESS_INDICATOR_LENGTH,
1974 called ? ett_sccp_called_ai : ett_sccp_calling_ai, &call_ai_item, "Address Indicator");
1975
1976 if (decode_mtp3_standard == ANSI_STANDARD) {
1977 national = tvb_get_guint8(tvb, 0) & ANSI_NATIONAL_MASK;
1978 expert_item = proto_tree_add_uint(call_ai_tree, called ? hf_sccp_called_ansi_national_indicator
1979 : hf_sccp_calling_ansi_national_indicator,
1980 tvb, 0, ADDRESS_INDICATOR_LENGTH, national);
1981 if (national == 0)
1982 expert_add_info(pinfo, expert_item, &ei_sccp_international_standard_address);
1983 } else {
1984 guint8 natl_use_bit = tvb_get_guint8(tvb, 0) & ITU_RESERVED_MASK;
1985
1986 proto_tree_add_uint(call_ai_tree, called ? hf_sccp_called_itu_natl_use_bit
1987 : hf_sccp_calling_itu_natl_use_bit,
1988 tvb, 0, ADDRESS_INDICATOR_LENGTH, natl_use_bit);
1989 }
1990
1991 routing_ind = tvb_get_guint8(tvb, 0) & ROUTING_INDICATOR_MASK;
1992 proto_tree_add_uint(call_ai_tree, called ? hf_sccp_called_routing_indicator : hf_sccp_calling_routing_indicator,
1993 tvb, 0, ADDRESS_INDICATOR_LENGTH, routing_ind);
1994 /* Only shift off the other bits after adding the item */
1995 routing_ind >>= ROUTING_INDICATOR_SHIFT;
1996
1997 gti = tvb_get_guint8(tvb, 0) & GTI_MASK;
1998
1999 if (decode_mtp3_standard == ITU_STANDARD ||
2000 decode_mtp3_standard == CHINESE_ITU_STANDARD ||
2001 decode_mtp3_standard == JAPAN_STANDARD ||
2002 national == 0) {
2003
2004 proto_tree_add_uint(call_ai_tree,
2005 called ? hf_sccp_called_itu_global_title_indicator : hf_sccp_calling_itu_global_title_indicator,
2006 tvb, 0, ADDRESS_INDICATOR_LENGTH, gti);
2007
2008 ssni = tvb_get_guint8(tvb, 0) & ITU_SSN_INDICATOR_MASK;
2009 expert_item = proto_tree_add_uint(call_ai_tree,
2010 called ? hf_sccp_called_itu_ssn_indicator : hf_sccp_calling_itu_ssn_indicator,
2011 tvb, 0, ADDRESS_INDICATOR_LENGTH, ssni);
2012 if ((routing_ind == ROUTE_ON_SSN) && (ssni == 0)) {
2013 expert_add_info(pinfo, expert_item, &ei_sccp_no_ssn_present);
2014 }
2015
2016 pci = tvb_get_guint8(tvb, 0) & ITU_PC_INDICATOR_MASK;
2017 proto_tree_add_uint(call_ai_tree, called ? hf_sccp_called_itu_point_code_indicator : hf_sccp_calling_itu_point_code_indicator,
2018 tvb, 0, ADDRESS_INDICATOR_LENGTH, pci);
2019
2020 offset = ADDRESS_INDICATOR_LENGTH;
2021
2022 /* Dissect PC (if present) */
2023 if (pci) {
2024 if (decode_mtp3_standard == ITU_STANDARD || national == 0) {
2025 if (length < offset + ITU_PC_LENGTH) {
2026 proto_tree_add_expert_format(call_tree, pinfo, &ei_sccp_wrong_length, tvb, 0, -1,
2027 "Wrong length indicated (%u) should be at least %u, PC is %u octets",
2028 length, offset + ITU_PC_LENGTH, ITU_PC_LENGTH);
2029 return;
2030 }
2031 proto_tree_add_item(call_tree, called ? hf_sccp_called_itu_pc : hf_sccp_calling_itu_pc,
2032 tvb, offset, ITU_PC_LENGTH, ENC_LITTLE_ENDIAN);
2033 offset += ITU_PC_LENGTH;
2034
2035 } else if (decode_mtp3_standard == JAPAN_STANDARD) {
2036
2037 if (length < offset + JAPAN_PC_LENGTH) {
2038 proto_tree_add_expert_format(call_tree, pinfo, &ei_sccp_wrong_length, tvb, 0, -1,
2039 "Wrong length indicated (%u) should be at least %u, PC is %u octets",
2040 length, offset + JAPAN_PC_LENGTH, JAPAN_PC_LENGTH);
2041 return;
2042 }
2043 proto_tree_add_item(call_tree, called ? hf_sccp_called_japan_pc : hf_sccp_calling_japan_pc,
2044 tvb, offset, JAPAN_PC_LENGTH, ENC_LITTLE_ENDIAN);
2045
2046 offset += JAPAN_PC_LENGTH;
2047
2048 } else /* CHINESE_ITU_STANDARD */ {
2049
2050 if (length < offset + ANSI_PC_LENGTH) {
2051 proto_tree_add_expert_format(call_tree, pinfo, &ei_sccp_wrong_length, tvb, 0, -1,
2052 "Wrong length indicated (%u) should be at least %u, PC is %u octets",
2053 length, offset + ANSI_PC_LENGTH, ANSI_PC_LENGTH);
2054 return;
2055 }
2056 offset = dissect_sccp_3byte_pc(tvb, call_tree, offset, called);
2057
2058 }
2059 }
2060
2061 /* Dissect SSN (if present) */
2062 if (ssni) {
2063 ssn = tvb_get_guint8(tvb, offset);
2064
2065 if ((routing_ind == ROUTE_ON_SSN) && (ssn == 0)) {
2066 expert_add_info(pinfo, expert_item, &ei_sccp_ssn_zero);
2067 }
2068
2069 if (called && sccp_info->assoc)
2070 sccp_info->assoc->called_ssn = ssn;
2071 else if (sccp_info->assoc)
2072 sccp_info->assoc->calling_ssn = ssn;
2073
2074 if (is_connectionless(sccp_info->message_type) && sccp_info->sccp_msg) {
2075 guint *ssn_ptr = called ? &(sccp_info->sccp_msg->data.ud.called_ssn) : &(sccp_info->sccp_msg->data.ud.calling_ssn);
2076
2077 *ssn_ptr = ssn;
2078 }
2079
2080 proto_tree_add_uint(call_tree, called ? hf_sccp_called_ssn
2081 : hf_sccp_calling_ssn,
2082 tvb, offset, ADDRESS_SSN_LENGTH, ssn);
2083 hidden_item = proto_tree_add_uint(call_tree, hf_sccp_ssn, tvb, offset,
2084 ADDRESS_SSN_LENGTH, ssn);
2085 proto_item_set_hidden(hidden_item);
2086
2087 offset += ADDRESS_SSN_LENGTH;
2088
2089 /* Get the dissector handle of the dissector registered for this ssn
2090 * And print its name.
2091 */
2092 ssn_dissector = dissector_get_uint_handle(sccp_ssn_dissector_table, ssn);
2093
2094 if (ssn_dissector) {
2095 ssn_dissector_short_name = dissector_handle_get_short_name(ssn_dissector);
2096
2097 if (ssn_dissector_short_name) {
2098 item = proto_tree_add_string_format(call_tree, hf_sccp_linked_dissector, tvb, offset - 1, ADDRESS_SSN_LENGTH,
2099 ssn_dissector_short_name, "Linked to %s", ssn_dissector_short_name);
2100 proto_item_set_generated(item);
2101
2102 if (g_ascii_strncasecmp("TCAP", ssn_dissector_short_name, 4)== 0) {
2103 tcap_ssn_dissector = get_itu_tcap_subdissector(ssn);
2104
2105 if (tcap_ssn_dissector) {
2106 tcap_ssn_dissector_short_name = dissector_handle_get_short_name(tcap_ssn_dissector);
2107 proto_item_append_text(item,", TCAP SSN linked to %s", tcap_ssn_dissector_short_name);
2108 }
2109 }
2110 } /* short name */
2111 } /* ssn_dissector */
2112 } /* ssni */
2113
2114 /* Dissect GT (if present) */
2115 if (gti != AI_GTI_NO_GT) {
2116 if (length < offset)
2117 return;
2118
2119 gt_tvb = tvb_new_subset_length(tvb, offset, (length - offset));
2120 dissect_sccp_global_title(gt_tvb, pinfo, call_tree, (length - offset), gti,
2121 called, sccp_info);
2122 }
2123
2124 } else if (decode_mtp3_standard == ANSI_STANDARD) {
2125
2126 proto_tree_add_uint(call_ai_tree, called ? hf_sccp_called_ansi_global_title_indicator
2127 : hf_sccp_calling_ansi_global_title_indicator,
2128 tvb, 0, ADDRESS_INDICATOR_LENGTH, gti);
2129
2130 pci = tvb_get_guint8(tvb, 0) & ANSI_PC_INDICATOR_MASK;
2131 proto_tree_add_uint(call_ai_tree, called ? hf_sccp_called_ansi_point_code_indicator
2132 : hf_sccp_calling_ansi_point_code_indicator,
2133 tvb, 0, ADDRESS_INDICATOR_LENGTH, pci);
2134
2135 ssni = tvb_get_guint8(tvb, 0) & ANSI_SSN_INDICATOR_MASK;
2136 expert_item = proto_tree_add_uint(call_ai_tree, called ? hf_sccp_called_ansi_ssn_indicator
2137 : hf_sccp_calling_ansi_ssn_indicator,
2138 tvb, 0, ADDRESS_INDICATOR_LENGTH, ssni);
2139 if ((routing_ind == ROUTE_ON_SSN) && (ssni == 0)) {
2140 expert_add_info(pinfo, expert_item, &ei_sccp_no_ssn_present);
2141 }
2142
2143 offset = ADDRESS_INDICATOR_LENGTH;
2144
2145 /* Dissect SSN (if present) */
2146 if (ssni) {
2147 ssn = tvb_get_guint8(tvb, offset);
2148
2149 if ((routing_ind == ROUTE_ON_SSN) && (ssn == 0)) {
2150 expert_add_info(pinfo, expert_item, &ei_sccp_ssn_zero);
2151 }
2152
2153 if (called && sccp_info->assoc) {
2154 sccp_info->assoc->called_ssn = ssn;
2155 } else if (sccp_info->assoc) {
2156 sccp_info->assoc->calling_ssn = ssn;
2157 }
2158
2159 if (is_connectionless(sccp_info->message_type) && sccp_info->sccp_msg) {
2160 guint *ssn_ptr = called ? &(sccp_info->sccp_msg->data.ud.called_ssn) : &(sccp_info->sccp_msg->data.ud.calling_ssn);
2161
2162 *ssn_ptr = ssn;
2163 }
2164
2165 proto_tree_add_uint(call_tree, called ? hf_sccp_called_ssn
2166 : hf_sccp_calling_ssn,
2167 tvb, offset, ADDRESS_SSN_LENGTH, ssn);
2168 hidden_item = proto_tree_add_uint(call_tree, hf_sccp_ssn, tvb, offset,
2169 ADDRESS_SSN_LENGTH, ssn);
2170 proto_item_set_hidden(hidden_item);
2171
2172 offset += ADDRESS_SSN_LENGTH;
2173 }
2174
2175 /* Dissect PC (if present) */
2176 if (pci) {
2177 offset = dissect_sccp_3byte_pc(tvb, call_tree, offset, called);
2178 }
2179
2180 /* Dissect GT (if present) */
2181 if (gti != AI_GTI_NO_GT) {
2182 if (length < offset)
2183 return;
2184 gt_tvb = tvb_new_subset_length(tvb, offset, (length - offset));
2185 dissect_sccp_global_title(gt_tvb, pinfo, call_tree, (length - offset), gti,
2186 called, sccp_info);
2187 }
2188
2189 }
2190
2191 }
2192
2193 static void
dissect_sccp_called_param(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,guint length,sccp_decode_context_t * sccp_info)2194 dissect_sccp_called_param(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint length, sccp_decode_context_t* sccp_info)
2195 {
2196 dissect_sccp_called_calling_param(tvb, tree, pinfo, length, TRUE, sccp_info);
2197 }
2198
2199 static void
dissect_sccp_calling_param(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,guint length,sccp_decode_context_t * sccp_info)2200 dissect_sccp_calling_param(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint length, sccp_decode_context_t* sccp_info)
2201 {
2202 dissect_sccp_called_calling_param(tvb, tree, pinfo, length, FALSE, sccp_info);
2203 }
2204
2205 static void
dissect_sccp_class_param(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,guint length,sccp_decode_context_t * sccp_info)2206 dissect_sccp_class_param(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint length, sccp_decode_context_t* sccp_info)
2207 {
2208 guint8 msg_class;
2209 proto_item *pi;
2210 gboolean invalid_class = FALSE;
2211
2212 if (length != 1) {
2213 proto_tree_add_expert_format(tree, pinfo, &ei_sccp_wrong_length, tvb, 0, length,
2214 "Wrong length indicated. Expected 1, got %u", length);
2215 return;
2216 }
2217
2218 msg_class = tvb_get_guint8(tvb, 0) & CLASS_CLASS_MASK;
2219 pi = proto_tree_add_uint(tree, hf_sccp_class, tvb, 0, length, msg_class);
2220
2221 switch (sccp_info->message_type) {
2222 case SCCP_MSG_TYPE_DT1:
2223 if (msg_class != 2)
2224 invalid_class = TRUE;
2225 break;
2226 case SCCP_MSG_TYPE_DT2:
2227 case SCCP_MSG_TYPE_AK:
2228 case SCCP_MSG_TYPE_ED:
2229 case SCCP_MSG_TYPE_EA:
2230 case SCCP_MSG_TYPE_RSR:
2231 case SCCP_MSG_TYPE_RSC:
2232 if (msg_class != 3)
2233 invalid_class = TRUE;
2234 break;
2235 case SCCP_MSG_TYPE_CR:
2236 case SCCP_MSG_TYPE_CC:
2237 case SCCP_MSG_TYPE_CREF:
2238 case SCCP_MSG_TYPE_RLSD:
2239 case SCCP_MSG_TYPE_RLC:
2240 case SCCP_MSG_TYPE_ERR:
2241 case SCCP_MSG_TYPE_IT:
2242 if ((msg_class != 2) && (msg_class != 3))
2243 invalid_class = TRUE;
2244 break;
2245 case SCCP_MSG_TYPE_UDT:
2246 case SCCP_MSG_TYPE_UDTS:
2247 case SCCP_MSG_TYPE_XUDT:
2248 case SCCP_MSG_TYPE_XUDTS:
2249 case SCCP_MSG_TYPE_LUDT:
2250 case SCCP_MSG_TYPE_LUDTS:
2251 if ((msg_class != 0) && (msg_class != 1))
2252 invalid_class = TRUE;
2253 break;
2254 }
2255
2256 if (invalid_class)
2257 expert_add_info(pinfo, pi, &ei_sccp_class_unexpected);
2258
2259 if (msg_class == 0 || msg_class == 1) {
2260 guint8 handling = tvb_get_guint8(tvb, 0) & CLASS_SPARE_HANDLING_MASK;
2261
2262 pi = proto_tree_add_item(tree, hf_sccp_handling, tvb, 0, length, ENC_NA);
2263 handling >>= CLASS_SPARE_HANDLING_SHIFT;
2264
2265 if (try_val_to_str(handling, sccp_class_handling_values) == NULL) {
2266 expert_add_info(pinfo, pi, &ei_sccp_handling_invalid);
2267 }
2268 }
2269 }
2270
2271 static void
dissect_sccp_segmenting_reassembling_param(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,guint length)2272 dissect_sccp_segmenting_reassembling_param(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint length)
2273 {
2274 if (length != 1) {
2275 proto_tree_add_expert_format(tree, pinfo, &ei_sccp_wrong_length, tvb, 0, length,
2276 "Wrong length indicated. Expected 1, got %u", length);
2277 return;
2278 }
2279
2280 proto_tree_add_item(tree, hf_sccp_more, tvb, 0, length, ENC_BIG_ENDIAN);
2281 }
2282
2283 static void
dissect_sccp_receive_sequence_number_param(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,guint length)2284 dissect_sccp_receive_sequence_number_param(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint length)
2285 {
2286 guint8 rsn;
2287
2288 if (length != 1) {
2289 proto_tree_add_expert_format(tree, pinfo, &ei_sccp_wrong_length, tvb, 0, length,
2290 "Wrong length indicated. Expected 1, got %u", length);
2291 return;
2292 }
2293
2294 rsn = tvb_get_guint8(tvb, 0) >> 1;
2295 proto_tree_add_uint(tree, hf_sccp_rsn, tvb, 0, length, rsn);
2296 }
2297
2298 static void
dissect_sccp_sequencing_segmenting_param(tvbuff_t * tvb,proto_tree * tree,guint length)2299 dissect_sccp_sequencing_segmenting_param(tvbuff_t *tvb, proto_tree *tree, guint length)
2300 {
2301 guint8 rsn, ssn;
2302 proto_tree *param_tree;
2303
2304 ssn = tvb_get_guint8(tvb, 0) >> 1;
2305 rsn = tvb_get_guint8(tvb, SEQUENCING_SEGMENTING_SSN_LENGTH) >> 1;
2306
2307 param_tree = proto_tree_add_subtree(tree, tvb, 0, length, ett_sccp_sequencing_segmenting, NULL,
2308 val_to_str(PARAMETER_SEQUENCING_SEGMENTING,
2309 sccp_parameter_values, "Unknown: %d"));
2310
2311 proto_tree_add_uint(param_tree, hf_sccp_sequencing_segmenting_ssn, tvb, 0,
2312 SEQUENCING_SEGMENTING_SSN_LENGTH, ssn);
2313 proto_tree_add_uint(param_tree, hf_sccp_sequencing_segmenting_rsn, tvb,
2314 SEQUENCING_SEGMENTING_SSN_LENGTH,
2315 SEQUENCING_SEGMENTING_RSN_LENGTH, rsn);
2316 proto_tree_add_item(param_tree, hf_sccp_sequencing_segmenting_more, tvb,
2317 SEQUENCING_SEGMENTING_SSN_LENGTH,
2318 SEQUENCING_SEGMENTING_RSN_LENGTH, ENC_NA);
2319 }
2320
2321 static void
dissect_sccp_credit_param(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,guint length)2322 dissect_sccp_credit_param(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint length)
2323 {
2324 if (length != 1) {
2325 proto_tree_add_expert_format(tree, pinfo, &ei_sccp_wrong_length, tvb, 0, length,
2326 "Wrong length indicated. Expected 1, got %u", length);
2327 return;
2328 }
2329
2330 proto_tree_add_item(tree, hf_sccp_credit, tvb, 0, length, ENC_NA);
2331 }
2332
2333 static void
dissect_sccp_release_cause_param(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,guint length)2334 dissect_sccp_release_cause_param(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint length)
2335 {
2336 if (length != 1) {
2337 proto_tree_add_expert_format(tree, pinfo, &ei_sccp_wrong_length, tvb, 0, length,
2338 "Wrong length indicated. Expected 1, got %u", length);
2339 return;
2340 }
2341
2342 proto_tree_add_item(tree, hf_sccp_release_cause, tvb, 0, length, ENC_LITTLE_ENDIAN);
2343
2344 if (show_key_params)
2345 col_append_fstr(pinfo->cinfo, COL_INFO, "Cause=%d ", tvb_get_guint8(tvb, 0));
2346 }
2347
2348 static void
dissect_sccp_return_cause_param(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,guint length)2349 dissect_sccp_return_cause_param(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint length)
2350 {
2351 if (length != 1) {
2352 proto_tree_add_expert_format(tree, pinfo, &ei_sccp_wrong_length, tvb, 0, length,
2353 "Wrong length indicated. Expected 1, got %u", length);
2354 return;
2355 }
2356
2357 proto_tree_add_item(tree, hf_sccp_return_cause, tvb, 0, length, ENC_LITTLE_ENDIAN);
2358
2359 if (show_key_params)
2360 col_append_fstr(pinfo->cinfo, COL_INFO, "Cause=%d ", tvb_get_guint8(tvb, 0));
2361 }
2362
2363 static void
dissect_sccp_reset_cause_param(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,guint length)2364 dissect_sccp_reset_cause_param(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint length)
2365 {
2366 if (length != 1) {
2367 proto_tree_add_expert_format(tree, pinfo, &ei_sccp_wrong_length, tvb, 0, length,
2368 "Wrong length indicated. Expected 1, got %u", length);
2369 return;
2370 }
2371
2372 proto_tree_add_item(tree, hf_sccp_reset_cause, tvb, 0, length, ENC_LITTLE_ENDIAN);
2373
2374 if (show_key_params)
2375 col_append_fstr(pinfo->cinfo, COL_INFO, "Cause=%d ", tvb_get_guint8(tvb, 0));
2376 }
2377
2378 static void
dissect_sccp_error_cause_param(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,guint length)2379 dissect_sccp_error_cause_param(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint length)
2380 {
2381 if (length != 1) {
2382 proto_tree_add_expert_format(tree, pinfo, &ei_sccp_wrong_length, tvb, 0, length,
2383 "Wrong length indicated. Expected 1, got %u", length);
2384 return;
2385 }
2386
2387 proto_tree_add_item(tree, hf_sccp_error_cause, tvb, 0, length, ENC_LITTLE_ENDIAN);
2388
2389 if (show_key_params)
2390 col_append_fstr(pinfo->cinfo, COL_INFO, "Cause=%d ", tvb_get_guint8(tvb, 0));
2391 }
2392
2393 static void
dissect_sccp_refusal_cause_param(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,guint length)2394 dissect_sccp_refusal_cause_param(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint length)
2395 {
2396 if (length != 1) {
2397 proto_tree_add_expert_format(tree, pinfo, &ei_sccp_wrong_length, tvb, 0, length,
2398 "Wrong length indicated. Expected 1, got %u", length);
2399 return;
2400 }
2401
2402 proto_tree_add_item(tree, hf_sccp_refusal_cause, tvb, 0, length, ENC_LITTLE_ENDIAN);
2403
2404 if (show_key_params)
2405 col_append_fstr(pinfo->cinfo, COL_INFO, "Cause=%d ", tvb_get_guint8(tvb, 0));
2406 }
2407
2408
2409 /* This function is used for both data and long data (ITU only) parameters */
2410 static void
dissect_sccp_data_param(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,sccp_assoc_info_t * assoc)2411 dissect_sccp_data_param(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, sccp_assoc_info_t *assoc)
2412 {
2413 guint8 ssn = INVALID_SSN;
2414 guint8 other_ssn = INVALID_SSN;
2415 const mtp3_addr_pc_t *dpc = NULL;
2416 const mtp3_addr_pc_t *opc = NULL;
2417 heur_dtbl_entry_t *hdtbl_entry;
2418 struct _sccp_msg_info_t* sccp_info = NULL;
2419
2420 if ((trace_sccp) && (assoc && assoc != &no_assoc)) {
2421 sccp_info = assoc->curr_msg;
2422 }
2423
2424 if (assoc) {
2425 switch (pinfo->p2p_dir) {
2426 case P2P_DIR_SENT:
2427 ssn = assoc->calling_ssn;
2428 other_ssn = assoc->called_ssn;
2429 dpc = (const mtp3_addr_pc_t*)pinfo->dst.data;
2430 opc = (const mtp3_addr_pc_t*)pinfo->src.data;
2431 break;
2432 case P2P_DIR_RECV:
2433 ssn = assoc->called_ssn;
2434 other_ssn = assoc->calling_ssn;
2435 dpc = (const mtp3_addr_pc_t*)pinfo->src.data;
2436 opc = (const mtp3_addr_pc_t*)pinfo->dst.data;
2437 break;
2438 default:
2439 ssn = assoc->called_ssn;
2440 other_ssn = assoc->calling_ssn;
2441 dpc = (const mtp3_addr_pc_t*)pinfo->dst.data;
2442 opc = (const mtp3_addr_pc_t*)pinfo->src.data;
2443 break;
2444 }
2445 }
2446
2447
2448 if ((num_sccp_users) && (pinfo->src.type == ss7pc_address_type)) {
2449 guint i;
2450 dissector_handle_t handle = NULL;
2451 gboolean uses_tcap = FALSE;
2452
2453 for (i=0; i < num_sccp_users; i++) {
2454 sccp_user_t *u = &(sccp_users[i]);
2455
2456 if (!dpc || dpc->ni != u->ni) continue;
2457
2458 if (value_is_in_range(u->called_ssn, ssn) && value_is_in_range(u->called_pc, dpc->pc) ) {
2459 handle = *(u->handlep);
2460 uses_tcap = u->uses_tcap;
2461 break;
2462 } else if (value_is_in_range(u->called_ssn, other_ssn) && opc && value_is_in_range(u->called_pc, opc->pc) ) {
2463 handle = *(u->handlep);
2464 uses_tcap = u->uses_tcap;
2465 break;
2466 }
2467 }
2468
2469 if (handle) {
2470 if (uses_tcap) {
2471 call_tcap_dissector(handle, tvb, pinfo, tree);
2472 } else {
2473 call_dissector_with_data(handle, tvb, pinfo, tree, sccp_info);
2474 }
2475 return;
2476 }
2477
2478 }
2479
2480 /* Save SSN for Decode As */
2481 p_add_proto_data(pinfo->pool, pinfo, proto_sccp, 0, GUINT_TO_POINTER((guint)ssn));
2482
2483 if ((ssn != INVALID_SSN) && dissector_try_uint_new(sccp_ssn_dissector_table, ssn, tvb, pinfo, tree, TRUE, sccp_info)) {
2484 return;
2485 }
2486
2487 if ((other_ssn != INVALID_SSN) && dissector_try_uint_new(sccp_ssn_dissector_table, other_ssn, tvb, pinfo, tree, TRUE, sccp_info)) {
2488 return;
2489 }
2490
2491 /* try heuristic subdissector list to see if there are any takers */
2492 if (dissector_try_heuristic(heur_subdissector_list, tvb, pinfo, tree, &hdtbl_entry, sccp_info)) {
2493 return;
2494 }
2495
2496 /* try user default subdissector */
2497 if (default_handle) {
2498 call_dissector_with_data(default_handle, tvb, pinfo, tree, sccp_info);
2499 return;
2500 }
2501
2502 /* No sub-dissection occurred, treat it as raw data */
2503 call_dissector(data_handle, tvb, pinfo, tree);
2504
2505 }
2506
2507 static void
dissect_sccp_segmentation_param(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,guint length)2508 dissect_sccp_segmentation_param(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint length)
2509 {
2510 proto_tree *param_tree;
2511
2512 param_tree = proto_tree_add_subtree(tree, tvb, 0, length, ett_sccp_segmentation, NULL,
2513 val_to_str(PARAMETER_SEGMENTATION,
2514 sccp_parameter_values, "Unknown: %d"));
2515
2516 proto_tree_add_item(param_tree, hf_sccp_segmentation_first, tvb, 0, 1, ENC_NA);
2517 proto_tree_add_item(param_tree, hf_sccp_segmentation_class, tvb, 0, 1, ENC_NA);
2518 proto_tree_add_item(param_tree, hf_sccp_segmentation_remaining, tvb, 0, 1, ENC_NA);
2519
2520 if (length-1 != 3) {
2521 proto_tree_add_expert_format(tree, pinfo, &ei_sccp_wrong_length, tvb, 0, length-1,
2522 "Wrong length indicated. Expected 3, got %u", length-1);
2523 return;
2524 }
2525
2526 proto_tree_add_item(param_tree, hf_sccp_segmentation_slr, tvb, 1, length-1, ENC_LITTLE_ENDIAN);
2527 }
2528
2529 static void
dissect_sccp_hop_counter_param(tvbuff_t * tvb,proto_tree * tree,guint length)2530 dissect_sccp_hop_counter_param(tvbuff_t *tvb, proto_tree *tree, guint length)
2531 {
2532 guint8 hops;
2533
2534 hops = tvb_get_guint8(tvb, 0);
2535 proto_tree_add_uint(tree, hf_sccp_hop_counter, tvb, 0, length, hops);
2536 }
2537
2538 static void
dissect_sccp_importance_param(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,guint length)2539 dissect_sccp_importance_param(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint length)
2540 {
2541 if (length != 1) {
2542 proto_tree_add_expert_format(tree, pinfo, &ei_sccp_wrong_length, tvb, 0, length,
2543 "Wrong length indicated. Expected 1, got %u", length);
2544 return;
2545 }
2546
2547 proto_tree_add_item(tree, hf_sccp_importance, tvb, 0, length, ENC_NA);
2548 }
2549
2550 static void
dissect_sccp_isni_param(tvbuff_t * tvb,proto_tree * tree,guint length)2551 dissect_sccp_isni_param(tvbuff_t *tvb, proto_tree *tree, guint length)
2552 {
2553 guint8 ti;
2554 guint offset = 0;
2555 proto_tree *param_tree;
2556
2557 /* Create a subtree for ISNI Routing Control */
2558 param_tree = proto_tree_add_subtree(tree, tvb, offset, ANSI_ISNI_ROUTING_CONTROL_LENGTH,
2559 ett_sccp_ansi_isni_routing_control, NULL, "ISNI Routing Control");
2560
2561 proto_tree_add_item(param_tree, hf_sccp_ansi_isni_mi, tvb, offset,
2562 ANSI_ISNI_ROUTING_CONTROL_LENGTH, ENC_NA);
2563
2564 proto_tree_add_item(param_tree, hf_sccp_ansi_isni_iri, tvb, offset,
2565 ANSI_ISNI_ROUTING_CONTROL_LENGTH, ENC_NA);
2566
2567 ti = tvb_get_guint8(tvb, offset) & ANSI_ISNI_TI_MASK;
2568 proto_tree_add_uint(param_tree, hf_sccp_ansi_isni_ti, tvb, offset,
2569 ANSI_ISNI_ROUTING_CONTROL_LENGTH, ti);
2570
2571 proto_tree_add_item(param_tree, hf_sccp_ansi_isni_counter, tvb, offset,
2572 ANSI_ISNI_ROUTING_CONTROL_LENGTH, ENC_NA);
2573
2574 offset += ANSI_ISNI_ROUTING_CONTROL_LENGTH;
2575
2576 if ((ti >> ANSI_ISNI_TI_SHIFT) == ANSI_ISNI_TYPE_1) {
2577 proto_tree_add_uint(param_tree, hf_sccp_ansi_isni_netspec, tvb, offset,
2578 ANSI_ISNI_ROUTING_CONTROL_LENGTH, ti);
2579 offset += ANSI_ISNI_ROUTING_CONTROL_LENGTH;
2580 }
2581
2582 while (offset < length) {
2583
2584 proto_tree_add_item(tree, hf_sccp_ansi_isni_network, tvb, offset,
2585 ANSI_NCM_LENGTH, ENC_NA);
2586 offset++;
2587
2588 proto_tree_add_item(tree, hf_sccp_ansi_isni_cluster, tvb, offset,
2589 ANSI_NCM_LENGTH, ENC_NA);
2590 offset++;
2591 }
2592
2593 }
2594
2595 /* FUNCTION dissect_sccp_parameter():
2596 * Dissect a parameter given its type, offset into tvb, and length.
2597 */
2598 static guint16
dissect_sccp_parameter(tvbuff_t * tvb,packet_info * pinfo,proto_tree * sccp_tree,proto_tree * tree,guint8 parameter_type,int offset,guint16 parameter_length,sccp_decode_context_t * sccp_info)2599 dissect_sccp_parameter(tvbuff_t *tvb, packet_info *pinfo, proto_tree *sccp_tree,
2600 proto_tree *tree, guint8 parameter_type, int offset,
2601 guint16 parameter_length, sccp_decode_context_t *sccp_info)
2602 {
2603 tvbuff_t *parameter_tvb;
2604
2605 switch (parameter_type) {
2606 case PARAMETER_CALLED_PARTY_ADDRESS:
2607 case PARAMETER_CALLING_PARTY_ADDRESS:
2608 case PARAMETER_DATA:
2609 case PARAMETER_LONG_DATA:
2610 case PARAMETER_SOURCE_LOCAL_REFERENCE:
2611 case PARAMETER_DESTINATION_LOCAL_REFERENCE:
2612 case PARAMETER_RELEASE_CAUSE:
2613 case PARAMETER_RETURN_CAUSE:
2614 case PARAMETER_RESET_CAUSE:
2615 case PARAMETER_ERROR_CAUSE:
2616 case PARAMETER_REFUSAL_CAUSE:
2617
2618 /* These parameters must be dissected even if !sccp_tree (so that
2619 * assoc information can be created).
2620 */
2621 break;
2622
2623 default:
2624 if (!sccp_tree) return(parameter_length);
2625
2626 }
2627
2628 parameter_tvb = tvb_new_subset_length(tvb, offset, parameter_length);
2629
2630 switch (parameter_type) {
2631
2632 case PARAMETER_END_OF_OPTIONAL_PARAMETERS:
2633 proto_tree_add_item(sccp_tree, hf_sccp_end_optional_param, tvb, offset, parameter_length, ENC_NA);
2634 break;
2635
2636 case PARAMETER_DESTINATION_LOCAL_REFERENCE:
2637 dissect_sccp_dlr_param(parameter_tvb, pinfo, sccp_tree, parameter_length, sccp_info);
2638 break;
2639
2640 case PARAMETER_SOURCE_LOCAL_REFERENCE:
2641 dissect_sccp_slr_param(parameter_tvb, pinfo, sccp_tree, parameter_length, sccp_info);
2642 break;
2643
2644 case PARAMETER_CALLED_PARTY_ADDRESS:
2645 dissect_sccp_called_param(parameter_tvb, pinfo, sccp_tree, parameter_length, sccp_info);
2646 break;
2647
2648 case PARAMETER_CALLING_PARTY_ADDRESS:
2649 dissect_sccp_calling_param(parameter_tvb, pinfo, sccp_tree, parameter_length, sccp_info);
2650 break;
2651
2652 case PARAMETER_CLASS:
2653 dissect_sccp_class_param(parameter_tvb, pinfo, sccp_tree, parameter_length, sccp_info);
2654 break;
2655
2656 case PARAMETER_SEGMENTING_REASSEMBLING:
2657 dissect_sccp_segmenting_reassembling_param(parameter_tvb, pinfo, sccp_tree,
2658 parameter_length);
2659 break;
2660
2661 case PARAMETER_RECEIVE_SEQUENCE_NUMBER:
2662 dissect_sccp_receive_sequence_number_param(parameter_tvb, pinfo, sccp_tree,
2663 parameter_length);
2664 break;
2665
2666 case PARAMETER_SEQUENCING_SEGMENTING:
2667 dissect_sccp_sequencing_segmenting_param(parameter_tvb, sccp_tree,
2668 parameter_length);
2669 break;
2670
2671 case PARAMETER_CREDIT:
2672 dissect_sccp_credit_param(parameter_tvb, pinfo, sccp_tree, parameter_length);
2673 break;
2674
2675 case PARAMETER_RELEASE_CAUSE:
2676 dissect_sccp_release_cause_param(parameter_tvb, pinfo, sccp_tree, parameter_length);
2677 break;
2678
2679 case PARAMETER_RETURN_CAUSE:
2680 dissect_sccp_return_cause_param(parameter_tvb, pinfo, sccp_tree, parameter_length);
2681 break;
2682
2683 case PARAMETER_RESET_CAUSE:
2684 dissect_sccp_reset_cause_param(parameter_tvb, pinfo, sccp_tree, parameter_length);
2685 break;
2686
2687 case PARAMETER_ERROR_CAUSE:
2688 dissect_sccp_error_cause_param(parameter_tvb, pinfo, sccp_tree, parameter_length);
2689 break;
2690
2691 case PARAMETER_REFUSAL_CAUSE:
2692 dissect_sccp_refusal_cause_param(parameter_tvb, pinfo, sccp_tree, parameter_length);
2693 break;
2694
2695 case PARAMETER_DATA:
2696 dissect_sccp_data_param(parameter_tvb, pinfo, tree, sccp_info->assoc);
2697
2698 /* TODO? Re-adjust length of SCCP item since it may be sub-dissected */
2699 /* sccp_length = proto_item_get_len(sccp_item);
2700 * sccp_length -= parameter_length;
2701 * proto_item_set_len(sccp_item, sccp_length);
2702 *
2703 * except that proto_item_get_len() is *NOT* guaranteed to return
2704 * a correct value - if the item has been "faked", it will be wrong
2705 */
2706 break;
2707
2708 case PARAMETER_SEGMENTATION:
2709 dissect_sccp_segmentation_param(parameter_tvb, pinfo, sccp_tree, parameter_length);
2710 break;
2711
2712 case PARAMETER_HOP_COUNTER:
2713 dissect_sccp_hop_counter_param(parameter_tvb, sccp_tree, parameter_length);
2714 break;
2715
2716 case PARAMETER_IMPORTANCE:
2717 if (decode_mtp3_standard != ANSI_STANDARD)
2718 dissect_sccp_importance_param(parameter_tvb, pinfo, sccp_tree, parameter_length);
2719 else
2720 dissect_sccp_unknown_param(parameter_tvb, sccp_tree, parameter_type,
2721 parameter_length);
2722 break;
2723
2724 case PARAMETER_LONG_DATA:
2725 dissect_sccp_data_param(parameter_tvb, pinfo, tree, sccp_info->assoc);
2726 break;
2727
2728 case PARAMETER_ISNI:
2729 if (decode_mtp3_standard != ANSI_STANDARD)
2730 dissect_sccp_unknown_param(parameter_tvb, sccp_tree, parameter_type,
2731 parameter_length);
2732 else
2733 dissect_sccp_isni_param(parameter_tvb, sccp_tree, parameter_length);
2734 break;
2735
2736 default:
2737 dissect_sccp_unknown_param(parameter_tvb, sccp_tree, parameter_type,
2738 parameter_length);
2739 break;
2740 }
2741
2742 return(parameter_length);
2743 }
2744
2745 /* FUNCTION dissect_sccp_variable_parameter():
2746 * Dissect a variable parameter given its type and offset into tvb. Length
2747 * of the parameter is gotten from tvb[0].
2748 * Length returned is sum of (length + parameter).
2749 */
2750 static guint16
dissect_sccp_variable_parameter(tvbuff_t * tvb,packet_info * pinfo,proto_tree * sccp_tree,proto_tree * tree,guint8 parameter_type,int offset,sccp_decode_context_t * sccp_info)2751 dissect_sccp_variable_parameter(tvbuff_t *tvb, packet_info *pinfo,
2752 proto_tree *sccp_tree, proto_tree *tree,
2753 guint8 parameter_type, int offset, sccp_decode_context_t* sccp_info)
2754 {
2755 guint16 parameter_length;
2756 guint8 length_length;
2757 proto_item *pi;
2758
2759 if (parameter_type != PARAMETER_LONG_DATA) {
2760 parameter_length = tvb_get_guint8(tvb, offset);
2761 length_length = PARAMETER_LENGTH_LENGTH;
2762 } else {
2763 /* Long data parameter has 16 bit length */
2764 parameter_length = tvb_get_letohs(tvb, offset);
2765 length_length = PARAMETER_LONG_DATA_LENGTH_LENGTH;
2766 }
2767
2768 pi = proto_tree_add_uint_format(sccp_tree, hf_sccp_param_length, tvb, offset,
2769 length_length, parameter_length, "%s length: %d",
2770 val_to_str(parameter_type, sccp_parameter_values,
2771 "Unknown: %d"),
2772 parameter_length);
2773 if (!sccp_show_length) {
2774 /* The user doesn't want to see it... */
2775 proto_item_set_hidden(pi);
2776 }
2777
2778 offset += length_length;
2779
2780 dissect_sccp_parameter(tvb, pinfo, sccp_tree, tree, parameter_type, offset,
2781 parameter_length, sccp_info);
2782
2783 return(parameter_length + length_length);
2784 }
2785
2786 /* FUNCTION dissect_sccp_optional_parameters():
2787 * Dissect all the optional parameters given the start of the optional
2788 * parameters into tvb. Parameter types and lengths are read from tvb.
2789 */
2790 static void
dissect_sccp_optional_parameters(tvbuff_t * tvb,packet_info * pinfo,proto_tree * sccp_tree,proto_tree * tree,int offset,sccp_decode_context_t * sccp_info)2791 dissect_sccp_optional_parameters(tvbuff_t *tvb, packet_info *pinfo,
2792 proto_tree *sccp_tree, proto_tree *tree,
2793 int offset, sccp_decode_context_t* sccp_info)
2794 {
2795 guint8 parameter_type;
2796
2797 while ((parameter_type = tvb_get_guint8(tvb, offset)) !=
2798 PARAMETER_END_OF_OPTIONAL_PARAMETERS) {
2799
2800 offset += PARAMETER_TYPE_LENGTH;
2801 offset += dissect_sccp_variable_parameter(tvb, pinfo, sccp_tree, tree,
2802 parameter_type, offset, sccp_info);
2803 }
2804
2805 /* Process end of optional parameters */
2806 dissect_sccp_parameter(tvb, pinfo, sccp_tree, tree, parameter_type, offset,
2807 END_OF_OPTIONAL_PARAMETERS_LENGTH, sccp_info);
2808
2809 }
2810
2811 static sccp_msg_info_t *
new_ud_msg(packet_info * pinfo,guint32 msg_type _U_)2812 new_ud_msg(packet_info *pinfo, guint32 msg_type _U_)
2813 {
2814 sccp_msg_info_t *m = wmem_new0(pinfo->pool, sccp_msg_info_t);
2815 m->framenum = pinfo->num;
2816 m->data.ud.calling_gt = NULL;
2817 m->data.ud.called_gt = NULL;
2818
2819 return m;
2820 }
2821
build_assoc_tree(tvbuff_t * tvb,packet_info * pinfo,proto_tree * sccp_tree,sccp_decode_context_t * sccp_info,guint msg_offset)2822 static void build_assoc_tree(tvbuff_t *tvb, packet_info *pinfo, proto_tree *sccp_tree,
2823 sccp_decode_context_t *sccp_info, guint msg_offset)
2824 {
2825 if (trace_sccp && sccp_info->assoc && (sccp_info->assoc != &no_assoc)) {
2826 proto_item *pi = proto_tree_add_uint(sccp_tree, hf_sccp_assoc_id, tvb, 0, 0, sccp_info->assoc->id);
2827 proto_item_set_generated(pi);
2828 proto_tree *pt = proto_item_add_subtree(pi, ett_sccp_assoc);
2829 if(sccp_info->assoc->imsi){
2830 proto_item *pi2 = proto_tree_add_string(sccp_tree, hf_assoc_imsi, tvb, 0, 0, sccp_info->assoc->imsi);
2831 proto_item_set_generated(pi2);
2832 }
2833 if (sccp_info->assoc->msgs) {
2834 sccp_msg_info_t *m;
2835 for(m = sccp_info->assoc->msgs; m ; m = m->data.co.next) {
2836 pi = proto_tree_add_uint(pt, hf_sccp_assoc_msg, tvb, 0, 0, m->framenum);
2837
2838 if (sccp_info->assoc->payload != SCCP_PLOAD_NONE)
2839 proto_item_append_text(pi," %s", val_to_str(sccp_info->assoc->payload, assoc_protos, "Unknown: %d"));
2840
2841 if (m->data.co.label)
2842 proto_item_append_text(pi," %s", m->data.co.label);
2843 if (m->data.co.imsi)
2844 proto_item_append_text(pi, " %s", m->data.co.imsi);
2845
2846 if ((m->framenum == pinfo->num) && (m->offset == msg_offset) ) {
2847 tap_queue_packet(sccp_tap, pinfo, m);
2848 proto_item_append_text(pi," (current)");
2849 }
2850 proto_item_set_generated(pi);
2851 }
2852 }
2853 }
2854 }
2855
2856 static int
dissect_xudt_common(tvbuff_t * tvb,packet_info * pinfo,proto_tree * sccp_tree,proto_tree * tree,int offset,sccp_decode_context_t * sccp_info,guint16 * optional_pointer_p,guint16 * orig_opt_ptr_p)2857 dissect_xudt_common(tvbuff_t *tvb, packet_info *pinfo, proto_tree *sccp_tree,
2858 proto_tree *tree, int offset, sccp_decode_context_t *sccp_info,
2859 guint16 *optional_pointer_p, guint16 *orig_opt_ptr_p)
2860 {
2861 guint16 variable_pointer1 = 0, variable_pointer2 = 0, variable_pointer3 = 0;
2862 guint16 optional_pointer = 0, orig_opt_ptr = 0;
2863 tvbuff_t *new_tvb = NULL;
2864 guint32 source_local_ref = 0;
2865 guint msg_offset = tvb_offset_from_real_beginning(tvb);
2866
2867 /* Macro for getting pointer to mandatory variable parameters */
2868 #define VARIABLE_POINTER(var, hf_var, ptr_size) \
2869 do { \
2870 if (ptr_size == POINTER_LENGTH) \
2871 var = tvb_get_guint8(tvb, offset); \
2872 else \
2873 var = tvb_get_letohs(tvb, offset); \
2874 proto_tree_add_uint(sccp_tree, hf_var, tvb, \
2875 offset, ptr_size, var); \
2876 var += offset; \
2877 if (ptr_size == POINTER_LENGTH_LONG) \
2878 var += 1; \
2879 offset += ptr_size; \
2880 } while (0)
2881
2882 /* Macro for getting pointer to optional parameters */
2883 #define OPTIONAL_POINTER(ptr_size) \
2884 do { \
2885 if (ptr_size == POINTER_LENGTH) \
2886 orig_opt_ptr = optional_pointer = tvb_get_guint8(tvb, offset); \
2887 else \
2888 orig_opt_ptr = optional_pointer = tvb_get_letohs(tvb, offset); \
2889 proto_tree_add_uint(sccp_tree, hf_sccp_optional_pointer, tvb, \
2890 offset, ptr_size, optional_pointer); \
2891 optional_pointer += offset; \
2892 if (ptr_size == POINTER_LENGTH_LONG) \
2893 optional_pointer += 1; \
2894 offset += ptr_size; \
2895 } while (0)
2896
2897
2898 /* Optional parameters are Segmentation and Importance
2899 * NOTE 2 - Segmentation Should not be present in case of a single XUDT
2900 * message.
2901 */
2902
2903 VARIABLE_POINTER(variable_pointer1, hf_sccp_variable_pointer1, POINTER_LENGTH);
2904 VARIABLE_POINTER(variable_pointer2, hf_sccp_variable_pointer2, POINTER_LENGTH);
2905 VARIABLE_POINTER(variable_pointer3, hf_sccp_variable_pointer3, POINTER_LENGTH);
2906 OPTIONAL_POINTER(POINTER_LENGTH);
2907
2908 sccp_info->assoc = get_sccp_assoc(pinfo, msg_offset, sccp_info);
2909 build_assoc_tree(tvb, pinfo, sccp_tree, sccp_info, msg_offset);
2910
2911 dissect_sccp_variable_parameter(tvb, pinfo, sccp_tree, tree,
2912 PARAMETER_CALLED_PARTY_ADDRESS,
2913 variable_pointer1, sccp_info);
2914 dissect_sccp_variable_parameter(tvb, pinfo, sccp_tree, tree,
2915 PARAMETER_CALLING_PARTY_ADDRESS,
2916 variable_pointer2, sccp_info);
2917
2918 if (tvb_get_guint8(tvb, optional_pointer) == PARAMETER_SEGMENTATION) {
2919 if (!sccp_reassemble) {
2920 proto_tree_add_item(sccp_tree, hf_sccp_segmented_data, tvb, variable_pointer3, tvb_get_guint8(tvb, variable_pointer3)+1, ENC_NA);
2921 } else {
2922 guint8 octet;
2923 gboolean more_frag = TRUE;
2924
2925 /* Get the first octet of parameter Segmentation, Ch 3.17 in Q.713
2926 * Bit 8 of octet 1 is used for First segment indication
2927 * Bit 7 of octet 1 is used to keep in the message in sequence
2928 * delivery option required by the SCCP user
2929 * Bits 6 and 5 in octet 1 are spare bits.
2930 * Bits 4-1 of octet 1 are used to indicate the number of
2931 * remaining segments.
2932 * The values 0000 to 1111 are possible; the value 0000 indicates
2933 * the last segment.
2934 */
2935 octet = tvb_get_guint8(tvb, optional_pointer+2);
2936 source_local_ref = tvb_get_letoh24(tvb, optional_pointer+3);
2937
2938 if ((octet & 0x0f) == 0)
2939 more_frag = FALSE;
2940
2941 new_tvb = sccp_reassemble_fragments(tvb, pinfo, tree, variable_pointer3, source_local_ref, more_frag);
2942
2943 if (new_tvb)
2944 dissect_sccp_data_param(new_tvb, pinfo, tree, sccp_info->assoc);
2945 }
2946 } else {
2947 dissect_sccp_variable_parameter(tvb, pinfo, sccp_tree, tree,
2948 PARAMETER_DATA, variable_pointer3, sccp_info);
2949 }
2950
2951 *optional_pointer_p = optional_pointer;
2952 *orig_opt_ptr_p = orig_opt_ptr;
2953 return offset;
2954 }
2955
2956 static int
dissect_sccp_message(tvbuff_t * tvb,packet_info * pinfo,proto_tree * sccp_tree,proto_tree * tree)2957 dissect_sccp_message(tvbuff_t *tvb, packet_info *pinfo, proto_tree *sccp_tree,
2958 proto_tree *tree)
2959 {
2960 guint16 variable_pointer1 = 0, variable_pointer2 = 0, variable_pointer3 = 0;
2961 guint16 optional_pointer = 0, orig_opt_ptr = 0;
2962 int offset = 0;
2963 tvbuff_t *new_tvb = NULL;
2964 guint32 source_local_ref = 0;
2965 guint8 more;
2966 guint msg_offset = tvb_offset_from_real_beginning(tvb);
2967 sccp_decode_context_t sccp_info = {0, INVALID_LR, INVALID_LR, NULL, NULL};
2968
2969 /* Extract the message type; all other processing is based on this */
2970 sccp_info.message_type = tvb_get_guint8(tvb, SCCP_MSG_TYPE_OFFSET);
2971 offset = SCCP_MSG_TYPE_LENGTH;
2972
2973 /* Do not change col_add_fstr() to col_append_fstr() here: we _want_
2974 * this call to overwrite whatever's currently in the INFO column (e.g.,
2975 * "DATA" from the SCTP dissector).
2976 *
2977 * If there's something there that should not be overwritten, whoever
2978 * put that info there should call col_set_fence() to protect it.
2979 */
2980 col_add_fstr(pinfo->cinfo, COL_INFO, "%s ",
2981 val_to_str(sccp_info.message_type, sccp_message_type_acro_values, "Unknown: %d"));
2982
2983 if (sccp_tree) {
2984 /* add the message type to the protocol tree */
2985 proto_tree_add_uint(sccp_tree, hf_sccp_message_type, tvb,
2986 SCCP_MSG_TYPE_OFFSET, SCCP_MSG_TYPE_LENGTH, sccp_info.message_type);
2987
2988 };
2989
2990 no_assoc.calling_dpc = 0;
2991 no_assoc.called_dpc = 0;
2992 no_assoc.calling_ssn = INVALID_SSN;
2993 no_assoc.called_ssn = INVALID_SSN;
2994 no_assoc.has_fw_key = FALSE;
2995 no_assoc.has_bw_key = FALSE;
2996 no_assoc.payload = SCCP_PLOAD_NONE;
2997 no_assoc.called_party = NULL;
2998 no_assoc.calling_party = NULL;
2999 no_assoc.extra_info = NULL;
3000
3001 switch (sccp_info.message_type) {
3002 case SCCP_MSG_TYPE_CR:
3003 /* TTC and NTT (Japan) say that the connection-oriented messages are
3004 * deleted (not standardized), but they appear to be used anyway, so
3005 * we'll dissect it...
3006 */
3007 offset += dissect_sccp_parameter(tvb, pinfo, sccp_tree, tree,
3008 PARAMETER_SOURCE_LOCAL_REFERENCE,
3009 offset, SOURCE_LOCAL_REFERENCE_LENGTH, &sccp_info);
3010 offset += dissect_sccp_parameter(tvb, pinfo, sccp_tree, tree,
3011 PARAMETER_CLASS, offset,
3012 PROTOCOL_CLASS_LENGTH, &sccp_info);
3013 sccp_info.assoc = get_sccp_assoc(pinfo, msg_offset, &sccp_info);
3014 build_assoc_tree(tvb, pinfo, sccp_tree, &sccp_info, msg_offset);
3015
3016 VARIABLE_POINTER(variable_pointer1, hf_sccp_variable_pointer1, POINTER_LENGTH);
3017 OPTIONAL_POINTER(POINTER_LENGTH);
3018
3019 dissect_sccp_variable_parameter(tvb, pinfo, sccp_tree, tree,
3020 PARAMETER_CALLED_PARTY_ADDRESS,
3021 variable_pointer1, &sccp_info);
3022 break;
3023
3024 case SCCP_MSG_TYPE_CC:
3025 /* TODO: connection has been established; theoretically we could keep
3026 * keep track of the SLR/DLR with the called/calling from the CR and
3027 * track the connection (e.g., on subsequent messages regarding this
3028 * SLR we could set the global vars "call*_ssn" so data could get
3029 * sub-dissected).
3030 */
3031 offset += dissect_sccp_parameter(tvb, pinfo, sccp_tree, tree,
3032 PARAMETER_DESTINATION_LOCAL_REFERENCE,
3033 offset,
3034 DESTINATION_LOCAL_REFERENCE_LENGTH, &sccp_info);
3035 offset += dissect_sccp_parameter(tvb, pinfo, sccp_tree, tree,
3036 PARAMETER_SOURCE_LOCAL_REFERENCE,
3037 offset, SOURCE_LOCAL_REFERENCE_LENGTH, &sccp_info);
3038
3039 sccp_info.assoc = get_sccp_assoc(pinfo, msg_offset, &sccp_info);
3040 build_assoc_tree(tvb, pinfo, sccp_tree, &sccp_info, msg_offset);
3041
3042 offset += dissect_sccp_parameter(tvb, pinfo, sccp_tree, tree,
3043 PARAMETER_CLASS, offset,
3044 PROTOCOL_CLASS_LENGTH, &sccp_info);
3045 OPTIONAL_POINTER(POINTER_LENGTH);
3046 break;
3047
3048 case SCCP_MSG_TYPE_CREF:
3049 offset += dissect_sccp_parameter(tvb, pinfo, sccp_tree, tree,
3050 PARAMETER_DESTINATION_LOCAL_REFERENCE,
3051 offset,
3052 DESTINATION_LOCAL_REFERENCE_LENGTH, &sccp_info);
3053
3054 sccp_info.assoc = get_sccp_assoc(pinfo, msg_offset, &sccp_info);
3055 build_assoc_tree(tvb, pinfo, sccp_tree, &sccp_info, msg_offset);
3056
3057 offset += dissect_sccp_parameter(tvb, pinfo, sccp_tree, tree,
3058 PARAMETER_REFUSAL_CAUSE, offset,
3059 REFUSAL_CAUSE_LENGTH, &sccp_info);
3060 OPTIONAL_POINTER(POINTER_LENGTH);
3061 break;
3062
3063 case SCCP_MSG_TYPE_RLSD:
3064 offset += dissect_sccp_parameter(tvb, pinfo, sccp_tree, tree,
3065 PARAMETER_DESTINATION_LOCAL_REFERENCE,
3066 offset,
3067 DESTINATION_LOCAL_REFERENCE_LENGTH, &sccp_info);
3068 offset += dissect_sccp_parameter(tvb, pinfo, sccp_tree, tree,
3069 PARAMETER_SOURCE_LOCAL_REFERENCE,
3070 offset, SOURCE_LOCAL_REFERENCE_LENGTH, &sccp_info);
3071
3072 sccp_info.assoc = get_sccp_assoc(pinfo, msg_offset, &sccp_info);
3073 build_assoc_tree(tvb, pinfo, sccp_tree, &sccp_info, msg_offset);
3074
3075 offset += dissect_sccp_parameter(tvb, pinfo, sccp_tree, tree,
3076 PARAMETER_RELEASE_CAUSE, offset,
3077 RELEASE_CAUSE_LENGTH, &sccp_info);
3078
3079 OPTIONAL_POINTER(POINTER_LENGTH);
3080 break;
3081
3082 case SCCP_MSG_TYPE_RLC:
3083 offset += dissect_sccp_parameter(tvb, pinfo, sccp_tree, tree,
3084 PARAMETER_DESTINATION_LOCAL_REFERENCE,
3085 offset,
3086 DESTINATION_LOCAL_REFERENCE_LENGTH, &sccp_info);
3087 offset += dissect_sccp_parameter(tvb, pinfo, sccp_tree, tree,
3088 PARAMETER_SOURCE_LOCAL_REFERENCE,
3089 offset, SOURCE_LOCAL_REFERENCE_LENGTH, &sccp_info);
3090
3091 sccp_info.assoc = get_sccp_assoc(pinfo, msg_offset, &sccp_info);
3092 build_assoc_tree(tvb, pinfo, sccp_tree, &sccp_info, msg_offset);
3093 break;
3094
3095 case SCCP_MSG_TYPE_DT1:
3096 {
3097 gint remaining_length;
3098 source_local_ref = tvb_get_letoh24(tvb, offset);
3099 offset += dissect_sccp_parameter(tvb, pinfo, sccp_tree, tree,
3100 PARAMETER_DESTINATION_LOCAL_REFERENCE,
3101 offset,
3102 DESTINATION_LOCAL_REFERENCE_LENGTH, &sccp_info);
3103
3104 sccp_info.assoc = get_sccp_assoc(pinfo, msg_offset, &sccp_info);
3105 build_assoc_tree(tvb, pinfo, sccp_tree, &sccp_info, msg_offset);
3106
3107 more = tvb_get_guint8(tvb, offset) & SEGMENTING_REASSEMBLING_MASK;
3108
3109 offset += dissect_sccp_parameter(tvb, pinfo, sccp_tree, tree,
3110 PARAMETER_SEGMENTING_REASSEMBLING,
3111 offset, SEGMENTING_REASSEMBLING_LENGTH, &sccp_info);
3112 VARIABLE_POINTER(variable_pointer1, hf_sccp_variable_pointer1, POINTER_LENGTH);
3113
3114 /* Reassemble */
3115 if (!sccp_reassemble) {
3116 proto_tree_add_item(sccp_tree, hf_sccp_segmented_data, tvb, variable_pointer1,
3117 tvb_get_guint8(tvb, variable_pointer1)+1, ENC_NA);
3118 dissect_sccp_variable_parameter(tvb, pinfo, sccp_tree, tree,
3119 PARAMETER_DATA, variable_pointer1, &sccp_info);
3120
3121 } else {
3122 remaining_length = tvb_reported_length_remaining(tvb, variable_pointer1 + 1);
3123 if(dt1_ignore_length && remaining_length > 255) {
3124 new_tvb = tvb_new_subset_length(tvb, variable_pointer1 + 1, remaining_length);
3125 } else {
3126 new_tvb = sccp_reassemble_fragments(tvb, pinfo, tree, variable_pointer1, source_local_ref, more);
3127 }
3128
3129 if (new_tvb)
3130 dissect_sccp_data_param(new_tvb, pinfo, tree, sccp_info.assoc);
3131 }
3132
3133 /* End reassemble */
3134 break;
3135 }
3136
3137 case SCCP_MSG_TYPE_DT2:
3138 offset += dissect_sccp_parameter(tvb, pinfo, sccp_tree, tree,
3139 PARAMETER_DESTINATION_LOCAL_REFERENCE,
3140 offset,
3141 DESTINATION_LOCAL_REFERENCE_LENGTH, &sccp_info);
3142
3143 sccp_info.assoc = get_sccp_assoc(pinfo, msg_offset, &sccp_info);
3144 build_assoc_tree(tvb, pinfo, sccp_tree, &sccp_info, msg_offset);
3145
3146 offset += dissect_sccp_parameter(tvb, pinfo, sccp_tree, tree,
3147 PARAMETER_SEQUENCING_SEGMENTING, offset,
3148 SEQUENCING_SEGMENTING_LENGTH, &sccp_info);
3149 break;
3150
3151 case SCCP_MSG_TYPE_AK:
3152 offset += dissect_sccp_parameter(tvb, pinfo, sccp_tree, tree,
3153 PARAMETER_DESTINATION_LOCAL_REFERENCE,
3154 offset,
3155 DESTINATION_LOCAL_REFERENCE_LENGTH, &sccp_info);
3156
3157 sccp_info.assoc = get_sccp_assoc(pinfo, msg_offset, &sccp_info);
3158 build_assoc_tree(tvb, pinfo, sccp_tree, &sccp_info, msg_offset);
3159
3160 offset += dissect_sccp_parameter(tvb, pinfo, sccp_tree, tree,
3161 PARAMETER_RECEIVE_SEQUENCE_NUMBER,
3162 offset, RECEIVE_SEQUENCE_NUMBER_LENGTH, &sccp_info);
3163 offset += dissect_sccp_parameter(tvb, pinfo, sccp_tree, tree,
3164 PARAMETER_CREDIT, offset, CREDIT_LENGTH, &sccp_info);
3165 break;
3166
3167 case SCCP_MSG_TYPE_UDT:
3168 sccp_info.sccp_msg = new_ud_msg(pinfo, sccp_info.message_type);
3169
3170 offset += dissect_sccp_parameter(tvb, pinfo, sccp_tree, tree,
3171 PARAMETER_CLASS, offset,
3172 PROTOCOL_CLASS_LENGTH, &sccp_info);
3173 VARIABLE_POINTER(variable_pointer1, hf_sccp_variable_pointer1, POINTER_LENGTH);
3174 VARIABLE_POINTER(variable_pointer2, hf_sccp_variable_pointer2, POINTER_LENGTH);
3175 VARIABLE_POINTER(variable_pointer3, hf_sccp_variable_pointer3, POINTER_LENGTH);
3176
3177 sccp_info.assoc = get_sccp_assoc(pinfo, msg_offset, &sccp_info);
3178 build_assoc_tree(tvb, pinfo, sccp_tree, &sccp_info, msg_offset);
3179
3180 dissect_sccp_variable_parameter(tvb, pinfo, sccp_tree, tree,
3181 PARAMETER_CALLED_PARTY_ADDRESS,
3182 variable_pointer1, &sccp_info);
3183 dissect_sccp_variable_parameter(tvb, pinfo, sccp_tree, tree,
3184 PARAMETER_CALLING_PARTY_ADDRESS,
3185 variable_pointer2, &sccp_info);
3186
3187 dissect_sccp_variable_parameter(tvb, pinfo, sccp_tree, tree, PARAMETER_DATA,
3188 variable_pointer3, &sccp_info);
3189 break;
3190
3191 case SCCP_MSG_TYPE_UDTS:
3192 {
3193 gboolean save_in_error_pkt = pinfo->flags.in_error_pkt;
3194 pinfo->flags.in_error_pkt = TRUE;
3195
3196 sccp_info.sccp_msg = new_ud_msg(pinfo, sccp_info.message_type);
3197
3198 offset += dissect_sccp_parameter(tvb, pinfo, sccp_tree, tree,
3199 PARAMETER_RETURN_CAUSE, offset,
3200 RETURN_CAUSE_LENGTH, &sccp_info);
3201
3202 VARIABLE_POINTER(variable_pointer1, hf_sccp_variable_pointer1, POINTER_LENGTH);
3203 VARIABLE_POINTER(variable_pointer2, hf_sccp_variable_pointer2, POINTER_LENGTH);
3204 VARIABLE_POINTER(variable_pointer3, hf_sccp_variable_pointer3, POINTER_LENGTH);
3205
3206 sccp_info.assoc = get_sccp_assoc(pinfo, msg_offset, &sccp_info);
3207 build_assoc_tree(tvb, pinfo, sccp_tree, &sccp_info, msg_offset);
3208
3209 dissect_sccp_variable_parameter(tvb, pinfo, sccp_tree, tree,
3210 PARAMETER_CALLED_PARTY_ADDRESS,
3211 variable_pointer1, &sccp_info);
3212
3213 dissect_sccp_variable_parameter(tvb, pinfo, sccp_tree, tree,
3214 PARAMETER_CALLING_PARTY_ADDRESS,
3215 variable_pointer2, &sccp_info);
3216
3217 dissect_sccp_variable_parameter(tvb, pinfo, sccp_tree, tree, PARAMETER_DATA,
3218 variable_pointer3, &sccp_info);
3219 pinfo->flags.in_error_pkt = save_in_error_pkt;
3220 break;
3221 }
3222
3223 case SCCP_MSG_TYPE_ED:
3224 offset += dissect_sccp_parameter(tvb, pinfo, sccp_tree, tree,
3225 PARAMETER_DESTINATION_LOCAL_REFERENCE,
3226 offset,
3227 DESTINATION_LOCAL_REFERENCE_LENGTH, &sccp_info);
3228
3229 sccp_info.assoc = get_sccp_assoc(pinfo, msg_offset, &sccp_info);
3230 build_assoc_tree(tvb, pinfo, sccp_tree, &sccp_info, msg_offset);
3231
3232 VARIABLE_POINTER(variable_pointer1, hf_sccp_variable_pointer1, POINTER_LENGTH);
3233
3234 dissect_sccp_variable_parameter(tvb, pinfo, sccp_tree, tree, PARAMETER_DATA,
3235 variable_pointer1, &sccp_info);
3236 break;
3237
3238 case SCCP_MSG_TYPE_EA:
3239 offset += dissect_sccp_parameter(tvb, pinfo, sccp_tree, tree,
3240 PARAMETER_DESTINATION_LOCAL_REFERENCE,
3241 offset,
3242 DESTINATION_LOCAL_REFERENCE_LENGTH, &sccp_info);
3243 sccp_info.assoc = get_sccp_assoc(pinfo, msg_offset, &sccp_info);
3244 build_assoc_tree(tvb, pinfo, sccp_tree, &sccp_info, msg_offset);
3245 break;
3246
3247 case SCCP_MSG_TYPE_RSR:
3248 offset += dissect_sccp_parameter(tvb, pinfo, sccp_tree, tree,
3249 PARAMETER_DESTINATION_LOCAL_REFERENCE,
3250 offset,
3251 DESTINATION_LOCAL_REFERENCE_LENGTH, &sccp_info);
3252 offset += dissect_sccp_parameter(tvb, pinfo, sccp_tree, tree,
3253 PARAMETER_SOURCE_LOCAL_REFERENCE,
3254 offset, SOURCE_LOCAL_REFERENCE_LENGTH, &sccp_info);
3255 offset += dissect_sccp_parameter(tvb, pinfo, sccp_tree, tree,
3256 PARAMETER_RESET_CAUSE, offset,
3257 RESET_CAUSE_LENGTH, &sccp_info);
3258 sccp_info.assoc = get_sccp_assoc(pinfo, msg_offset, &sccp_info);
3259 build_assoc_tree(tvb, pinfo, sccp_tree, &sccp_info, msg_offset);
3260 break;
3261
3262 case SCCP_MSG_TYPE_RSC:
3263 offset += dissect_sccp_parameter(tvb, pinfo, sccp_tree, tree,
3264 PARAMETER_DESTINATION_LOCAL_REFERENCE,
3265 offset,
3266 DESTINATION_LOCAL_REFERENCE_LENGTH, &sccp_info);
3267 offset += dissect_sccp_parameter(tvb, pinfo, sccp_tree, tree,
3268 PARAMETER_SOURCE_LOCAL_REFERENCE,
3269 offset, SOURCE_LOCAL_REFERENCE_LENGTH, &sccp_info);
3270 sccp_info.assoc = get_sccp_assoc(pinfo, msg_offset, &sccp_info);
3271 build_assoc_tree(tvb, pinfo, sccp_tree, &sccp_info, msg_offset);
3272 break;
3273
3274 case SCCP_MSG_TYPE_ERR:
3275 offset += dissect_sccp_parameter(tvb, pinfo, sccp_tree, tree,
3276 PARAMETER_DESTINATION_LOCAL_REFERENCE,
3277 offset,
3278 DESTINATION_LOCAL_REFERENCE_LENGTH, &sccp_info);
3279 offset += dissect_sccp_parameter(tvb, pinfo, sccp_tree, tree,
3280 PARAMETER_ERROR_CAUSE, offset,
3281 ERROR_CAUSE_LENGTH, &sccp_info);
3282 sccp_info.assoc = get_sccp_assoc(pinfo, msg_offset, &sccp_info);
3283 build_assoc_tree(tvb, pinfo, sccp_tree, &sccp_info, msg_offset);
3284 break;
3285
3286 case SCCP_MSG_TYPE_IT:
3287 offset += dissect_sccp_parameter(tvb, pinfo, sccp_tree, tree,
3288 PARAMETER_DESTINATION_LOCAL_REFERENCE,
3289 offset,
3290 DESTINATION_LOCAL_REFERENCE_LENGTH, &sccp_info);
3291 offset += dissect_sccp_parameter(tvb, pinfo, sccp_tree, tree,
3292 PARAMETER_SOURCE_LOCAL_REFERENCE,
3293 offset, SOURCE_LOCAL_REFERENCE_LENGTH, &sccp_info);
3294 sccp_info.assoc = get_sccp_assoc(pinfo, msg_offset, &sccp_info);
3295 build_assoc_tree(tvb, pinfo, sccp_tree, &sccp_info, msg_offset);
3296 offset += dissect_sccp_parameter(tvb, pinfo, sccp_tree, tree,
3297 PARAMETER_CLASS, offset,
3298 PROTOCOL_CLASS_LENGTH, &sccp_info);
3299 offset += dissect_sccp_parameter(tvb, pinfo, sccp_tree, tree,
3300 PARAMETER_SEQUENCING_SEGMENTING,
3301 offset, SEQUENCING_SEGMENTING_LENGTH, &sccp_info);
3302 offset += dissect_sccp_parameter(tvb, pinfo, sccp_tree, tree,
3303 PARAMETER_CREDIT, offset, CREDIT_LENGTH, &sccp_info);
3304 break;
3305
3306 case SCCP_MSG_TYPE_XUDT:
3307 sccp_info.sccp_msg = new_ud_msg(pinfo, sccp_info.message_type);
3308 offset += dissect_sccp_parameter(tvb, pinfo, sccp_tree, tree,
3309 PARAMETER_CLASS, offset,
3310 PROTOCOL_CLASS_LENGTH, &sccp_info);
3311 offset += dissect_sccp_parameter(tvb, pinfo, sccp_tree, tree,
3312 PARAMETER_HOP_COUNTER, offset,
3313 HOP_COUNTER_LENGTH, &sccp_info);
3314
3315 offset = dissect_xudt_common(tvb, pinfo, sccp_tree, tree, offset, &sccp_info,
3316 &optional_pointer, &orig_opt_ptr);
3317 break;
3318
3319 case SCCP_MSG_TYPE_XUDTS:
3320 {
3321 gboolean save_in_error_pkt = pinfo->flags.in_error_pkt;
3322 pinfo->flags.in_error_pkt = TRUE;
3323
3324 sccp_info.sccp_msg = new_ud_msg(pinfo, sccp_info.message_type);
3325 offset += dissect_sccp_parameter(tvb, pinfo, sccp_tree, tree,
3326 PARAMETER_RETURN_CAUSE, offset,
3327 RETURN_CAUSE_LENGTH, &sccp_info);
3328 offset += dissect_sccp_parameter(tvb, pinfo, sccp_tree, tree,
3329 PARAMETER_HOP_COUNTER, offset,
3330 HOP_COUNTER_LENGTH, &sccp_info);
3331
3332 offset = dissect_xudt_common(tvb, pinfo, sccp_tree, tree, offset, &sccp_info,
3333 &optional_pointer, &orig_opt_ptr);
3334
3335 pinfo->flags.in_error_pkt = save_in_error_pkt;
3336 break;
3337 }
3338 case SCCP_MSG_TYPE_LUDT:
3339 sccp_info.sccp_msg = new_ud_msg(pinfo, sccp_info.message_type);
3340
3341 offset += dissect_sccp_parameter(tvb, pinfo, sccp_tree, tree,
3342 PARAMETER_CLASS, offset,
3343 PROTOCOL_CLASS_LENGTH, &sccp_info);
3344 offset += dissect_sccp_parameter(tvb, pinfo, sccp_tree, tree,
3345 PARAMETER_HOP_COUNTER, offset,
3346 HOP_COUNTER_LENGTH, &sccp_info);
3347
3348 VARIABLE_POINTER(variable_pointer1, hf_sccp_variable_pointer1, POINTER_LENGTH_LONG);
3349 VARIABLE_POINTER(variable_pointer2, hf_sccp_variable_pointer2, POINTER_LENGTH_LONG);
3350 VARIABLE_POINTER(variable_pointer3, hf_sccp_variable_pointer3, POINTER_LENGTH_LONG);
3351 OPTIONAL_POINTER(POINTER_LENGTH_LONG);
3352
3353 sccp_info.assoc = get_sccp_assoc(pinfo, msg_offset, &sccp_info);
3354 build_assoc_tree(tvb, pinfo, sccp_tree, &sccp_info, msg_offset);
3355
3356 dissect_sccp_variable_parameter(tvb, pinfo, sccp_tree, tree,
3357 PARAMETER_CALLED_PARTY_ADDRESS,
3358 variable_pointer1, &sccp_info);
3359 dissect_sccp_variable_parameter(tvb, pinfo, sccp_tree, tree,
3360 PARAMETER_CALLING_PARTY_ADDRESS,
3361 variable_pointer2, &sccp_info);
3362 dissect_sccp_variable_parameter(tvb, pinfo, sccp_tree, tree,
3363 PARAMETER_LONG_DATA, variable_pointer3, &sccp_info);
3364 break;
3365
3366 case SCCP_MSG_TYPE_LUDTS:
3367 sccp_info.sccp_msg = new_ud_msg(pinfo, sccp_info.message_type);
3368 offset += dissect_sccp_parameter(tvb, pinfo, sccp_tree, tree,
3369 PARAMETER_RETURN_CAUSE, offset,
3370 RETURN_CAUSE_LENGTH, &sccp_info);
3371 offset += dissect_sccp_parameter(tvb, pinfo, sccp_tree, tree,
3372 PARAMETER_HOP_COUNTER, offset,
3373 HOP_COUNTER_LENGTH, &sccp_info);
3374
3375 VARIABLE_POINTER(variable_pointer1, hf_sccp_variable_pointer1, POINTER_LENGTH_LONG);
3376 VARIABLE_POINTER(variable_pointer2, hf_sccp_variable_pointer2, POINTER_LENGTH_LONG);
3377 VARIABLE_POINTER(variable_pointer3, hf_sccp_variable_pointer3, POINTER_LENGTH_LONG);
3378 OPTIONAL_POINTER(POINTER_LENGTH_LONG);
3379
3380 sccp_info.assoc = get_sccp_assoc(pinfo, msg_offset, &sccp_info);
3381 build_assoc_tree(tvb, pinfo, sccp_tree, &sccp_info, msg_offset);
3382
3383 dissect_sccp_variable_parameter(tvb, pinfo, sccp_tree, tree,
3384 PARAMETER_CALLED_PARTY_ADDRESS,
3385 variable_pointer1, &sccp_info);
3386 dissect_sccp_variable_parameter(tvb, pinfo, sccp_tree, tree,
3387 PARAMETER_CALLING_PARTY_ADDRESS,
3388 variable_pointer2, &sccp_info);
3389 dissect_sccp_variable_parameter(tvb, pinfo, sccp_tree, tree,
3390 PARAMETER_LONG_DATA, variable_pointer3, &sccp_info);
3391 break;
3392
3393 default:
3394 dissect_sccp_unknown_message(tvb, sccp_tree);
3395 }
3396
3397 if (orig_opt_ptr)
3398 dissect_sccp_optional_parameters(tvb, pinfo, sccp_tree, tree,
3399 optional_pointer, &sccp_info);
3400
3401 return offset;
3402 }
3403
3404 static int
dissect_sccp(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,void * data _U_)3405 dissect_sccp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_)
3406 {
3407 proto_item *sccp_item = NULL;
3408 proto_tree *sccp_tree = NULL;
3409 const mtp3_addr_pc_t *mtp3_addr_p;
3410
3411 if ((pinfo->src.type == ss7pc_address_type) &&
3412 ((mtp3_addr_p = (const mtp3_addr_pc_t *)pinfo->src.data)->type <= CHINESE_ITU_STANDARD)) {
3413 /*
3414 * Allow a protocol beneath to specify how the SCCP layer should be
3415 * dissected.
3416 *
3417 * It is possible to have multiple sets of SCCP traffic some of which is
3418 * ITU and some of which is ANSI.
3419 * An example is A-interface traffic having ANSI MTP3/ANSI SCCP/3GPP2 IOS
3420 * and at the same time ITU MTP3/ITU SCCP/ANSI TCAP/ANSI MAP.
3421 */
3422 decode_mtp3_standard = mtp3_addr_p->type;
3423 } else {
3424 decode_mtp3_standard = (Standard_Type)mtp3_standard;
3425 }
3426
3427 /* Make entry in the Protocol column on summary display */
3428 switch (decode_mtp3_standard) {
3429 case ITU_STANDARD:
3430 col_set_str(pinfo->cinfo, COL_PROTOCOL, "SCCP (Int. ITU)");
3431 break;
3432 case ANSI_STANDARD:
3433 col_set_str(pinfo->cinfo, COL_PROTOCOL, "SCCP (ANSI)");
3434 break;
3435 case CHINESE_ITU_STANDARD:
3436 col_set_str(pinfo->cinfo, COL_PROTOCOL, "SCCP (Chin. ITU)");
3437 break;
3438 case JAPAN_STANDARD:
3439 col_set_str(pinfo->cinfo, COL_PROTOCOL, "SCCP (Japan)");
3440 break;
3441 };
3442
3443 /* In the interest of speed, if "tree" is NULL, don't do any work not
3444 necessary to generate protocol tree items. */
3445 if (tree) {
3446 /* create the sccp protocol tree */
3447 sccp_item = proto_tree_add_item(tree, proto_sccp, tvb, 0, -1, ENC_NA);
3448 sccp_tree = proto_item_add_subtree(sccp_item, ett_sccp);
3449 }
3450
3451 /* Set whether message is UPLINK, DOWNLINK, or of UNKNOWN direction */
3452
3453 if (pinfo->src.type == ss7pc_address_type) {
3454 /*
3455 * XXX - we assume that the "data" pointers of the source and destination
3456 * addresses are set to point to "mtp3_addr_pc_t" structures, so that
3457 * we can safely cast them.
3458 */
3459 mtp3_addr_p = (const mtp3_addr_pc_t *)pinfo->src.data;
3460
3461 if (sccp_source_pc_global == mtp3_addr_p->pc) {
3462 pinfo->p2p_dir = P2P_DIR_SENT;
3463 } else {
3464 /* assuming if src was SS7 PC then dst will be too */
3465 mtp3_addr_p = (const mtp3_addr_pc_t *)pinfo->dst.data;
3466
3467 if (sccp_source_pc_global == mtp3_addr_p->pc)
3468 {
3469 pinfo->p2p_dir = P2P_DIR_RECV;
3470 } else {
3471 pinfo->p2p_dir = P2P_DIR_UNKNOWN;
3472 }
3473 }
3474 }
3475
3476 /* dissect the message */
3477 dissect_sccp_message(tvb, pinfo, sccp_tree, tree);
3478 return tvb_captured_length(tvb);
3479 }
3480
3481 /*** SccpUsers Table **/
3482
3483 static struct _sccp_ul {
3484 guint id;
3485 gboolean uses_tcap;
3486 dissector_handle_t *handlep;
3487 } user_list[] = {
3488
3489 {SCCP_USER_DATA, FALSE, &data_handle},
3490 {SCCP_USER_TCAP, FALSE, &tcap_handle},
3491 {SCCP_USER_RANAP, FALSE, &ranap_handle},
3492 {SCCP_USER_BSSAP, FALSE, &bssap_handle},
3493 {SCCP_USER_GSMMAP, TRUE, &gsmmap_handle},
3494 {SCCP_USER_CAMEL, TRUE, &camel_handle},
3495 {SCCP_USER_INAP, TRUE, &inap_handle},
3496 {0, FALSE, NULL}
3497 };
3498
3499 static gboolean
sccp_users_update_cb(void * r,char ** err)3500 sccp_users_update_cb(void *r, char **err)
3501 {
3502 sccp_user_t *u = (sccp_user_t *)r;
3503 struct _sccp_ul *c;
3504 range_t *empty;
3505
3506 empty = range_empty(NULL);
3507 if (ranges_are_equal(u->called_pc, empty)) {
3508 *err = g_strdup("Must specify a PC");
3509 wmem_free(NULL, empty);
3510 return FALSE;
3511 }
3512
3513 if (ranges_are_equal(u->called_ssn, empty)) {
3514 *err = g_strdup("Must specify an SSN");
3515 wmem_free(NULL, empty);
3516 return FALSE;
3517 }
3518
3519 wmem_free(NULL, empty);
3520 for (c=user_list; c->handlep; c++) {
3521 if (c->id == u->user) {
3522 u->uses_tcap = c->uses_tcap;
3523 u->handlep = c->handlep;
3524 return TRUE;
3525 }
3526 }
3527
3528 u->uses_tcap = FALSE;
3529 u->handlep = &data_handle;
3530 return TRUE;
3531 }
3532
3533 static void *
sccp_users_copy_cb(void * n,const void * o,size_t siz _U_)3534 sccp_users_copy_cb(void *n, const void *o, size_t siz _U_)
3535 {
3536 const sccp_user_t *u = (const sccp_user_t *)o;
3537 sccp_user_t *un = (sccp_user_t *)n;
3538
3539 un->ni = u->ni;
3540 un->user = u->user;
3541 un->uses_tcap = u->uses_tcap;
3542 un->handlep = u->handlep;
3543
3544 if (u->called_pc)
3545 un->called_pc = range_copy(NULL, u->called_pc);
3546 if (u->called_ssn)
3547 un->called_ssn = range_copy(NULL, u->called_ssn);
3548
3549 return n;
3550 }
3551
3552 static void
sccp_users_free_cb(void * r)3553 sccp_users_free_cb(void *r)
3554 {
3555 sccp_user_t *u = (sccp_user_t *)r;
3556 if (u->called_pc) wmem_free(NULL, u->called_pc);
3557 if (u->called_ssn) wmem_free(NULL, u->called_ssn);
3558 }
3559
3560
UAT_DEC_CB_DEF(sccp_users,ni,sccp_user_t)3561 UAT_DEC_CB_DEF(sccp_users, ni, sccp_user_t)
3562 UAT_RANGE_CB_DEF(sccp_users, called_pc, sccp_user_t)
3563 UAT_RANGE_CB_DEF(sccp_users, called_ssn, sccp_user_t)
3564 UAT_VS_DEF(sccp_users, user, sccp_user_t, guint, SCCP_USER_DATA, "Data")
3565
3566 /** End SccpUsersTable **/
3567
3568
3569 static void
3570 init_sccp(void)
3571 {
3572 next_assoc_id = 1;
3573 sccp_reassembly_id_next = 1;
3574 }
3575
3576 /* Register the protocol with Wireshark */
3577 void
proto_register_sccp(void)3578 proto_register_sccp(void)
3579 {
3580 /* Setup list of header fields */
3581 static hf_register_info hf[] = {
3582 { &hf_sccp_message_type,
3583 { "Message Type", "sccp.message_type",
3584 FT_UINT8, BASE_HEX, VALS(sccp_message_type_values), 0x0,
3585 NULL, HFILL}
3586 },
3587 { &hf_sccp_variable_pointer1,
3588 { "Pointer to first Mandatory Variable parameter", "sccp.variable_pointer1",
3589 FT_UINT16, BASE_DEC, NULL, 0x0,
3590 NULL, HFILL}
3591 },
3592 { &hf_sccp_variable_pointer2,
3593 { "Pointer to second Mandatory Variable parameter", "sccp.variable_pointer2",
3594 FT_UINT16, BASE_DEC, NULL, 0x0,
3595 NULL, HFILL}
3596 },
3597 { &hf_sccp_variable_pointer3,
3598 { "Pointer to third Mandatory Variable parameter", "sccp.variable_pointer3",
3599 FT_UINT16, BASE_DEC, NULL, 0x0,
3600 NULL, HFILL}
3601 },
3602 { &hf_sccp_optional_pointer,
3603 { "Pointer to Optional parameter", "sccp.optional_pointer",
3604 FT_UINT16, BASE_DEC, NULL, 0x0,
3605 NULL, HFILL}
3606 },
3607 { &hf_sccp_param_length,
3608 { "Variable parameter length", "sccp.parameter_length",
3609 FT_UINT16, BASE_DEC, NULL, 0x0,
3610 NULL, HFILL}
3611 },
3612 { &hf_sccp_ssn,
3613 { "Called or Calling SubSystem Number", "sccp.ssn",
3614 FT_UINT8, BASE_DEC, VALS(sccp_ssn_values), 0x0,
3615 NULL, HFILL}
3616 },
3617 { &hf_sccp_gt_digits,
3618 { "Called or Calling GT Digits", "sccp.digits",
3619 FT_STRING, BASE_NONE, NULL, 0x0,
3620 NULL, HFILL }
3621 },
3622 { &hf_sccp_called_ansi_national_indicator,
3623 { "National Indicator", "sccp.called.ni",
3624 FT_UINT8, BASE_HEX, VALS(sccp_ansi_national_indicator_values), ANSI_NATIONAL_MASK,
3625 NULL, HFILL}
3626 },
3627 { &hf_sccp_called_itu_natl_use_bit,
3628 { "Reserved for national use", "sccp.called.reserved",
3629 FT_UINT8, BASE_HEX, NULL, ITU_RESERVED_MASK,
3630 NULL, HFILL}
3631 },
3632 { &hf_sccp_called_routing_indicator,
3633 { "Routing Indicator", "sccp.called.ri",
3634 FT_UINT8, BASE_HEX, VALS(sccp_routing_indicator_values), ROUTING_INDICATOR_MASK,
3635 NULL, HFILL}
3636 },
3637 { &hf_sccp_called_itu_global_title_indicator,
3638 { "Global Title Indicator", "sccp.called.gti",
3639 FT_UINT8, BASE_HEX, VALS(sccp_itu_global_title_indicator_values), GTI_MASK,
3640 NULL, HFILL}
3641 },
3642 { &hf_sccp_called_ansi_global_title_indicator,
3643 { "Global Title Indicator", "sccp.called.gti",
3644 FT_UINT8, BASE_HEX, VALS(sccp_ansi_global_title_indicator_values), GTI_MASK,
3645 NULL, HFILL}
3646 },
3647 { &hf_sccp_called_itu_ssn_indicator,
3648 { "SubSystem Number Indicator", "sccp.called.ssni",
3649 FT_UINT8, BASE_HEX, VALS(sccp_ai_ssni_values), ITU_SSN_INDICATOR_MASK,
3650 NULL, HFILL}
3651 },
3652 { &hf_sccp_called_itu_point_code_indicator,
3653 { "Point Code Indicator", "sccp.called.pci",
3654 FT_UINT8, BASE_HEX, VALS(sccp_ai_pci_values), ITU_PC_INDICATOR_MASK,
3655 NULL, HFILL}
3656 },
3657 { &hf_sccp_called_ansi_ssn_indicator,
3658 { "SubSystem Number Indicator", "sccp.called.ssni",
3659 FT_UINT8, BASE_HEX, VALS(sccp_ai_ssni_values), ANSI_SSN_INDICATOR_MASK,
3660 NULL, HFILL}
3661 },
3662 { &hf_sccp_called_ansi_point_code_indicator,
3663 { "Point Code Indicator", "sccp.called.pci",
3664 FT_UINT8, BASE_HEX, VALS(sccp_ai_pci_values), ANSI_PC_INDICATOR_MASK,
3665 NULL, HFILL}
3666 },
3667 { &hf_sccp_called_ssn,
3668 { "SubSystem Number", "sccp.called.ssn",
3669 FT_UINT8, BASE_DEC, VALS(sccp_ssn_values), 0x0,
3670 NULL, HFILL}
3671 },
3672 { &hf_sccp_called_itu_pc,
3673 { "PC", "sccp.called.pc",
3674 FT_UINT16, BASE_DEC, NULL, ITU_PC_MASK,
3675 NULL, HFILL}
3676 },
3677 { &hf_sccp_called_ansi_pc,
3678 { "PC", "sccp.called.ansi_pc",
3679 FT_STRING, BASE_NONE, NULL, 0x0,
3680 NULL, HFILL}
3681 },
3682 { &hf_sccp_called_chinese_pc,
3683 { "PC", "sccp.called.chinese_pc",
3684 FT_STRING, BASE_NONE, NULL, 0x0,
3685 NULL, HFILL}
3686 },
3687 { &hf_sccp_called_japan_pc,
3688 { "PC", "sccp.called.pc",
3689 FT_UINT16, BASE_DEC, NULL, 0x0,
3690 NULL, HFILL}
3691 },
3692 { &hf_sccp_called_pc_network,
3693 { "PC Network", "sccp.called.network",
3694 FT_UINT24, BASE_DEC, NULL, ANSI_NETWORK_MASK,
3695 NULL, HFILL }
3696 },
3697 { &hf_sccp_called_pc_cluster,
3698 { "PC Cluster", "sccp.called.cluster",
3699 FT_UINT24, BASE_DEC, NULL, ANSI_CLUSTER_MASK,
3700 NULL, HFILL }
3701 },
3702 { &hf_sccp_called_pc_member,
3703 { "PC Member", "sccp.called.member",
3704 FT_UINT24, BASE_DEC, NULL, ANSI_MEMBER_MASK,
3705 NULL, HFILL }
3706 },
3707 { &hf_sccp_called_gt_nai,
3708 { "Nature of Address Indicator", "sccp.called.nai",
3709 FT_UINT8, BASE_HEX, VALS(sccp_nai_values), GT_NAI_MASK,
3710 NULL, HFILL }
3711 },
3712 { &hf_sccp_called_gt_oe,
3713 { "Odd/Even Indicator", "sccp.called.oe",
3714 FT_UINT8, BASE_HEX, VALS(sccp_oe_values), GT_OE_MASK,
3715 NULL, HFILL }
3716 },
3717 { &hf_sccp_called_gt_tt,
3718 { "Translation Type", "sccp.called.tt",
3719 FT_UINT8, BASE_HEX_DEC, NULL, 0x0,
3720 NULL, HFILL }
3721 },
3722 { &hf_sccp_called_gt_np,
3723 { "Numbering Plan", "sccp.called.np",
3724 FT_UINT8, BASE_HEX, VALS(sccp_np_values), GT_NP_MASK,
3725 NULL, HFILL }
3726 },
3727 { &hf_sccp_called_gt_es,
3728 { "Encoding Scheme", "sccp.called.es",
3729 FT_UINT8, BASE_HEX, VALS(sccp_es_values), GT_ES_MASK,
3730 NULL, HFILL }
3731 },
3732 { &hf_sccp_called_gt_digits,
3733 { "Called Party Digits", "sccp.called.digits",
3734 FT_STRING, BASE_NONE, NULL, 0x0,
3735 NULL, HFILL }
3736 },
3737 { &hf_sccp_called_gt_digits_length,
3738 { "Number of Called Party Digits", "sccp.called.digits.length",
3739 FT_UINT8, BASE_DEC, NULL, 0x0,
3740 NULL, HFILL }
3741 },
3742 { &hf_sccp_calling_ansi_national_indicator,
3743 { "National Indicator", "sccp.calling.ni",
3744 FT_UINT8, BASE_HEX, VALS(sccp_ansi_national_indicator_values), ANSI_NATIONAL_MASK,
3745 NULL, HFILL}
3746 },
3747 { &hf_sccp_calling_itu_natl_use_bit,
3748 { "Reserved for national use", "sccp.calling.reserved",
3749 FT_UINT8, BASE_HEX, NULL, ITU_RESERVED_MASK,
3750 NULL, HFILL}
3751 },
3752 { &hf_sccp_calling_routing_indicator,
3753 { "Routing Indicator", "sccp.calling.ri",
3754 FT_UINT8, BASE_HEX, VALS(sccp_routing_indicator_values), ROUTING_INDICATOR_MASK,
3755 NULL, HFILL}
3756 },
3757 { &hf_sccp_calling_itu_global_title_indicator,
3758 { "Global Title Indicator", "sccp.calling.gti",
3759 FT_UINT8, BASE_HEX, VALS(sccp_itu_global_title_indicator_values), GTI_MASK,
3760 NULL, HFILL}
3761 },
3762 { &hf_sccp_calling_ansi_global_title_indicator,
3763 { "Global Title Indicator", "sccp.calling.gti",
3764 FT_UINT8, BASE_HEX, VALS(sccp_ansi_global_title_indicator_values), GTI_MASK,
3765 NULL, HFILL}
3766 },
3767 { &hf_sccp_calling_itu_ssn_indicator,
3768 { "SubSystem Number Indicator", "sccp.calling.ssni",
3769 FT_UINT8, BASE_HEX, VALS(sccp_ai_ssni_values), ITU_SSN_INDICATOR_MASK,
3770 NULL, HFILL}
3771 },
3772 { &hf_sccp_calling_itu_point_code_indicator,
3773 { "Point Code Indicator", "sccp.calling.pci",
3774 FT_UINT8, BASE_HEX, VALS(sccp_ai_pci_values), ITU_PC_INDICATOR_MASK,
3775 NULL, HFILL}
3776 },
3777 { &hf_sccp_calling_ansi_ssn_indicator,
3778 { "SubSystem Number Indicator", "sccp.calling.ssni",
3779 FT_UINT8, BASE_HEX, VALS(sccp_ai_ssni_values), ANSI_SSN_INDICATOR_MASK,
3780 NULL, HFILL}
3781 },
3782 { &hf_sccp_calling_ansi_point_code_indicator,
3783 { "Point Code Indicator", "sccp.calling.pci",
3784 FT_UINT8, BASE_HEX, VALS(sccp_ai_pci_values), ANSI_PC_INDICATOR_MASK,
3785 NULL, HFILL}
3786 },
3787 { &hf_sccp_calling_ssn,
3788 { "SubSystem Number", "sccp.calling.ssn",
3789 FT_UINT8, BASE_DEC, VALS(sccp_ssn_values), 0x0,
3790 NULL, HFILL}
3791 },
3792 { &hf_sccp_calling_itu_pc,
3793 { "PC", "sccp.calling.pc",
3794 FT_UINT16, BASE_DEC, NULL, ITU_PC_MASK,
3795 NULL, HFILL}
3796 },
3797 { &hf_sccp_calling_ansi_pc,
3798 { "PC", "sccp.calling.ansi_pc",
3799 FT_STRING, BASE_NONE, NULL, 0x0,
3800 NULL, HFILL}
3801 },
3802 { &hf_sccp_calling_chinese_pc,
3803 { "PC", "sccp.calling.chinese_pc",
3804 FT_STRING, BASE_NONE, NULL, 0x0,
3805 NULL, HFILL}
3806 },
3807 { &hf_sccp_calling_japan_pc,
3808 { "PC", "sccp.calling.pc",
3809 FT_UINT16, BASE_DEC, NULL, 0x0,
3810 NULL, HFILL}
3811 },
3812 { &hf_sccp_calling_pc_network,
3813 { "PC Network", "sccp.calling.network",
3814 FT_UINT24, BASE_DEC, NULL, ANSI_NETWORK_MASK,
3815 NULL, HFILL }
3816 },
3817 { &hf_sccp_calling_pc_cluster,
3818 { "PC Cluster", "sccp.calling.cluster",
3819 FT_UINT24, BASE_DEC, NULL, ANSI_CLUSTER_MASK,
3820 NULL, HFILL }
3821 },
3822 { &hf_sccp_calling_pc_member,
3823 { "PC Member", "sccp.calling.member",
3824 FT_UINT24, BASE_DEC, NULL, ANSI_MEMBER_MASK,
3825 NULL, HFILL }
3826 },
3827 { &hf_sccp_calling_gt_nai,
3828 { "Nature of Address Indicator", "sccp.calling.nai",
3829 FT_UINT8, BASE_HEX, VALS(sccp_nai_values), GT_NAI_MASK,
3830 NULL, HFILL }
3831 },
3832 { &hf_sccp_calling_gt_oe,
3833 { "Odd/Even Indicator", "sccp.calling.oe",
3834 FT_UINT8, BASE_HEX, VALS(sccp_oe_values), GT_OE_MASK,
3835 NULL, HFILL }
3836 },
3837 { &hf_sccp_calling_gt_tt,
3838 { "Translation Type", "sccp.calling.tt",
3839 FT_UINT8, BASE_HEX_DEC, NULL, 0x0,
3840 NULL, HFILL }
3841 },
3842 { &hf_sccp_calling_gt_np,
3843 { "Numbering Plan", "sccp.calling.np",
3844 FT_UINT8, BASE_HEX, VALS(sccp_np_values), GT_NP_MASK,
3845 NULL, HFILL }
3846 },
3847 { &hf_sccp_calling_gt_es,
3848 { "Encoding Scheme", "sccp.calling.es",
3849 FT_UINT8, BASE_HEX, VALS(sccp_es_values), GT_ES_MASK,
3850 NULL, HFILL }
3851 },
3852 { &hf_sccp_calling_gt_digits,
3853 { "Calling Party Digits", "sccp.calling.digits",
3854 FT_STRING, BASE_NONE, NULL, 0x0,
3855 NULL, HFILL }
3856 },
3857 { &hf_sccp_calling_gt_digits_length,
3858 { "Number of Calling Party Digits", "sccp.calling.digits.length",
3859 FT_UINT8, BASE_DEC, NULL, 0x0,
3860 NULL, HFILL }
3861 },
3862 { &hf_sccp_dlr,
3863 { "Destination Local Reference", "sccp.dlr",
3864 FT_UINT24, BASE_HEX, NULL, 0x0,
3865 NULL, HFILL}
3866 },
3867 { &hf_sccp_slr,
3868 { "Source Local Reference", "sccp.slr",
3869 FT_UINT24, BASE_HEX, NULL, 0x0,
3870 NULL, HFILL}
3871 },
3872 { &hf_sccp_lr,
3873 { "Local Reference", "sccp.lr",
3874 FT_UINT24, BASE_HEX, NULL, 0x0,
3875 NULL, HFILL}
3876 },
3877 { &hf_sccp_class,
3878 { "Class", "sccp.class",
3879 FT_UINT8, BASE_HEX, NULL, CLASS_CLASS_MASK,
3880 NULL, HFILL}
3881 },
3882 { &hf_sccp_handling,
3883 { "Message handling", "sccp.handling",
3884 FT_UINT8, BASE_HEX, VALS(sccp_class_handling_values), CLASS_SPARE_HANDLING_MASK,
3885 NULL, HFILL}
3886 },
3887 { &hf_sccp_more,
3888 { "More data", "sccp.more",
3889 FT_UINT8, BASE_HEX, VALS(sccp_segmenting_reassembling_values), SEGMENTING_REASSEMBLING_MASK,
3890 NULL, HFILL}
3891 },
3892 { &hf_sccp_rsn,
3893 { "Receive Sequence Number", "sccp.rsn",
3894 FT_UINT8, BASE_HEX, NULL, RSN_MASK,
3895 NULL, HFILL}
3896 },
3897 { &hf_sccp_sequencing_segmenting_ssn,
3898 { "Sequencing Segmenting: Send Sequence Number", "sccp.sequencing_segmenting.ssn",
3899 FT_UINT8, BASE_HEX, NULL, SEND_SEQUENCE_NUMBER_MASK,
3900 NULL, HFILL}
3901 },
3902 { &hf_sccp_sequencing_segmenting_rsn,
3903 { "Sequencing Segmenting: Receive Sequence Number", "sccp.sequencing_segmenting.rsn",
3904 FT_UINT8, BASE_HEX, NULL, RECEIVE_SEQUENCE_NUMBER_MASK,
3905 NULL, HFILL}
3906 },
3907 { &hf_sccp_sequencing_segmenting_more,
3908 { "Sequencing Segmenting: More", "sccp.sequencing_segmenting.more",
3909 FT_UINT8, BASE_HEX, VALS(sccp_segmenting_reassembling_values), SEQUENCING_SEGMENTING_MORE_MASK,
3910 NULL, HFILL}
3911 },
3912 { &hf_sccp_credit,
3913 { "Credit", "sccp.credit",
3914 FT_UINT8, BASE_HEX, NULL, 0x0,
3915 NULL, HFILL}
3916 },
3917 { &hf_sccp_release_cause,
3918 { "Release Cause", "sccp.release_cause",
3919 FT_UINT8, BASE_HEX, VALS(sccp_release_cause_values), 0x0,
3920 NULL, HFILL}
3921 },
3922 { &hf_sccp_return_cause,
3923 { "Return Cause", "sccp.return_cause",
3924 FT_UINT8, BASE_HEX, VALS(sccp_return_cause_values), 0x0,
3925 NULL, HFILL}
3926 },
3927 { &hf_sccp_reset_cause,
3928 { "Reset Cause", "sccp.reset_cause",
3929 FT_UINT8, BASE_HEX, VALS(sccp_reset_cause_values), 0x0,
3930 NULL, HFILL}
3931 },
3932 { &hf_sccp_error_cause,
3933 { "Error Cause", "sccp.error_cause",
3934 FT_UINT8, BASE_HEX, VALS(sccp_error_cause_values), 0x0,
3935 NULL, HFILL}
3936 },
3937 { &hf_sccp_refusal_cause,
3938 { "Refusal Cause", "sccp.refusal_cause",
3939 FT_UINT8, BASE_HEX, VALS(sccp_refusal_cause_values), 0x0,
3940 NULL, HFILL}
3941 },
3942 { &hf_sccp_segmentation_first,
3943 { "Segmentation: First", "sccp.segmentation.first",
3944 FT_UINT8, BASE_HEX, VALS(sccp_segmentation_first_segment_values), SEGMENTATION_FIRST_SEGMENT_MASK,
3945 NULL, HFILL}
3946 },
3947 { &hf_sccp_segmentation_class,
3948 { "Segmentation: Class", "sccp.segmentation.class",
3949 FT_UINT8, BASE_HEX, VALS(sccp_segmentation_class_values), SEGMENTATION_CLASS_MASK,
3950 NULL, HFILL}
3951 },
3952 { &hf_sccp_segmentation_remaining,
3953 { "Segmentation: Remaining", "sccp.segmentation.remaining",
3954 FT_UINT8, BASE_HEX, NULL, SEGMENTATION_REMAINING_MASK,
3955 NULL, HFILL}
3956 },
3957 { &hf_sccp_segmentation_slr,
3958 { "Segmentation: Source Local Reference", "sccp.segmentation.slr",
3959 FT_UINT24, BASE_HEX, NULL, 0x0,
3960 NULL, HFILL}
3961 },
3962 { &hf_sccp_hop_counter,
3963 { "Hop Counter", "sccp.hops",
3964 FT_UINT8, BASE_HEX, NULL, 0x0,
3965 NULL, HFILL}
3966 },
3967 { &hf_sccp_importance,
3968 { "Importance", "sccp.importance",
3969 FT_UINT8, BASE_HEX, NULL, IMPORTANCE_IMPORTANCE_MASK,
3970 NULL, HFILL}
3971 },
3972 /* ISNI is ANSI only */
3973 { &hf_sccp_ansi_isni_mi,
3974 { "ISNI Mark for Identification Indicator", "sccp.isni.mi",
3975 FT_UINT8, BASE_HEX, VALS(sccp_isni_mark_for_id_values), ANSI_ISNI_MI_MASK,
3976 NULL, HFILL}
3977 },
3978 { &hf_sccp_ansi_isni_iri,
3979 { "ISNI Routing Indicator", "sccp.isni.iri",
3980 FT_UINT8, BASE_HEX, VALS(sccp_isni_iri_values), ANSI_ISNI_IRI_MASK,
3981 NULL, HFILL}
3982 },
3983 { &hf_sccp_ansi_isni_ti,
3984 { "ISNI Type Indicator", "sccp.isni.ti",
3985 FT_UINT8, BASE_HEX, VALS(sccp_isni_ti_values), ANSI_ISNI_TI_MASK,
3986 NULL, HFILL}
3987 },
3988 { &hf_sccp_ansi_isni_netspec,
3989 { "ISNI Network Specific (Type 1)", "sccp.isni.netspec",
3990 FT_UINT8, BASE_HEX, NULL, ANSI_ISNI_NETSPEC_MASK,
3991 NULL, HFILL}
3992 },
3993 { &hf_sccp_ansi_isni_counter,
3994 { "ISNI Counter", "sccp.isni.counter",
3995 FT_UINT8, BASE_DEC, NULL, ANSI_ISNI_COUNTER_MASK,
3996 NULL, HFILL}
3997 },
3998 { &hf_sccp_ansi_isni_network,
3999 { "Network ID network", "sccp.isni.network",
4000 FT_UINT8, BASE_DEC, NULL, 0x0,
4001 NULL, HFILL}
4002 },
4003 { &hf_sccp_ansi_isni_cluster,
4004 { "Network ID cluster", "sccp.isni.cluster",
4005 FT_UINT8, BASE_DEC, NULL, 0x0,
4006 NULL, HFILL}
4007 },
4008 {&hf_sccp_xudt_msg_fragments,
4009 { "Message fragments", "sccp.msg.fragments",
4010 FT_NONE, BASE_NONE, NULL, 0x00,
4011 NULL, HFILL }
4012 },
4013 {&hf_sccp_xudt_msg_fragment,
4014 { "Message fragment", "sccp.msg.fragment",
4015 FT_FRAMENUM, BASE_NONE, NULL, 0x00,
4016 NULL, HFILL }
4017 },
4018 {&hf_sccp_xudt_msg_fragment_overlap,
4019 { "Message fragment overlap", "sccp.msg.fragment.overlap",
4020 FT_BOOLEAN, BASE_NONE, NULL, 0x0,
4021 NULL, HFILL }
4022 },
4023 {&hf_sccp_xudt_msg_fragment_overlap_conflicts,
4024 { "Message fragment overlapping with conflicting data", "sccp.msg.fragment.overlap.conflicts",
4025 FT_BOOLEAN, BASE_NONE, NULL, 0x0,
4026 NULL, HFILL }
4027 },
4028 {&hf_sccp_xudt_msg_fragment_multiple_tails,
4029 { "Message has multiple tail fragments", "sccp.msg.fragment.multiple_tails",
4030 FT_BOOLEAN, BASE_NONE, NULL, 0x0,
4031 NULL, HFILL }
4032 },
4033 {&hf_sccp_xudt_msg_fragment_too_long_fragment,
4034 { "Message fragment too long", "sccp.msg.fragment.too_long_fragment",
4035 FT_BOOLEAN, BASE_NONE, NULL, 0x0,
4036 NULL, HFILL }
4037 },
4038 {&hf_sccp_xudt_msg_fragment_error,
4039 { "Message defragmentation error", "sccp.msg.fragment.error",
4040 FT_FRAMENUM, BASE_NONE, NULL, 0x00,
4041 NULL, HFILL }
4042 },
4043 {&hf_sccp_xudt_msg_fragment_count,
4044 { "Message fragment count", "sccp.msg.fragment.count",
4045 FT_UINT32, BASE_DEC, NULL, 0x00,
4046 NULL, HFILL }
4047 },
4048 {&hf_sccp_xudt_msg_reassembled_in,
4049 { "Reassembled in", "sccp.msg.reassembled.in",
4050 FT_FRAMENUM, BASE_NONE, NULL, 0x00,
4051 NULL, HFILL }
4052 },
4053 {&hf_sccp_xudt_msg_reassembled_length,
4054 { "Reassembled SCCP length", "sccp.msg.reassembled.length",
4055 FT_UINT32, BASE_DEC, NULL, 0x00,
4056 NULL, HFILL }
4057 },
4058 { &hf_sccp_assoc_id,
4059 { "Association ID", "sccp.assoc.id",
4060 FT_UINT32, BASE_DEC, NULL, 0x0,
4061 NULL, HFILL}
4062 },
4063 {&hf_sccp_assoc_msg,
4064 { "Message in frame", "sccp.assoc.msg",
4065 FT_FRAMENUM, BASE_NONE, NULL, 0x00,
4066 NULL, HFILL }
4067 },
4068 {&hf_sccp_segmented_data,
4069 { "Segmented Data", "sccp.segmented_data",
4070 FT_BYTES, BASE_NONE, NULL, 0x00,
4071 NULL, HFILL }
4072 },
4073 {&hf_sccp_linked_dissector,
4074 { "Linked dissector", "sccp.linked_dissector",
4075 FT_STRING, BASE_NONE, NULL, 0x00,
4076 NULL, HFILL }
4077 },
4078 {&hf_sccp_end_optional_param,
4079 { "End of Optional", "sccp.end_optional_param",
4080 FT_NONE, BASE_NONE, NULL, 0x00,
4081 NULL, HFILL }
4082 },
4083 {&hf_sccp_unknown_message,
4084 { "Unknown message", "sccp.unknown_message",
4085 FT_BYTES, BASE_NONE, NULL, 0x00,
4086 NULL, HFILL }
4087 },
4088 {&hf_sccp_unknown_parameter,
4089 { "Unknown parameter", "sccp.unknown_parameter",
4090 FT_BYTES, BASE_NONE, NULL, 0x00,
4091 NULL, HFILL }
4092 },
4093 };
4094
4095 /* Setup protocol subtree array */
4096 static gint *ett[] = {
4097 &ett_sccp,
4098 &ett_sccp_called,
4099 &ett_sccp_called_ai,
4100 &ett_sccp_called_pc,
4101 &ett_sccp_called_gt,
4102 &ett_sccp_called_gt_digits,
4103 &ett_sccp_calling,
4104 &ett_sccp_calling_ai,
4105 &ett_sccp_calling_pc,
4106 &ett_sccp_calling_gt,
4107 &ett_sccp_calling_gt_digits,
4108 &ett_sccp_sequencing_segmenting,
4109 &ett_sccp_segmentation,
4110 &ett_sccp_ansi_isni_routing_control,
4111 &ett_sccp_xudt_msg_fragment,
4112 &ett_sccp_xudt_msg_fragments,
4113 &ett_sccp_assoc
4114 };
4115
4116 static ei_register_info ei[] = {
4117 { &ei_sccp_wrong_length, { "sccp.wrong_length", PI_MALFORMED, PI_ERROR, "Wrong length indicated.", EXPFILL }},
4118 { &ei_sccp_international_standard_address, { "sccp.international_standard_address", PI_MALFORMED, PI_WARN,
4119 "Address is coded to international standards. This doesn't normally happen in ANSI networks.", EXPFILL }},
4120 { &ei_sccp_no_ssn_present, { "sccp.ssn.not_present", PI_PROTOCOL, PI_WARN, "Message is routed on SSN, but SSN is not present", EXPFILL }},
4121 { &ei_sccp_ssn_zero, { "sccp.ssn.is_zero", PI_PROTOCOL, PI_WARN, "Message is routed on SSN, but SSN is zero (unspecified)", EXPFILL }},
4122 { &ei_sccp_class_unexpected, { "sccp.class_unexpected", PI_MALFORMED, PI_ERROR, "Unexpected message class for this message type", EXPFILL }},
4123 { &ei_sccp_handling_invalid, { "sccp.handling_invalid", PI_MALFORMED, PI_ERROR, "Invalid message handling", EXPFILL }},
4124 { &ei_sccp_gt_digits_missing, { "sccp.gt_digits_missing", PI_MALFORMED, PI_ERROR, "Address digits missing", EXPFILL }},
4125 };
4126
4127 /* Decode As handling */
4128 static build_valid_func sccp_da_build_value[1] = {sccp_value};
4129 static decode_as_value_t sccp_da_values = {sccp_prompt, 1, sccp_da_build_value};
4130 static decode_as_t sccp_da = {"sccp", "sccp.ssn", 1, 0, &sccp_da_values, NULL, NULL,
4131 decode_as_default_populate_list, decode_as_default_reset, decode_as_default_change, NULL};
4132
4133 module_t *sccp_module;
4134 expert_module_t* expert_sccp;
4135
4136 static uat_field_t users_flds[] = {
4137 UAT_FLD_DEC(sccp_users, ni, "Network Indicator", "Network Indicator"),
4138 UAT_FLD_RANGE(sccp_users, called_pc, "Called DPCs", 0xFFFFFF, "DPCs for which this protocol is to be used"),
4139 UAT_FLD_RANGE(sccp_users, called_ssn, "Called SSNs", 255, "Called SSNs for which this protocol is to be used"),
4140 UAT_FLD_VS(sccp_users, user, "User protocol", sccp_users_vals, "The User Protocol"),
4141 UAT_END_FIELDS
4142 };
4143
4144
4145 uat_t *users_uat = uat_new("SCCP Users Table", sizeof(sccp_user_t),
4146 "sccp_users", TRUE, &sccp_users,
4147 &num_sccp_users, UAT_AFFECTS_DISSECTION,
4148 "ChSccpUsers", sccp_users_copy_cb,
4149 sccp_users_update_cb, sccp_users_free_cb,
4150 NULL, NULL, users_flds );
4151
4152 /* Register the protocol name and description */
4153 proto_sccp = proto_register_protocol("Signalling Connection Control Part", "SCCP", "sccp");
4154
4155 sccp_handle = register_dissector("sccp", dissect_sccp, proto_sccp);
4156
4157 /* Required function calls to register the header fields and subtrees used */
4158 proto_register_field_array(proto_sccp, hf, array_length(hf));
4159 proto_register_subtree_array(ett, array_length(ett));
4160 expert_sccp = expert_register_protocol(proto_sccp);
4161 expert_register_field_array(expert_sccp, ei, array_length(ei));
4162
4163 sccp_ssn_dissector_table = register_dissector_table("sccp.ssn", "SCCP SSN", proto_sccp, FT_UINT8, BASE_DEC);
4164
4165 heur_subdissector_list = register_heur_dissector_list("sccp", proto_sccp);
4166
4167 sccp_module = prefs_register_protocol(proto_sccp, proto_reg_handoff_sccp);
4168
4169 prefs_register_uint_preference(sccp_module, "source_pc",
4170 "Source PC (in hex)",
4171 "The source point code (usually MSC) (to determine whether message is uplink or downlink)",
4172 16, &sccp_source_pc_global);
4173
4174 prefs_register_bool_preference(sccp_module, "show_length", "Show length",
4175 "Show parameter length in the protocol tree",
4176 &sccp_show_length);
4177
4178 prefs_register_bool_preference(sccp_module, "defragment_xudt",
4179 "Reassemble SCCP messages",
4180 "Whether SCCP messages should be reassembled",
4181 &sccp_reassemble);
4182
4183 prefs_register_bool_preference(sccp_module, "trace_sccp",
4184 "Trace Associations",
4185 "Whether to keep information about messages and their associations",
4186 &trace_sccp);
4187
4188
4189 prefs_register_bool_preference(sccp_module, "show_more_info",
4190 "Show key parameters in Info Column",
4191 "Show SLR, DLR, and CAUSE Parameters in the Information Column of the Summary",
4192 &show_key_params);
4193
4194
4195 prefs_register_uat_preference(sccp_module, "users_table", "Users Table",
4196 "A table that enumerates user protocols to be used against specific PCs and SSNs",
4197 users_uat);
4198
4199 prefs_register_bool_preference(sccp_module, "set_addresses", "Set source and destination GT addresses",
4200 "Set the source and destination addresses to the GT digits (if present)."
4201 " This may affect TCAP's ability to recognize which messages belong to which TCAP session.",
4202 &set_addresses);
4203
4204 prefs_register_string_preference(sccp_module, "default_payload", "Default Payload",
4205 "The protocol which should be used to dissect the payload if nothing else has claimed it",
4206 &default_payload);
4207
4208 prefs_register_bool_preference(sccp_module, "dt1_ignore_length", "Ignore length in DT1",
4209 "Use all bytes for data payload. Overcome 255 bytes limit of SCCP stadard."
4210 " (Some tracing tool save information without DT1 segmentation of 255 bytes)",
4211 &dt1_ignore_length);
4212
4213 register_init_routine(&init_sccp);
4214 reassembly_table_register(&sccp_xudt_msg_reassembly_table,
4215 &addresses_reassembly_table_functions);
4216
4217 assocs = wmem_tree_new_autoreset(wmem_epan_scope(), wmem_file_scope());
4218
4219 sccp_reassembly_ids = wmem_tree_new_autoreset(wmem_epan_scope(), wmem_file_scope());
4220 sccp_reassembly_id_map = wmem_map_new_autoreset(wmem_epan_scope(), wmem_file_scope(),
4221 g_int64_hash, g_int64_equal);
4222
4223 sccp_tap = register_tap("sccp");
4224
4225 register_decode_as(&sccp_da);
4226 }
4227
4228 void
proto_reg_handoff_sccp(void)4229 proto_reg_handoff_sccp(void)
4230 {
4231 static gboolean initialised = FALSE;
4232
4233 if (!initialised) {
4234 dissector_add_uint("wtap_encap", WTAP_ENCAP_SCCP, sccp_handle);
4235 dissector_add_uint("mtp3.service_indicator", MTP_SI_SCCP, sccp_handle);
4236 dissector_add_string("tali.opcode", "sccp", sccp_handle);
4237
4238 data_handle = find_dissector("data");
4239 tcap_handle = find_dissector_add_dependency("tcap", proto_sccp);
4240 ranap_handle = find_dissector_add_dependency("ranap", proto_sccp);
4241 bssap_handle = find_dissector_add_dependency("bssap", proto_sccp);
4242 gsmmap_handle = find_dissector_add_dependency("gsm_map_sccp", proto_sccp);
4243 camel_handle = find_dissector_add_dependency("camel", proto_sccp);
4244 inap_handle = find_dissector_add_dependency("inap", proto_sccp);
4245
4246 ss7pc_address_type = address_type_get_by_name("AT_SS7PC");
4247
4248 initialised = TRUE;
4249 hf_assoc_imsi = proto_registrar_get_id_byname("e212.assoc.imsi");
4250 }
4251
4252 default_handle = find_dissector(default_payload);
4253 }
4254
4255 /*
4256 * Editor modelines - https://www.wireshark.org/tools/modelines.html
4257 *
4258 * Local Variables:
4259 * c-basic-offset: 2
4260 * tab-width: 8
4261 * indent-tabs-mode: nil
4262 * End:
4263 *
4264 * ex: set shiftwidth=2 tabstop=8 expandtab:
4265 * :indentSize=2:tabSize=8:noTabs=true:
4266 */
4267