2002-03-04 22:39:22 +00:00
/* packet-sccp.c
* Routines for Signalling Connection Control Part ( SCCP ) dissection
2003-04-10 18:52:15 +00:00
*
2002-03-04 22:39:22 +00:00
* It is hopefully compliant to :
* ANSI T1 .112 .3 - 1996
* ITU - T Q .713 7 / 1996
2003-04-10 18:52:15 +00:00
* YDN 03 8 - 1997 ( Chinese ITU variant )
2006-04-05 16:03:36 +00:00
* JT - Q713 and NTT - Q713 ( Japan )
*
* Note that Japan - specific GTT is incomplete ; in particular , the specific
* TTs that are defined in TTC and NTT are not decoded in detail .
2002-03-04 22:39:22 +00:00
*
* Copyright 2002 , Jeff Morriss < jeff . morriss [ AT ] ulticom . com >
*
2004-07-18 00:24:25 +00:00
* $ Id $
2002-03-04 22:39:22 +00:00
*
2006-05-21 04:49:01 +00:00
* Wireshark - Network traffic analyzer
* By Gerald Combs < gerald @ wireshark . org >
2002-03-04 22:39:22 +00:00
* Copyright 1998 Gerald Combs
*
* Copied from packet - m2pa . c
*
* This program is free software ; you can redistribute it and / or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation ; either version 2
* of the License , or ( at your option ) any later version .
*
* This program is distributed in the hope that it will be useful ,
* but WITHOUT ANY WARRANTY ; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the
* GNU General Public License for more details .
*
* You should have received a copy of the GNU General Public License
* along with this program ; if not , write to the Free Software
* Foundation , Inc . , 59 Temple Place - Suite 330 , Boston , MA 02111 - 1307 , USA .
*/
# ifdef HAVE_CONFIG_H
# include "config.h"
# endif
# include <stdio.h>
# include <stdlib.h>
# include <string.h>
2003-01-02 20:44:32 +00:00
# include <glib.h>
# include <epan/packet.h>
2004-09-27 22:55:15 +00:00
# include <epan/prefs.h>
2005-12-13 22:07:09 +00:00
# include <epan/emem.h>
2006-01-19 05:51:59 +00:00
# include <epan/reassemble.h>
2007-05-13 20:58:29 +00:00
# include <epan/asn1.h>
2008-01-09 21:14:01 +00:00
# include <epan/uat.h>
2008-03-01 17:23:39 +00:00
# include <epan/strutil.h>
2008-01-09 21:14:01 +00:00
# include "packet-mtp3.h"
2006-01-31 18:33:56 +00:00
# include "packet-tcap.h"
2006-03-11 15:30:52 +00:00
# include "packet-sccp.h"
2008-01-09 21:14:01 +00:00
# include "packet-e164.h"
# include "packet-e212.h"
2008-03-28 05:56:02 +00:00
# include "packet-frame.h"
2007-03-21 00:48:46 +00:00
# include "tap.h"
2002-03-04 22:39:22 +00:00
2005-08-19 08:36:38 +00:00
static Standard_Type decode_mtp3_standard ;
2002-03-04 22:39:22 +00:00
# define SCCP_SI 3
2007-03-21 00:48:46 +00:00
# define SCCP_MSG_TYPE_OFFSET 0
# define SCCP_MSG_TYPE_LENGTH 1
2002-03-04 22:39:22 +00:00
# define POINTER_LENGTH 1
2003-03-21 23:05:25 +00:00
# define POINTER_LENGTH_LONG 2
2002-03-04 22:39:22 +00:00
2007-11-24 15:38:19 +00:00
# define INVALID_LR 0xffffff /* a reserved value */
2007-04-03 19:08:00 +00:00
2002-03-04 22:39:22 +00:00
/* Same as below but with names typed out */
static const value_string sccp_message_type_values [ ] = {
2007-03-21 00:48:46 +00:00
{ SCCP_MSG_TYPE_CR , " Connection Request " } ,
{ SCCP_MSG_TYPE_CC , " Connection Confirm " } ,
{ SCCP_MSG_TYPE_CREF , " Connection Refused " } ,
{ SCCP_MSG_TYPE_RLSD , " Released " } ,
{ SCCP_MSG_TYPE_RLC , " Release Complete " } ,
{ SCCP_MSG_TYPE_DT1 , " Data Form 1 " } ,
{ SCCP_MSG_TYPE_DT2 , " Data Form 2 " } ,
{ SCCP_MSG_TYPE_AK , " Data Acknowledgement " } ,
{ SCCP_MSG_TYPE_UDT , " Unitdata " } ,
{ SCCP_MSG_TYPE_UDTS , " Unitdata Service " } ,
{ SCCP_MSG_TYPE_ED , " Expedited Data " } ,
{ SCCP_MSG_TYPE_EA , " Expedited Data Acknowledgement " } ,
{ SCCP_MSG_TYPE_RSR , " Reset Request " } ,
{ SCCP_MSG_TYPE_RSC , " Reset Confirmation " } ,
{ SCCP_MSG_TYPE_ERR , " Error " } ,
{ SCCP_MSG_TYPE_IT , " Inactivity Timer " } ,
{ SCCP_MSG_TYPE_XUDT , " Extended Unitdata " } ,
{ SCCP_MSG_TYPE_XUDTS , " Extended Unitdata Service " } ,
{ SCCP_MSG_TYPE_LUDT , " Long Unitdata (ITU) " } ,
{ SCCP_MSG_TYPE_LUDTS , " Long Unitdata Service (ITU) " } ,
2007-01-19 17:25:13 +00:00
{ 0 , NULL } } ;
2002-03-04 22:39:22 +00:00
2003-01-02 20:44:32 +00:00
/* Same as above but in acronym form (for the Info column) */
2007-03-21 00:48:46 +00:00
const value_string sccp_message_type_acro_values [ ] = {
{ SCCP_MSG_TYPE_CR , " CR " } ,
{ SCCP_MSG_TYPE_CC , " CC " } ,
{ SCCP_MSG_TYPE_CREF , " CREF " } ,
{ SCCP_MSG_TYPE_RLSD , " RLSD " } ,
{ SCCP_MSG_TYPE_RLC , " RLC " } ,
{ SCCP_MSG_TYPE_DT1 , " DT1 " } ,
{ SCCP_MSG_TYPE_DT2 , " DT2 " } ,
{ SCCP_MSG_TYPE_AK , " AK " } ,
{ SCCP_MSG_TYPE_UDT , " UDT " } ,
{ SCCP_MSG_TYPE_UDTS , " UDTS " } ,
{ SCCP_MSG_TYPE_ED , " ED " } ,
{ SCCP_MSG_TYPE_EA , " EA " } ,
{ SCCP_MSG_TYPE_RSR , " RSR " } ,
{ SCCP_MSG_TYPE_RSC , " RSC " } ,
{ SCCP_MSG_TYPE_ERR , " ERR " } ,
{ SCCP_MSG_TYPE_IT , " IT " } ,
{ SCCP_MSG_TYPE_XUDT , " XUDT " } ,
{ SCCP_MSG_TYPE_XUDTS , " XUDTS " } ,
{ SCCP_MSG_TYPE_LUDT , " LUDT " } ,
{ SCCP_MSG_TYPE_LUDTS , " LUDTS " } ,
2007-01-19 17:25:13 +00:00
{ 0 , NULL } } ;
2002-03-04 22:39:22 +00:00
# define PARAMETER_LENGTH_LENGTH 1
# define PARAMETER_LONG_DATA_LENGTH_LENGTH 2
# define PARAMETER_TYPE_LENGTH 1
2007-01-19 17:25:13 +00:00
# define PARAMETER_END_OF_OPTIONAL_PARAMETERS 0x00
# define PARAMETER_DESTINATION_LOCAL_REFERENCE 0x01
# define PARAMETER_SOURCE_LOCAL_REFERENCE 0x02
# define PARAMETER_CALLED_PARTY_ADDRESS 0x03
# define PARAMETER_CALLING_PARTY_ADDRESS 0x04
# define PARAMETER_CLASS 0x05
# define PARAMETER_SEGMENTING_REASSEMBLING 0x06
# define PARAMETER_RECEIVE_SEQUENCE_NUMBER 0x07
# define PARAMETER_SEQUENCING_SEGMENTING 0x08
2007-12-30 00:02:25 +00:00
# define PARAMETER_CREDIT 0x09
# define PARAMETER_RELEASE_CAUSE 0x0a
# define PARAMETER_RETURN_CAUSE 0x0b
# define PARAMETER_RESET_CAUSE 0x0c
# define PARAMETER_ERROR_CAUSE 0x0d
# define PARAMETER_REFUSAL_CAUSE 0x0e
# define PARAMETER_DATA 0x0f
# define PARAMETER_SEGMENTATION 0x10
# define PARAMETER_HOP_COUNTER 0x11
2002-03-04 22:39:22 +00:00
/* The below 2 are ITU only */
2007-12-30 00:02:25 +00:00
# define PARAMETER_IMPORTANCE 0x12
# define PARAMETER_LONG_DATA 0x13
2002-03-04 22:39:22 +00:00
/* ISNI is ANSI only */
2007-12-30 00:02:25 +00:00
# define PARAMETER_ISNI 0xfa
2002-03-04 22:39:22 +00:00
static const value_string sccp_parameter_values [ ] = {
2007-12-30 00:02:25 +00:00
{ PARAMETER_END_OF_OPTIONAL_PARAMETERS , " End of Optional Parameters " } ,
{ PARAMETER_DESTINATION_LOCAL_REFERENCE , " Destination Local Reference " } ,
{ PARAMETER_SOURCE_LOCAL_REFERENCE , " Source Local Reference " } ,
{ PARAMETER_CALLED_PARTY_ADDRESS , " Called Party Address " } ,
{ PARAMETER_CALLING_PARTY_ADDRESS , " Calling Party Address " } ,
{ PARAMETER_CLASS , " Protocol Class " } ,
{ PARAMETER_SEGMENTING_REASSEMBLING , " Segmenting/Reassembling " } ,
{ PARAMETER_RECEIVE_SEQUENCE_NUMBER , " Receive Sequence Number " } ,
{ PARAMETER_SEQUENCING_SEGMENTING , " Sequencing/Segmenting " } ,
{ PARAMETER_CREDIT , " Credit " } ,
{ PARAMETER_RELEASE_CAUSE , " Release Cause " } ,
{ PARAMETER_RETURN_CAUSE , " Return Cause " } ,
{ PARAMETER_RESET_CAUSE , " Reset Cause " } ,
{ PARAMETER_ERROR_CAUSE , " Error Cause " } ,
{ PARAMETER_REFUSAL_CAUSE , " Refusal Cause " } ,
{ PARAMETER_DATA , " Data " } ,
{ PARAMETER_SEGMENTATION , " Segmentation " } ,
{ PARAMETER_HOP_COUNTER , " Hop Counter " } ,
{ PARAMETER_IMPORTANCE , " Importance (ITU) " } ,
{ PARAMETER_LONG_DATA , " Long Data (ITU) " } ,
{ PARAMETER_ISNI , " Intermediate Signaling Network Identification (ANSI) " } ,
2007-01-19 17:25:13 +00:00
{ 0 , NULL } } ;
# define END_OF_OPTIONAL_PARAMETERS_LENGTH 1
# define DESTINATION_LOCAL_REFERENCE_LENGTH 3
# define SOURCE_LOCAL_REFERENCE_LENGTH 3
# define PROTOCOL_CLASS_LENGTH 1
# define RECEIVE_SEQUENCE_NUMBER_LENGTH 1
# define CREDIT_LENGTH 1
# define RELEASE_CAUSE_LENGTH 1
# define RETURN_CAUSE_LENGTH 1
# define RESET_CAUSE_LENGTH 1
# define ERROR_CAUSE_LENGTH 1
# define REFUSAL_CAUSE_LENGTH 1
# define HOP_COUNTER_LENGTH 1
# define IMPORTANCE_LENGTH 1
2002-03-04 22:39:22 +00:00
/* Parts of the Called and Calling Address parameters */
/* Address Indicator */
2007-01-19 17:25:13 +00:00
# define ADDRESS_INDICATOR_LENGTH 1
# define ITU_RESERVED_MASK 0x80
# define ANSI_NATIONAL_MASK 0x80
# define ROUTING_INDICATOR_MASK 0x40
# define GTI_MASK 0x3C
# define GTI_SHIFT 2
# define ITU_SSN_INDICATOR_MASK 0x02
# define ITU_PC_INDICATOR_MASK 0x01
# define ANSI_PC_INDICATOR_MASK 0x02
# define ANSI_SSN_INDICATOR_MASK 0x01
2002-03-04 22:39:22 +00:00
static const value_string sccp_national_indicator_values [ ] = {
{ 0x0 , " Address coded to International standard " } ,
{ 0x1 , " Address coded to National standard " } ,
{ 0 , NULL } } ;
static const value_string sccp_routing_indicator_values [ ] = {
{ 0x0 , " Route on GT " } ,
{ 0x1 , " Route on SSN " } ,
{ 0 , NULL } } ;
2007-01-19 17:25:13 +00:00
# define AI_GTI_NO_GT 0x0
# define ITU_AI_GTI_NAI 0x1
# define AI_GTI_TT 0x2
# define ITU_AI_GTI_TT_NP_ES 0x3
# define ITU_AI_GTI_TT_NP_ES_NAI 0x4
2002-03-04 22:39:22 +00:00
static const value_string sccp_itu_global_title_indicator_values [ ] = {
2007-01-19 17:25:13 +00:00
{ AI_GTI_NO_GT , " No Global Title " } ,
{ ITU_AI_GTI_NAI , " Nature of Address Indicator only " } ,
{ AI_GTI_TT , " Translation Type only " } ,
{ ITU_AI_GTI_TT_NP_ES , " Translation Type, Numbering Plan, and Encoding Scheme included " } ,
{ ITU_AI_GTI_TT_NP_ES_NAI , " Translation Type, Numbering Plan, Encoding Scheme, and Nature of Address Indicator included " } ,
{ 0 , NULL } } ;
/* #define AI_GTI_NO_GT 0x0 */
# define ANSI_AI_GTI_TT_NP_ES 0x1
/* #define AI_GTI_TT 0x2 */
2002-03-04 22:39:22 +00:00
static const value_string sccp_ansi_global_title_indicator_values [ ] = {
2007-01-19 17:25:13 +00:00
{ AI_GTI_NO_GT , " No Global Title " } ,
{ ANSI_AI_GTI_TT_NP_ES , " Translation Type, Numbering Plan, and Encoding Scheme included " } ,
{ AI_GTI_TT , " Translation Type only " } ,
{ 0 , NULL } } ;
2002-03-04 22:39:22 +00:00
static const value_string sccp_ai_pci_values [ ] = {
{ 0x1 , " Point Code present " } ,
{ 0x0 , " Point Code not present " } ,
{ 0 , NULL } } ;
static const value_string sccp_ai_ssni_values [ ] = {
{ 0x1 , " SSN present " } ,
{ 0x0 , " SSN not present " } ,
{ 0 , NULL } } ;
# define ADDRESS_SSN_LENGTH 1
# define INVALID_SSN 0xff
2006-02-04 10:28:28 +00:00
/* Some values from 3GPP TS 23.003 */
2006-04-05 16:03:36 +00:00
/* Japan TTC and NTT define a lot of SSNs, some of which conflict with
* these . They are not added for now .
*/
2002-03-04 22:39:22 +00:00
static const value_string sccp_ssn_values [ ] = {
{ 0x00 , " SSN not known/not used " } ,
{ 0x01 , " SCCP management " } ,
{ 0x02 , " Reserved for ITU-T allocation " } ,
{ 0x03 , " ISDN User Part " } ,
{ 0x04 , " OMAP (Operation, Maintenance, and Administration Part) " } ,
{ 0x05 , " MAP (Mobile Application Part) " } ,
{ 0x06 , " HLR (Home Location Register) " } ,
{ 0x07 , " VLR (Visitor Location Register) " } ,
{ 0x08 , " MSC (Mobile Switching Center) " } ,
{ 0x09 , " EIC/EIR (Equipment Identifier Center/Equipment Identification Register) " } ,
{ 0x0a , " AUC/AC (Authentication Center) " } ,
{ 0x0b , " ISDN supplementary services (ITU only) " } ,
{ 0x0c , " Reserved for international use (ITU only) " } ,
{ 0x0d , " Broadband ISDN edge-to-edge applications (ITU only) " } ,
{ 0x0e , " TC test responder (ITU only) " } ,
2006-02-04 10:28:28 +00:00
/* The following national network subsystem numbers have been allocated for use within and
* between GSM / UMTS networks :
*/
2003-10-22 20:12:02 +00:00
{ 0x8e , " RANAP " } ,
2006-03-29 17:00:16 +00:00
{ 0x8f , " RNSAP " } ,
2006-02-04 10:28:28 +00:00
{ 0x91 , " GMLC(MAP) " } ,
2006-02-22 16:25:29 +00:00
{ 0x92 , " CAP " } ,
2006-02-04 10:28:28 +00:00
{ 0x93 , " gsmSCF (MAP) or IM-SSF (MAP) or Presence Network Agent " } ,
{ 0x94 , " SIWF (MAP) " } ,
{ 0x95 , " SGSN (MAP) " } ,
{ 0x96 , " GGSN (MAP) " } ,
/* The following national network subsystem numbers have been allocated for use within GSM/UMTS networks:*/
{ 0xf9 , " PCAP " } ,
{ 0xfa , " BSC (BSSAP-LE) " } ,
{ 0xfb , " MSC (BSSAP-LE) " } ,
{ 0xfc , " IOS or SMLC (BSSAP-LE) " } ,
{ 0xfd , " BSS O&M (A interface) " } ,
2003-10-22 20:12:02 +00:00
{ 0xfe , " BSSAP/BSAP " } ,
2002-03-04 22:39:22 +00:00
{ 0 , NULL } } ;
/* * * * * * * * * * * * * * * * *
* Global Title : ITU GTI = = 0001 *
* * * * * * * * * * * * * * * * */
# define GT_NAI_MASK 0x7F
# define GT_NAI_LENGTH 1
2008-01-09 22:01:57 +00:00
# define GT_NAI_UNKNOWN 0x00
# define GT_NAI_SUBSCRIBER_NUMBER 0x01
# define GT_NAI_RESERVED_NATIONAL 0x02
# define GT_NAI_NATIONAL_SIG_NUM 0x03
# define GT_NAI_INTERNATIONAL_NUM 0x04
2002-03-04 22:39:22 +00:00
static const value_string sccp_nai_values [ ] = {
2008-01-09 22:01:57 +00:00
{ GT_NAI_UNKNOWN , " NAI unknown " } ,
{ GT_NAI_SUBSCRIBER_NUMBER , " Subscriber Number " } ,
{ GT_NAI_RESERVED_NATIONAL , " Reserved for national use " } ,
{ GT_NAI_NATIONAL_SIG_NUM , " National significant number " } ,
{ GT_NAI_INTERNATIONAL_NUM , " International number " } ,
{ 0 , NULL } } ;
2002-03-04 22:39:22 +00:00
# define GT_OE_MASK 0x80
# define GT_OE_EVEN 0
# define GT_OE_ODD 1
static const value_string sccp_oe_values [ ] = {
2007-01-19 17:25:13 +00:00
{ GT_OE_EVEN , " Even number of address signals " } ,
{ GT_OE_ODD , " Odd number of address signals " } ,
{ 0 , NULL } } ;
2002-03-04 22:39:22 +00:00
# define GT_SIGNAL_LENGTH 1
# define GT_ODD_SIGNAL_MASK 0x0f
# define GT_EVEN_SIGNAL_MASK 0xf0
# define GT_EVEN_SIGNAL_SHIFT 4
2007-03-22 22:59:20 +00:00
# define GT_MAX_SIGNALS (32*7) /* its a bit big, but it allows for adding a lot of "(spare)" and "Unknown" values (7 chars) if there are errors - e.g. ANSI vs ITU wrongly selected */
2002-03-04 22:39:22 +00:00
static const value_string sccp_address_signal_values [ ] = {
{ 0 , " 0 " } ,
{ 1 , " 1 " } ,
{ 2 , " 2 " } ,
{ 3 , " 3 " } ,
{ 4 , " 4 " } ,
{ 5 , " 5 " } ,
{ 6 , " 6 " } ,
{ 7 , " 7 " } ,
{ 8 , " 8 " } ,
{ 9 , " 9 " } ,
{ 10 , " (spare) " } ,
{ 11 , " 11 " } ,
{ 12 , " 12 " } ,
{ 13 , " (spare) " } ,
{ 14 , " (spare) " } ,
{ 15 , " ST " } ,
{ 0 , NULL } } ;
/* * * * * * * * * * * * * * * * * * * * *
* Global Title : ITU and ANSI GTI = = 0010 *
* * * * * * * * * * * * * * * * * * * * */
# define GT_TT_LENGTH 1
/* * * * * * * * * * * * * * * * * * * * * * * * * *
* Global Title : ITU GTI = = 0011 , ANSI GTI = = 0001 *
* * * * * * * * * * * * * * * * * * * * * * * * * */
# define GT_NP_MASK 0xf0
2008-01-09 22:01:57 +00:00
# define GT_NP_SHIFT 4
2002-03-04 22:39:22 +00:00
# define GT_NP_ES_LENGTH 1
2008-01-09 22:01:57 +00:00
# define GT_NP_UNKNOWN 0x00
# define GT_NP_ISDN 0x01
# define GT_NP_GENERIC_RESERVED 0x02
# define GT_NP_DATA 0x03
# define GT_NP_TELEX 0x04
# define GT_NP_MARITIME_MOBILE 0x05
# define GT_NP_LAND_MOBILE 0x06
# define GT_NP_ISDN_MOBILE 0x07
# define GT_NP_PRIVATE_NETWORK 0x0e
# define GT_NP_RESERVED 0x0f
2002-03-04 22:39:22 +00:00
static const value_string sccp_np_values [ ] = {
2008-01-09 22:01:57 +00:00
{ GT_NP_UNKNOWN , " Unknown " } ,
{ GT_NP_ISDN , " ISDN/telephony " } ,
{ GT_NP_GENERIC_RESERVED , " Generic (ITU)/Reserved (ANSI) " } ,
{ GT_NP_DATA , " Data " } ,
{ GT_NP_TELEX , " Telex " } ,
{ GT_NP_MARITIME_MOBILE , " Maritime mobile " } ,
{ GT_NP_LAND_MOBILE , " Land mobile " } ,
{ GT_NP_ISDN_MOBILE , " ISDN/mobile " } ,
{ GT_NP_PRIVATE_NETWORK , " Private network or network-specific " } ,
{ GT_NP_RESERVED , " Reserved " } ,
{ 0 , NULL } } ;
2002-03-04 22:39:22 +00:00
# define GT_ES_MASK 0x0f
# define GT_ES_UNKNOWN 0x0
# define GT_ES_BCD_ODD 0x1
# define GT_ES_BCD_EVEN 0x2
# define GT_ES_NATIONAL 0x3
# define GT_ES_RESERVED 0xf
static const value_string sccp_es_values [ ] = {
2007-01-19 17:25:13 +00:00
{ GT_ES_UNKNOWN , " Unknown " } ,
{ GT_ES_BCD_ODD , " BCD, odd number of digits " } ,
{ GT_ES_BCD_EVEN , " BCD, even number of digits " } ,
{ GT_ES_NATIONAL , " National specific " } ,
{ GT_ES_RESERVED , " Reserved (ITU)/Spare (ANSI) " } ,
{ 0 , NULL } } ;
2002-03-04 22:39:22 +00:00
/* Address signals above */
/* * * * * * * * * * * * * * * * *
* Global Title : ITU GTI = = 0100 *
* * * * * * * * * * * * * * * * */
/* NP above */
/* ES above */
/* NAI above */
/* Address signals above */
# define CLASS_CLASS_MASK 0xf
# define CLASS_SPARE_HANDLING_MASK 0xf0
static const value_string sccp_class_handling_values [ ] = {
{ 0x0 , " No special options " } ,
{ 0x8 , " Return message on error " } ,
{ 0 , NULL } } ;
# define SEGMENTING_REASSEMBLING_LENGTH 1
# define SEGMENTING_REASSEMBLING_MASK 0x01
# define NO_MORE_DATA 0
# define MORE_DATA 1
/* This is also used by sequencing-segmenting parameter */
static const value_string sccp_segmenting_reassembling_values [ ] = {
2007-01-19 17:25:13 +00:00
{ NO_MORE_DATA , " No more data " } ,
{ MORE_DATA , " More data " } ,
{ 0 , NULL } } ;
2002-03-04 22:39:22 +00:00
2007-01-19 17:25:13 +00:00
# define RECEIVE_SEQUENCE_NUMBER_LENGTH 1
# define RSN_MASK 0xfe
2002-03-04 22:39:22 +00:00
2007-01-19 17:25:13 +00:00
# define SEQUENCING_SEGMENTING_LENGTH 2
# define SEQUENCING_SEGMENTING_SSN_LENGTH 1
# define SEQUENCING_SEGMENTING_RSN_LENGTH 1
# define SEND_SEQUENCE_NUMBER_MASK 0xfe
# define RECEIVE_SEQUENCE_NUMBER_MASK 0xfe
# define SEQUENCING_SEGMENTING_MORE_MASK 0x01
2002-03-04 22:39:22 +00:00
# define CREDIT_LENGTH 1
2007-01-19 17:25:13 +00:00
# define RELEASE_CAUSE_LENGTH 1
2002-03-04 22:39:22 +00:00
static const value_string sccp_release_cause_values [ ] = {
{ 0x00 , " End user originated " } ,
{ 0x01 , " End user congestion " } ,
{ 0x02 , " End user failure " } ,
{ 0x03 , " SCCP user originated " } ,
{ 0x04 , " Remote procedure error " } ,
{ 0x05 , " Inconsistent connection data " } ,
{ 0x06 , " Access failure " } ,
{ 0x07 , " Access congestion " } ,
{ 0x08 , " Subsystem failure " } ,
{ 0x09 , " Subsystem congestion " } ,
{ 0x0a , " MTP failure " } ,
{ 0x0b , " Netowrk congestion " } ,
{ 0x0c , " Expiration of reset timer " } ,
{ 0x0d , " Expiration of receive inactivity timer " } ,
{ 0x0e , " Reserved " } ,
{ 0x0f , " Unqualified " } ,
{ 0x10 , " SCCP failure (ITU only) " } ,
{ 0 , NULL } } ;
2007-01-19 17:25:13 +00:00
# define RETURN_CAUSE_LENGTH 1
2002-03-04 22:39:22 +00:00
static const value_string sccp_return_cause_values [ ] = {
{ 0x00 , " No translation for an address of such nature " } ,
{ 0x01 , " No translation for this specific address " } ,
{ 0x02 , " Subsystem congestion " } ,
{ 0x03 , " Subsystem failure " } ,
{ 0x04 , " Unequipped failure " } ,
{ 0x05 , " MTP failure " } ,
{ 0x06 , " Network congestion " } ,
{ 0x07 , " Unqualified " } ,
{ 0x08 , " Error in message transport " } ,
{ 0x09 , " Error in local processing " } ,
{ 0x0a , " Destination cannot perform reassembly " } ,
{ 0x0b , " SCCP failure " } ,
{ 0x0c , " Hop counter violation " } ,
{ 0x0d , " Segmentation not supported (ITU only) " } ,
{ 0x0e , " Segmentation failure (ITU only) " } ,
{ 0xf9 , " Invalid ISNI routing request (ANSI only) " } ,
{ 0xfa , " Unauthorized message (ANSI only) " } ,
{ 0xfb , " Message incompatibility (ANSI only) " } ,
{ 0xfc , " Cannot perform ISNI constrained routing (ANSI only) " } ,
{ 0xfd , " Unable to perform ISNI identification (ANSI only) " } ,
{ 0 , NULL } } ;
2007-01-19 17:25:13 +00:00
# define RESET_CAUSE_LENGTH 1
2002-03-04 22:39:22 +00:00
static const value_string sccp_reset_cause_values [ ] = {
{ 0x00 , " End user originated " } ,
{ 0x01 , " SCCP user originated " } ,
{ 0x02 , " Message out of order - incorrect send sequence number " } ,
{ 0x03 , " Message out of order - incorrect receive sequence number " } ,
{ 0x04 , " Remote procedure error - message out of window " } ,
{ 0x05 , " Remote procedure error - incorrect send sequence number after (re)initialization " } ,
{ 0x06 , " Remote procedure error - general " } ,
{ 0x07 , " Remote end user operational " } ,
{ 0x08 , " Network operational " } ,
{ 0x09 , " Access operational " } ,
{ 0x0a , " Network congestion " } ,
{ 0x0b , " Reserved (ITU)/Not obtainable (ANSI) " } ,
{ 0x0c , " Unqualified " } ,
{ 0 , NULL } } ;
2007-01-19 17:25:13 +00:00
# define ERROR_CAUSE_LENGTH 1
2002-03-04 22:39:22 +00:00
static const value_string sccp_error_cause_values [ ] = {
{ 0x00 , " Local Reference Number (LRN) mismatch - unassigned destination LRN " } ,
{ 0x01 , " Local Reference Number (LRN) mismatch - inconsistent source LRN " } ,
{ 0x02 , " Point code mismatch " } ,
{ 0x03 , " Service class mismatch " } ,
{ 0x04 , " Unqualified " } ,
{ 0 , NULL } } ;
2007-01-19 17:25:13 +00:00
# define REFUSAL_CAUSE_LENGTH 1
2002-03-04 22:39:22 +00:00
static const value_string sccp_refusal_cause_values [ ] = {
{ 0x00 , " End user originated " } ,
{ 0x01 , " End user congestion " } ,
{ 0x02 , " End user failure " } ,
{ 0x03 , " SCCP user originated " } ,
{ 0x04 , " Destination address unknown " } ,
{ 0x05 , " Destination inaccessible " } ,
{ 0x06 , " Network resource - QOS not available/non-transient " } ,
{ 0x07 , " Network resource - QOS not available/transient " } ,
{ 0x08 , " Access failure " } ,
{ 0x09 , " Access congestion " } ,
{ 0x0a , " Subsystem failure " } ,
{ 0x0b , " Subsystem congestion " } ,
{ 0x0c , " Expiration of connection establishment timer " } ,
{ 0x0d , " Incompatible user data " } ,
{ 0x0e , " Reserved " } ,
{ 0x0f , " Unqualified " } ,
{ 0x10 , " Hop counter violation " } ,
{ 0x11 , " SCCP failure (ITU only) " } ,
{ 0x12 , " No translation for an address of such nature " } ,
{ 0x13 , " Unequipped user " } ,
{ 0 , NULL } } ;
2007-01-19 17:25:13 +00:00
# define SEGMENTATION_LENGTH 4
# define SEGMENTATION_FIRST_SEGMENT_MASK 0x80
# define SEGMENTATION_CLASS_MASK 0x40
# define SEGMENTATION_SPARE_MASK 0x30
# define SEGMENTATION_REMAINING_MASK 0x0f
2002-03-04 22:39:22 +00:00
static const value_string sccp_segmentation_first_segment_values [ ] = {
{ 1 , " First segment " } ,
{ 0 , " Not first segment " } ,
{ 0 , NULL } } ;
static const value_string sccp_segmentation_class_values [ ] = {
{ 0 , " Class 0 selected " } ,
{ 1 , " Class 1 selected " } ,
{ 0 , NULL } } ;
# define HOP_COUNTER_LENGTH 1
2007-01-19 17:25:13 +00:00
# define IMPORTANCE_LENGTH 1
# define IMPORTANCE_IMPORTANCE_MASK 0x7
2002-03-04 22:39:22 +00:00
# define ANSI_ISNI_ROUTING_CONTROL_LENGTH 1
2007-01-19 17:25:13 +00:00
# define ANSI_ISNI_MI_MASK 0x01
# define ANSI_ISNI_IRI_MASK 0x06
# define ANSI_ISNI_RES_MASK 0x08
# define ANSI_ISNI_TI_MASK 0x10
# define ANSI_ISNI_TI_SHIFT 4
# define ANSI_ISNI_COUNTER_MASK 0xe0
# define ANSI_ISNI_NETSPEC_MASK 0x03
2002-03-04 22:39:22 +00:00
static const value_string sccp_isni_mark_for_id_values [ ] = {
{ 0x0 , " Do not identify networks " } ,
{ 0x1 , " Identify networks " } ,
{ 0 , NULL } } ;
static const value_string sccp_isni_iri_values [ ] = {
{ 0x0 , " Neither constrained nor suggested ISNI routing " } ,
{ 0x1 , " Constrained ISNI routing " } ,
{ 0x2 , " Reserved for suggested ISNI routing " } ,
{ 0x3 , " Spare " } ,
{ 0 , NULL } } ;
# define ANSI_ISNI_TYPE_0 0x0
# define ANSI_ISNI_TYPE_1 0x1
static const value_string sccp_isni_ti_values [ ] = {
2007-01-19 17:25:13 +00:00
{ ANSI_ISNI_TYPE_0 , " Type zero ISNI parameter format " } ,
{ ANSI_ISNI_TYPE_1 , " Type one ISNI parameter format " } ,
{ 0 , NULL } } ;
2002-03-04 22:39:22 +00:00
/* Initialize the protocol and registered fields */
static int proto_sccp = - 1 ;
static int hf_sccp_message_type = - 1 ;
static int hf_sccp_variable_pointer1 = - 1 ;
static int hf_sccp_variable_pointer2 = - 1 ;
static int hf_sccp_variable_pointer3 = - 1 ;
static int hf_sccp_optional_pointer = - 1 ;
static int hf_sccp_ssn = - 1 ;
static int hf_sccp_gt_digits = - 1 ;
/* Called Party address */
static int hf_sccp_called_national_indicator = - 1 ;
static int hf_sccp_called_routing_indicator = - 1 ;
static int hf_sccp_called_itu_global_title_indicator = - 1 ;
static int hf_sccp_called_ansi_global_title_indicator = - 1 ;
static int hf_sccp_called_itu_ssn_indicator = - 1 ;
static int hf_sccp_called_itu_point_code_indicator = - 1 ;
static int hf_sccp_called_ansi_ssn_indicator = - 1 ;
static int hf_sccp_called_ansi_point_code_indicator = - 1 ;
static int hf_sccp_called_ssn = - 1 ;
static int hf_sccp_called_pc_member = - 1 ;
static int hf_sccp_called_pc_cluster = - 1 ;
static int hf_sccp_called_pc_network = - 1 ;
2003-01-02 20:44:32 +00:00
static int hf_sccp_called_ansi_pc = - 1 ;
2003-04-10 18:52:15 +00:00
static int hf_sccp_called_chinese_pc = - 1 ;
2002-03-04 22:39:22 +00:00
static int hf_sccp_called_itu_pc = - 1 ;
2006-04-05 16:03:36 +00:00
static int hf_sccp_called_japan_pc = - 1 ;
2002-03-04 22:39:22 +00:00
static int hf_sccp_called_gt_nai = - 1 ;
static int hf_sccp_called_gt_oe = - 1 ;
static int hf_sccp_called_gt_tt = - 1 ;
static int hf_sccp_called_gt_np = - 1 ;
static int hf_sccp_called_gt_es = - 1 ;
static int hf_sccp_called_gt_digits = - 1 ;
/* Calling party address */
static int hf_sccp_calling_national_indicator = - 1 ;
static int hf_sccp_calling_routing_indicator = - 1 ;
static int hf_sccp_calling_itu_global_title_indicator = - 1 ;
static int hf_sccp_calling_ansi_global_title_indicator = - 1 ;
static int hf_sccp_calling_itu_ssn_indicator = - 1 ;
static int hf_sccp_calling_itu_point_code_indicator = - 1 ;
static int hf_sccp_calling_ansi_ssn_indicator = - 1 ;
static int hf_sccp_calling_ansi_point_code_indicator = - 1 ;
static int hf_sccp_calling_ssn = - 1 ;
static int hf_sccp_calling_pc_member = - 1 ;
static int hf_sccp_calling_pc_cluster = - 1 ;
static int hf_sccp_calling_pc_network = - 1 ;
2003-01-02 20:44:32 +00:00
static int hf_sccp_calling_ansi_pc = - 1 ;
2003-04-10 18:52:15 +00:00
static int hf_sccp_calling_chinese_pc = - 1 ;
2002-03-04 22:39:22 +00:00
static int hf_sccp_calling_itu_pc = - 1 ;
2006-04-05 16:03:36 +00:00
static int hf_sccp_calling_japan_pc = - 1 ;
2002-03-04 22:39:22 +00:00
static int hf_sccp_calling_gt_nai = - 1 ;
static int hf_sccp_calling_gt_oe = - 1 ;
static int hf_sccp_calling_gt_tt = - 1 ;
static int hf_sccp_calling_gt_np = - 1 ;
static int hf_sccp_calling_gt_es = - 1 ;
static int hf_sccp_calling_gt_digits = - 1 ;
/* Other parameter values */
static int hf_sccp_dlr = - 1 ;
static int hf_sccp_slr = - 1 ;
2005-12-13 22:07:09 +00:00
static int hf_sccp_lr = - 1 ;
2002-03-04 22:39:22 +00:00
static int hf_sccp_class = - 1 ;
static int hf_sccp_handling = - 1 ;
static int hf_sccp_more = - 1 ;
static int hf_sccp_rsn = - 1 ;
static int hf_sccp_sequencing_segmenting_ssn = - 1 ;
static int hf_sccp_sequencing_segmenting_rsn = - 1 ;
static int hf_sccp_sequencing_segmenting_more = - 1 ;
static int hf_sccp_credit = - 1 ;
static int hf_sccp_release_cause = - 1 ;
static int hf_sccp_return_cause = - 1 ;
static int hf_sccp_reset_cause = - 1 ;
static int hf_sccp_error_cause = - 1 ;
static int hf_sccp_refusal_cause = - 1 ;
static int hf_sccp_segmentation_first = - 1 ;
static int hf_sccp_segmentation_class = - 1 ;
static int hf_sccp_segmentation_remaining = - 1 ;
static int hf_sccp_segmentation_slr = - 1 ;
static int hf_sccp_hop_counter = - 1 ;
static int hf_sccp_importance = - 1 ;
static int hf_sccp_ansi_isni_mi = - 1 ;
static int hf_sccp_ansi_isni_iri = - 1 ;
static int hf_sccp_ansi_isni_ti = - 1 ;
static int hf_sccp_ansi_isni_netspec = - 1 ;
static int hf_sccp_ansi_isni_counter = - 1 ;
2006-01-19 05:51:59 +00:00
static int hf_sccp_xudt_msg_fragments = - 1 ;
static int hf_sccp_xudt_msg_fragment = - 1 ;
static int hf_sccp_xudt_msg_fragment_overlap = - 1 ;
static int hf_sccp_xudt_msg_fragment_overlap_conflicts = - 1 ;
static int hf_sccp_xudt_msg_fragment_multiple_tails = - 1 ;
static int hf_sccp_xudt_msg_fragment_too_long_fragment = - 1 ;
static int hf_sccp_xudt_msg_fragment_error = - 1 ;
static int hf_sccp_xudt_msg_reassembled_in = - 1 ;
2007-03-03 23:38:35 +00:00
static int hf_sccp_assoc_msg = - 1 ;
static int hf_sccp_assoc_id = - 1 ;
2002-03-04 22:39:22 +00:00
/* Initialize the subtree pointers */
static gint ett_sccp = - 1 ;
static gint ett_sccp_called = - 1 ;
static gint ett_sccp_called_ai = - 1 ;
static gint ett_sccp_called_pc = - 1 ;
static gint ett_sccp_called_gt = - 1 ;
static gint ett_sccp_calling = - 1 ;
static gint ett_sccp_calling_ai = - 1 ;
static gint ett_sccp_calling_pc = - 1 ;
static gint ett_sccp_calling_gt = - 1 ;
static gint ett_sccp_sequencing_segmenting = - 1 ;
static gint ett_sccp_segmentation = - 1 ;
static gint ett_sccp_ansi_isni_routing_control = - 1 ;
2006-01-19 05:51:59 +00:00
static gint ett_sccp_xudt_msg_fragment = - 1 ;
static gint ett_sccp_xudt_msg_fragments = - 1 ;
2007-03-03 23:38:35 +00:00
static gint ett_sccp_assoc = - 1 ;
2008-01-09 22:01:57 +00:00
static gint ett_sccp_digits = - 1 ;
2007-03-03 23:38:35 +00:00
2006-01-19 05:51:59 +00:00
/* Declarations to desegment XUDT Messages */
static gboolean sccp_xudt_desegment = TRUE ;
2007-03-22 22:59:20 +00:00
static gboolean show_key_params = FALSE ;
2007-03-21 00:48:46 +00:00
static int sccp_tap = - 1 ;
2006-01-19 05:51:59 +00:00
static const fragment_items sccp_xudt_msg_frag_items = {
/* Fragment subtrees */
& ett_sccp_xudt_msg_fragment ,
& ett_sccp_xudt_msg_fragments ,
/* Fragment fields */
& hf_sccp_xudt_msg_fragments ,
& hf_sccp_xudt_msg_fragment ,
& hf_sccp_xudt_msg_fragment_overlap ,
& hf_sccp_xudt_msg_fragment_overlap_conflicts ,
& hf_sccp_xudt_msg_fragment_multiple_tails ,
& hf_sccp_xudt_msg_fragment_too_long_fragment ,
& hf_sccp_xudt_msg_fragment_error ,
/* Reassembled in field */
& hf_sccp_xudt_msg_reassembled_in ,
/* Tag */
" SCCP XUDT Message fragments "
} ;
static GHashTable * sccp_xudt_msg_fragment_table = NULL ;
static GHashTable * sccp_xudt_msg_reassembled_table = NULL ;
2007-04-03 19:08:00 +00:00
# define SCCP_USER_DATA 0
# define SCCP_USER_TCAP 1
# define SCCP_USER_RANAP 2
# define SCCP_USER_BSSAP 3
# define SCCP_USER_GSMMAP 4
# define SCCP_USER_CAMEL 5
# define SCCP_USER_INAP 6
typedef struct _sccp_user_t {
guint ni ;
range_t * called_pc ;
range_t * called_ssn ;
guint user ;
gboolean uses_tcap ;
dissector_handle_t * handlep ;
} sccp_user_t ;
static sccp_user_t * sccp_users ;
static guint num_sccp_users ;
static dissector_handle_t data_handle ;
static dissector_handle_t tcap_handle ;
static dissector_handle_t ranap_handle ;
static dissector_handle_t bssap_handle ;
static dissector_handle_t gsmmap_handle ;
static dissector_handle_t camel_handle ;
static dissector_handle_t inap_handle ;
static value_string sccp_users_vals [ ] = {
{ SCCP_USER_DATA , " Data " } ,
{ SCCP_USER_TCAP , " TCAP " } ,
{ SCCP_USER_RANAP , " RANAP " } ,
{ SCCP_USER_BSSAP , " BSSAP " } ,
{ SCCP_USER_GSMMAP , " GSM MAP " } ,
{ SCCP_USER_CAMEL , " CAMEL " } ,
{ SCCP_USER_INAP , " INAP " } ,
{ 0 , NULL }
} ;
2002-03-04 22:39:22 +00:00
2003-12-08 21:36:53 +00:00
/*
* Here are the global variables associated with
* the various user definable characteristics of the dissection
*/
static guint32 sccp_source_pc_global = 0 ;
static gboolean sccp_show_length = FALSE ;
static module_t * sccp_module ;
static heur_dissector_list_t heur_subdissector_list ;
2002-03-04 22:39:22 +00:00
/* Keep track of SSN value of current message so if/when we get to the data
* parameter , we can call appropriate sub - dissector . TODO : can this info
* be stored elsewhere ?
*/
2005-12-14 20:01:21 +00:00
2005-12-13 22:07:09 +00:00
static guint8 message_type = 0 ;
static guint dlr = 0 ;
static guint slr = 0 ;
2002-03-04 22:39:22 +00:00
static dissector_table_t sccp_ssn_dissector_table ;
2006-08-14 08:29:29 +00:00
static emem_tree_t * assocs = NULL ;
2007-03-03 23:38:35 +00:00
static sccp_assoc_info_t * assoc ;
2007-03-27 23:00:55 +00:00
static sccp_msg_info_t * sccp_msg ;
2007-03-21 00:48:46 +00:00
static sccp_assoc_info_t no_assoc = { 0 , 0 , 0 , 0 , 0 , FALSE , FALSE , NULL , NULL , SCCP_PLOAD_NONE , NULL , NULL , NULL } ;
2007-03-03 23:38:35 +00:00
static gboolean trace_sccp = FALSE ;
static guint32 next_assoc_id = 0 ;
2005-12-13 22:07:09 +00:00
2007-03-21 00:48:46 +00:00
static const value_string assoc_protos [ ] = {
{ SCCP_PLOAD_BSSAP , " BSSAP " } ,
{ SCCP_PLOAD_RANAP , " RANAP " } ,
{ 0 , NULL }
} ;
static sccp_assoc_info_t * new_assoc ( guint32 calling , guint32 called ) {
sccp_assoc_info_t * a = se_alloc ( sizeof ( sccp_assoc_info_t ) ) ;
a - > id = next_assoc_id + + ;
a - > calling_dpc = calling ;
a - > called_dpc = called ;
a - > calling_ssn = INVALID_SSN ;
a - > called_ssn = INVALID_SSN ;
a - > has_fw_key = FALSE ;
a - > has_bw_key = FALSE ;
2007-03-22 22:59:20 +00:00
a - > payload = SCCP_PLOAD_NONE ;
2007-03-21 00:48:46 +00:00
a - > calling_party = NULL ;
a - > called_party = NULL ;
a - > extra_info = NULL ;
a - > msgs = NULL ;
2007-03-24 13:46:41 +00:00
return a ;
2007-03-21 00:48:46 +00:00
}
2007-03-27 23:00:55 +00:00
void reset_sccp_assoc ( void ) {
assoc = NULL ;
}
2007-03-22 22:59:20 +00:00
sccp_assoc_info_t * get_sccp_assoc ( packet_info * pinfo , guint offset , guint32 src_lr , guint32 dst_lr , guint msg_type ) {
2006-03-11 15:30:52 +00:00
guint32 opck , dpck ;
2007-03-03 23:38:35 +00:00
address * opc = & ( pinfo - > src ) ;
address * dpc = & ( pinfo - > dst ) ;
2007-03-05 23:50:08 +00:00
guint framenum = pinfo - > fd - > num ;
2007-03-24 13:46:41 +00:00
2007-03-27 23:00:55 +00:00
if ( assoc )
return assoc ;
2007-03-24 13:46:41 +00:00
2007-04-26 07:57:44 +00:00
opck = opc - > type = = AT_SS7PC ? mtp3_pc_hash ( ( const mtp3_addr_pc_t * ) opc - > data ) : g_str_hash ( address_to_str ( opc ) ) ;
dpck = dpc - > type = = AT_SS7PC ? mtp3_pc_hash ( ( const mtp3_addr_pc_t * ) dpc - > data ) : g_str_hash ( address_to_str ( dpc ) ) ;
2007-03-24 13:46:41 +00:00
2007-03-22 22:59:20 +00:00
switch ( msg_type ) {
2007-03-21 00:48:46 +00:00
case SCCP_MSG_TYPE_CR :
{
/* CR contains the opc,dpc,dlr key of backward messages swapped as dpc,opc,slr */
emem_tree_key_t bw_key [ ] = {
{ 1 , & dpck } , { 1 , & opck } , { 1 , & src_lr } , { 0 , NULL }
} ;
2007-07-26 20:05:54 +00:00
2007-03-21 00:48:46 +00:00
if ( ! ( assoc = se_tree_lookup32_array ( assocs , bw_key ) ) & & ! pinfo - > fd - > flags . visited ) {
assoc = new_assoc ( opck , dpck ) ;
se_tree_insert32_array ( assocs , bw_key , assoc ) ;
assoc - > has_bw_key = TRUE ;
}
2007-07-26 20:05:54 +00:00
2007-04-03 19:08:00 +00:00
pinfo - > p2p_dir = P2P_DIR_SENT ;
2007-07-26 20:05:54 +00:00
2007-03-21 00:48:46 +00:00
break ;
2007-01-19 17:25:13 +00:00
}
2007-03-21 00:48:46 +00:00
case SCCP_MSG_TYPE_CC :
{
emem_tree_key_t fw_key [ ] = {
{ 1 , & dpck } , { 1 , & opck } , { 1 , & src_lr } , { 0 , NULL }
} ;
emem_tree_key_t bw_key [ ] = {
{ 1 , & opck } , { 1 , & dpck } , { 1 , & dst_lr } , { 0 , NULL }
} ;
2007-07-26 20:05:54 +00:00
2007-03-21 00:48:46 +00:00
if ( ( assoc = se_tree_lookup32_array ( assocs , bw_key ) ) ) {
goto got_assoc ;
2007-03-24 13:46:41 +00:00
}
2007-03-21 00:48:46 +00:00
if ( ( assoc = se_tree_lookup32_array ( assocs , fw_key ) ) ) {
2007-03-24 13:46:41 +00:00
goto got_assoc ;
2007-03-21 00:48:46 +00:00
}
2007-03-24 13:46:41 +00:00
2007-04-03 19:08:00 +00:00
assoc = new_assoc ( dpck , opck ) ;
2007-03-21 00:48:46 +00:00
got_assoc :
2007-07-26 20:05:54 +00:00
2007-04-03 19:08:00 +00:00
pinfo - > p2p_dir = P2P_DIR_RECV ;
2007-07-26 20:05:54 +00:00
2007-03-21 00:48:46 +00:00
if ( ! pinfo - > fd - > flags . visited & & ! assoc - > has_bw_key ) {
se_tree_insert32_array ( assocs , bw_key , assoc ) ;
assoc - > has_bw_key = TRUE ;
}
2007-03-24 13:46:41 +00:00
2007-03-21 00:48:46 +00:00
if ( ! pinfo - > fd - > flags . visited & & ! assoc - > has_fw_key ) {
se_tree_insert32_array ( assocs , fw_key , assoc ) ;
assoc - > has_fw_key = TRUE ;
}
break ;
}
default :
{
emem_tree_key_t key [ ] = {
{ 1 , & opck } , { 1 , & dpck } , { 1 , & dst_lr } , { 0 , NULL }
} ;
2007-07-26 20:05:54 +00:00
2007-03-21 00:48:46 +00:00
assoc = se_tree_lookup32_array ( assocs , key ) ;
2007-07-26 20:05:54 +00:00
2007-04-03 19:08:00 +00:00
if ( assoc ) {
if ( assoc - > calling_dpc = = dpck ) {
pinfo - > p2p_dir = P2P_DIR_RECV ;
} else {
pinfo - > p2p_dir = P2P_DIR_SENT ;
2007-07-26 20:05:54 +00:00
}
2007-04-03 19:08:00 +00:00
}
2007-07-26 20:05:54 +00:00
2007-03-21 00:48:46 +00:00
break ;
2007-01-19 17:25:13 +00:00
}
2005-12-13 22:07:09 +00:00
}
2007-03-24 13:46:41 +00:00
2007-03-21 00:48:46 +00:00
if ( assoc & & trace_sccp ) {
2007-03-05 23:50:08 +00:00
if ( ! pinfo - > fd - > flags . visited ) {
2007-03-21 00:48:46 +00:00
sccp_msg_info_t * msg = se_alloc ( sizeof ( sccp_msg_info_t ) ) ;
msg - > framenum = framenum ;
msg - > offset = offset ;
2007-03-27 23:00:55 +00:00
msg - > data . co . next = NULL ;
msg - > data . co . assoc = assoc ;
msg - > data . co . label = NULL ;
msg - > data . co . comment = NULL ;
2007-03-22 22:59:20 +00:00
msg - > type = msg_type ;
2007-03-24 13:46:41 +00:00
2007-03-21 00:48:46 +00:00
if ( assoc - > msgs ) {
sccp_msg_info_t * m ;
2007-03-27 23:00:55 +00:00
for ( m = assoc - > msgs ; m - > data . co . next ; m = m - > data . co . next ) ;
m - > data . co . next = msg ;
2007-03-21 00:48:46 +00:00
} else {
assoc - > msgs = msg ;
}
2007-03-24 13:46:41 +00:00
2007-03-21 00:48:46 +00:00
assoc - > curr_msg = msg ;
2007-03-24 13:46:41 +00:00
2007-03-05 23:50:08 +00:00
} else {
2007-03-24 13:46:41 +00:00
2007-03-21 00:48:46 +00:00
sccp_msg_info_t * m ;
2007-03-24 13:46:41 +00:00
2007-03-27 23:00:55 +00:00
for ( m = assoc - > msgs ; m ; m = m - > data . co . next ) {
2007-03-21 00:48:46 +00:00
if ( m - > framenum = = framenum & & m - > offset = = offset ) {
assoc - > curr_msg = m ;
break ;
}
2007-03-05 23:50:08 +00:00
}
}
2007-03-03 23:38:35 +00:00
}
2007-03-24 13:46:41 +00:00
2007-03-21 00:48:46 +00:00
return assoc ? assoc : & no_assoc ;
2005-12-13 22:07:09 +00:00
}
2002-03-04 22:39:22 +00:00
static void
dissect_sccp_unknown_message ( tvbuff_t * message_tvb , proto_tree * sccp_tree )
{
guint32 message_length ;
message_length = tvb_length ( message_tvb ) ;
proto_tree_add_text ( sccp_tree , message_tvb , 0 , message_length ,
" Unknown message (%u byte%s) " ,
message_length , plurality ( message_length , " " , " s " ) ) ;
}
static void
2003-12-18 00:43:48 +00:00
dissect_sccp_unknown_param ( tvbuff_t * tvb , proto_tree * tree , guint8 type , guint length )
2002-03-04 22:39:22 +00:00
{
proto_tree_add_text ( tree , tvb , 0 , length , " Unknown parameter 0x%x (%u byte%s) " ,
type , length , plurality ( length , " " , " s " ) ) ;
}
static void
2007-03-22 22:59:20 +00:00
dissect_sccp_dlr_param ( tvbuff_t * tvb , proto_tree * tree , guint length , packet_info * pinfo )
2002-03-04 22:39:22 +00:00
{
2005-12-13 22:07:09 +00:00
proto_item * lr_item ;
2002-03-04 22:39:22 +00:00
2005-12-13 22:07:09 +00:00
dlr = tvb_get_letoh24 ( tvb , 0 ) ;
proto_tree_add_uint ( tree , hf_sccp_dlr , tvb , 0 , length , dlr ) ;
lr_item = proto_tree_add_uint ( tree , hf_sccp_lr , tvb , 0 , length , dlr ) ;
PROTO_ITEM_SET_HIDDEN ( lr_item ) ;
2007-03-22 22:59:20 +00:00
if ( show_key_params & & check_col ( pinfo - > cinfo , COL_INFO ) )
2007-03-24 13:46:41 +00:00
col_append_fstr ( pinfo - > cinfo , COL_INFO , " DLR=%d " , dlr ) ;
2002-03-04 22:39:22 +00:00
}
static void
2007-03-22 22:59:20 +00:00
dissect_sccp_slr_param ( tvbuff_t * tvb , proto_tree * tree , guint length , packet_info * pinfo )
2002-03-04 22:39:22 +00:00
{
2005-12-13 22:07:09 +00:00
proto_item * lr_item ;
2007-01-19 17:25:13 +00:00
2005-12-13 22:07:09 +00:00
slr = tvb_get_letoh24 ( tvb , 0 ) ;
proto_tree_add_uint ( tree , hf_sccp_slr , tvb , 0 , length , slr ) ;
lr_item = proto_tree_add_uint ( tree , hf_sccp_lr , tvb , 0 , length , slr ) ;
PROTO_ITEM_SET_HIDDEN ( lr_item ) ;
2007-03-22 22:59:20 +00:00
if ( show_key_params & & check_col ( pinfo - > cinfo , COL_INFO ) )
2007-03-24 13:46:41 +00:00
col_append_fstr ( pinfo - > cinfo , COL_INFO , " SLR=%d " , slr ) ;
2002-03-04 22:39:22 +00:00
}
2007-03-27 23:00:55 +00:00
# define is_connectionless(m) \
( m = = SCCP_MSG_TYPE_UDT | | m = = SCCP_MSG_TYPE_UDTS \
| | m = = SCCP_MSG_TYPE_XUDT | | m = = SCCP_MSG_TYPE_XUDTS \
| | m = = SCCP_MSG_TYPE_LUDT | | m = = SCCP_MSG_TYPE_LUDTS )
2008-01-09 22:01:57 +00:00
static proto_item *
2002-03-04 22:39:22 +00:00
dissect_sccp_gt_address_information ( tvbuff_t * tvb , proto_tree * tree ,
2003-12-18 00:43:48 +00:00
guint length , gboolean even_length ,
2002-03-04 22:39:22 +00:00
gboolean called )
{
2003-12-18 00:43:48 +00:00
guint offset = 0 ;
2002-03-04 22:39:22 +00:00
guint8 odd_signal , even_signal = 0x0f ;
2008-05-09 13:59:10 +00:00
proto_item * digits_item , * hidden_item ;
2005-04-28 14:53:41 +00:00
char gt_digits [ GT_MAX_SIGNALS + 1 ] = { 0 } ;
2002-03-04 22:39:22 +00:00
while ( offset < length )
{
odd_signal = tvb_get_guint8 ( tvb , offset ) & GT_ODD_SIGNAL_MASK ;
even_signal = tvb_get_guint8 ( tvb , offset ) & GT_EVEN_SIGNAL_MASK ;
even_signal > > = GT_EVEN_SIGNAL_SHIFT ;
2008-03-01 17:23:39 +00:00
g_strlcat ( gt_digits , val_to_str ( odd_signal , sccp_address_signal_values ,
" Unknown " ) , GT_MAX_SIGNALS + 1 ) ;
2007-01-19 17:25:13 +00:00
2002-03-04 22:39:22 +00:00
/* If the last signal is NOT filler */
if ( offset ! = ( length - 1 ) | | even_length = = TRUE )
2008-03-01 17:23:39 +00:00
g_strlcat ( gt_digits , val_to_str ( even_signal , sccp_address_signal_values ,
" Unknown " ) , GT_MAX_SIGNALS + 1 ) ;
2002-03-04 22:39:22 +00:00
offset + = GT_SIGNAL_LENGTH ;
}
2007-03-27 23:00:55 +00:00
if ( is_connectionless ( message_type ) & & sccp_msg ) {
guint8 * * gt_ptr = called ? & ( sccp_msg - > data . ud . called_gt ) : & ( sccp_msg - > data . ud . calling_gt ) ;
2008-02-09 23:35:28 +00:00
* gt_ptr = ( guint8 * ) ep_strdup ( gt_digits ) ;
2007-03-27 23:00:55 +00:00
}
2008-01-09 22:01:57 +00:00
digits_item = proto_tree_add_string_format ( tree ,
called ? hf_sccp_called_gt_digits
: hf_sccp_calling_gt_digits ,
tvb , 0 , length , gt_digits ,
" Address information (digits): %s " ,
gt_digits ) ;
2008-05-09 13:59:10 +00:00
hidden_item = proto_tree_add_string ( tree , hf_sccp_gt_digits , tvb , 0 , length ,
2008-01-09 22:01:57 +00:00
gt_digits ) ;
2008-05-09 13:59:10 +00:00
PROTO_ITEM_SET_HIDDEN ( hidden_item ) ;
2008-01-09 22:01:57 +00:00
return digits_item ;
2002-03-04 22:39:22 +00:00
}
static void
2003-12-18 00:43:48 +00:00
dissect_sccp_global_title ( tvbuff_t * tvb , proto_tree * tree , guint length ,
2002-03-04 22:39:22 +00:00
guint8 gti , gboolean called )
{
proto_item * gt_item = 0 ;
2008-01-09 22:01:57 +00:00
proto_item * digits_item = 0 ;
2002-03-04 22:39:22 +00:00
proto_tree * gt_tree = 0 ;
2008-01-09 22:01:57 +00:00
proto_tree * digits_tree = 0 ;
2002-03-04 22:39:22 +00:00
tvbuff_t * signals_tvb ;
2003-12-18 00:43:48 +00:00
guint offset = 0 ;
2008-01-09 22:01:57 +00:00
guint8 odd_even , nai = 0 , tt , np = 0 , es ;
2002-03-04 22:39:22 +00:00
gboolean even = TRUE ;
/* Shift GTI to where we can work with it */
gti > > = GTI_SHIFT ;
gt_item = proto_tree_add_text ( tree , tvb , offset , length ,
" Global Title 0x%x (%u byte%s) " ,
gti , length , plurality ( length , " " , " s " ) ) ;
gt_tree = proto_item_add_subtree ( gt_item , called ? ett_sccp_called_gt
: ett_sccp_calling_gt ) ;
/* Decode Transation Type (if present) */
2007-06-13 13:39:05 +00:00
if ( ( gti = = AI_GTI_TT ) | |
( decode_mtp3_standard ! = ANSI_STANDARD & &
( gti = = ITU_AI_GTI_TT_NP_ES | | gti = = ITU_AI_GTI_TT_NP_ES_NAI ) ) | |
( decode_mtp3_standard = = ANSI_STANDARD & & gti = = ANSI_AI_GTI_TT_NP_ES ) ) {
2002-03-04 22:39:22 +00:00
tt = tvb_get_guint8 ( tvb , offset ) ;
proto_tree_add_uint ( gt_tree , called ? hf_sccp_called_gt_tt
: hf_sccp_calling_gt_tt ,
tvb , offset , GT_TT_LENGTH , tt ) ;
offset + = GT_TT_LENGTH ;
}
2007-06-13 13:39:05 +00:00
if ( gti = = AI_GTI_TT ) {
/* Protocol doesn't tell us, so we ASSUME even... */
even = TRUE ;
}
2002-03-04 22:39:22 +00:00
/* Decode Numbering Plan and Encoding Scheme (if present) */
2007-06-13 13:39:05 +00:00
if ( ( decode_mtp3_standard ! = ANSI_STANDARD & &
( gti = = ITU_AI_GTI_TT_NP_ES | | gti = = ITU_AI_GTI_TT_NP_ES_NAI ) ) | |
( decode_mtp3_standard = = ANSI_STANDARD & & gti = = ANSI_AI_GTI_TT_NP_ES ) ) {
2002-03-04 22:39:22 +00:00
np = tvb_get_guint8 ( tvb , offset ) & GT_NP_MASK ;
proto_tree_add_uint ( gt_tree , called ? hf_sccp_called_gt_np
: hf_sccp_calling_gt_np ,
tvb , offset , GT_NP_ES_LENGTH , np ) ;
es = tvb_get_guint8 ( tvb , offset ) & GT_ES_MASK ;
proto_tree_add_uint ( gt_tree , called ? hf_sccp_called_gt_es
: hf_sccp_calling_gt_es ,
tvb , offset , GT_NP_ES_LENGTH , es ) ;
even = ( es = = GT_ES_BCD_EVEN ) ? TRUE : FALSE ;
offset + = GT_NP_ES_LENGTH ;
}
/* Decode Nature of Address Indicator (if present) */
2007-06-13 13:39:05 +00:00
if ( decode_mtp3_standard ! = ANSI_STANDARD & &
( gti = = ITU_AI_GTI_NAI | | gti = = ITU_AI_GTI_TT_NP_ES_NAI ) ) {
/* Decode Odd/Even Indicator (if present) */
if ( gti = = ITU_AI_GTI_NAI ) {
odd_even = tvb_get_guint8 ( tvb , offset ) & GT_OE_MASK ;
proto_tree_add_uint ( gt_tree , called ? hf_sccp_called_gt_oe
: hf_sccp_calling_gt_oe ,
tvb , offset , GT_NAI_LENGTH , odd_even ) ;
even = ( odd_even = = GT_OE_EVEN ) ? TRUE : FALSE ;
}
2002-03-04 22:39:22 +00:00
nai = tvb_get_guint8 ( tvb , offset ) & GT_NAI_MASK ;
proto_tree_add_uint ( gt_tree , called ? hf_sccp_called_gt_nai
: hf_sccp_calling_gt_nai ,
tvb , offset , GT_NAI_LENGTH , nai ) ;
offset + = GT_NAI_LENGTH ;
}
/* Decode address signal(s) */
2003-12-18 00:43:48 +00:00
if ( length < offset )
return ;
2007-01-19 17:25:13 +00:00
2002-03-04 22:39:22 +00:00
signals_tvb = tvb_new_subset ( tvb , offset , ( length - offset ) ,
( length - offset ) ) ;
2008-01-09 22:01:57 +00:00
digits_item = dissect_sccp_gt_address_information ( signals_tvb , gt_tree ,
( length - offset ) ,
even , called ) ;
/* Display the country code (if we can) */
switch ( np > > GT_NP_SHIFT ) {
case GT_NP_ISDN :
case GT_NP_ISDN_MOBILE :
if ( nai = = GT_NAI_INTERNATIONAL_NUM ) {
digits_tree = proto_item_add_subtree ( digits_item ,
ett_sccp_digits ) ;
dissect_e164_cc ( signals_tvb , digits_tree , 0 , TRUE ) ;
}
break ;
case GT_NP_LAND_MOBILE :
digits_tree = proto_item_add_subtree ( digits_item ,
ett_sccp_digits ) ;
2008-03-27 23:09:22 +00:00
dissect_e212_mcc_mnc ( signals_tvb , digits_tree , 0 ) ;
2008-01-09 22:01:57 +00:00
break ;
2008-01-09 21:14:01 +00:00
default :
2008-01-09 22:01:57 +00:00
break ;
2008-01-09 21:14:01 +00:00
}
2002-03-04 22:39:22 +00:00
}
2003-04-10 18:52:15 +00:00
static int
2003-12-18 00:43:48 +00:00
dissect_sccp_3byte_pc ( tvbuff_t * tvb , proto_tree * call_tree , guint offset ,
2007-01-19 17:25:13 +00:00
gboolean called )
2003-04-10 18:52:15 +00:00
{
int * hf_pc ;
2005-08-19 08:36:38 +00:00
if ( decode_mtp3_standard = = ANSI_STANDARD )
2003-04-10 18:52:15 +00:00
{
if ( called )
hf_pc = & hf_sccp_called_ansi_pc ;
else
hf_pc = & hf_sccp_calling_ansi_pc ;
} else /* CHINESE_ITU_STANDARD */ {
if ( called )
hf_pc = & hf_sccp_called_chinese_pc ;
else
hf_pc = & hf_sccp_calling_chinese_pc ;
}
2006-09-14 10:51:44 +00:00
/* create and fill the PC tree */
dissect_mtp3_3byte_pc ( tvb , offset , call_tree ,
called ? ett_sccp_called_pc : ett_sccp_calling_pc ,
* hf_pc ,
called ? hf_sccp_called_pc_network : hf_sccp_calling_pc_network ,
called ? hf_sccp_called_pc_cluster : hf_sccp_calling_pc_cluster ,
called ? hf_sccp_called_pc_member : hf_sccp_calling_pc_member ,
0 , 0 ) ;
return ( offset + ANSI_PC_LENGTH ) ;
2003-04-10 18:52:15 +00:00
}
2002-03-04 22:39:22 +00:00
/* FUNCTION dissect_sccp_called_calling_param():
* Dissect the Calling or Called Party Address parameters .
*
* The boolean ' called ' describes whether this function is decoding a
* called ( TRUE ) or calling ( FALSE ) party address . There is simply too
* much code in this function to have 2 copies of it ( one for called , one
* for calling ) .
*
* NOTE : this function is called even when ( ! tree ) so that we can get
* the SSN and subsequently call subdissectors ( if and when there ' s a data
* parameter ) . Realistically we should put if ( ! tree ) ' s around a lot of the
* code , but I think that would make it unreadable - - and the expense of not
* doing so does not appear to be very high .
*/
static void
dissect_sccp_called_calling_param ( tvbuff_t * tvb , proto_tree * tree ,
2003-12-18 00:43:48 +00:00
guint length , gboolean called )
2002-03-04 22:39:22 +00:00
{
2008-05-09 13:59:10 +00:00
proto_item * call_item = 0 , * call_ai_item = 0 , * item , * hidden_item ;
2003-04-10 18:52:15 +00:00
proto_tree * call_tree = 0 , * call_ai_tree = 0 ;
2003-12-18 00:43:48 +00:00
guint offset ;
2008-02-09 23:35:28 +00:00
guint8 national = 0xFFU , routing_ind , gti , pci , ssni , ssn ;
2002-03-04 22:39:22 +00:00
tvbuff_t * gt_tvb ;
2006-01-31 18:33:56 +00:00
dissector_handle_t ssn_dissector = NULL , tcap_ssn_dissector = NULL ;
const char * ssn_dissector_short_name = NULL ;
const char * tcap_ssn_dissector_short_name = NULL ;
2002-03-04 22:39:22 +00:00
call_item = proto_tree_add_text ( tree , tvb , 0 , length ,
" %s Party address (%u byte%s) " ,
called ? " Called " : " Calling " , length ,
plurality ( length , " " , " s " ) ) ;
call_tree = proto_item_add_subtree ( call_item , called ? ett_sccp_called
: ett_sccp_calling ) ;
call_ai_item = proto_tree_add_text ( call_tree , tvb , 0 ,
ADDRESS_INDICATOR_LENGTH ,
" Address Indicator " ) ;
call_ai_tree = proto_item_add_subtree ( call_ai_item , called ? ett_sccp_called_ai
: ett_sccp_calling_ai ) ;
2005-08-19 08:36:38 +00:00
if ( decode_mtp3_standard = = ANSI_STANDARD )
2002-03-04 22:39:22 +00:00
{
national = tvb_get_guint8 ( tvb , 0 ) & ANSI_NATIONAL_MASK ;
proto_tree_add_uint ( call_ai_tree , called ? hf_sccp_called_national_indicator
: hf_sccp_calling_national_indicator ,
tvb , 0 , ADDRESS_INDICATOR_LENGTH , national ) ;
}
routing_ind = tvb_get_guint8 ( tvb , 0 ) & ROUTING_INDICATOR_MASK ;
proto_tree_add_uint ( call_ai_tree , called ? hf_sccp_called_routing_indicator
: hf_sccp_calling_routing_indicator ,
tvb , 0 , ADDRESS_INDICATOR_LENGTH , routing_ind ) ;
gti = tvb_get_guint8 ( tvb , 0 ) & GTI_MASK ;
2005-08-19 08:36:38 +00:00
if ( decode_mtp3_standard = = ITU_STANDARD | |
decode_mtp3_standard = = CHINESE_ITU_STANDARD | |
2006-04-05 16:03:36 +00:00
decode_mtp3_standard = = JAPAN_STANDARD | |
2003-04-10 18:52:15 +00:00
national = = 0 ) {
2002-03-04 22:39:22 +00:00
proto_tree_add_uint ( call_ai_tree , called ? hf_sccp_called_itu_global_title_indicator
2007-08-15 21:07:01 +00:00
: hf_sccp_calling_itu_global_title_indicator ,
2002-03-04 22:39:22 +00:00
tvb , 0 , ADDRESS_INDICATOR_LENGTH , gti ) ;
ssni = tvb_get_guint8 ( tvb , 0 ) & ITU_SSN_INDICATOR_MASK ;
proto_tree_add_uint ( call_ai_tree , called ? hf_sccp_called_itu_ssn_indicator
: hf_sccp_calling_itu_ssn_indicator ,
tvb , 0 , ADDRESS_INDICATOR_LENGTH , ssni ) ;
pci = tvb_get_guint8 ( tvb , 0 ) & ITU_PC_INDICATOR_MASK ;
proto_tree_add_uint ( call_ai_tree , called ? hf_sccp_called_itu_point_code_indicator
: hf_sccp_calling_itu_point_code_indicator ,
tvb , 0 , ADDRESS_INDICATOR_LENGTH , pci ) ;
offset = ADDRESS_INDICATOR_LENGTH ;
/* Dissect PC (if present) */
if ( pci ) {
2008-09-15 20:17:47 +00:00
if ( decode_mtp3_standard = = ITU_STANDARD | | national = = 0 ) {
2003-04-10 18:52:15 +00:00
2006-04-05 16:03:36 +00:00
proto_tree_add_item ( call_tree , called ? hf_sccp_called_itu_pc
2003-04-10 18:52:15 +00:00
: hf_sccp_calling_itu_pc ,
2006-04-05 16:03:36 +00:00
tvb , offset , ITU_PC_LENGTH , TRUE ) ;
2003-04-10 18:52:15 +00:00
offset + = ITU_PC_LENGTH ;
2006-04-05 16:03:36 +00:00
} else if ( decode_mtp3_standard = = JAPAN_STANDARD ) {
proto_tree_add_item ( call_tree , called ? hf_sccp_called_japan_pc
: hf_sccp_calling_japan_pc ,
tvb , offset , JAPAN_PC_LENGTH , TRUE ) ;
offset + = JAPAN_PC_LENGTH ;
2007-01-19 17:25:13 +00:00
2003-04-10 18:52:15 +00:00
} else /* CHINESE_ITU_STANDARD */ {
offset = dissect_sccp_3byte_pc ( tvb , call_tree , offset , called ) ;
}
2002-03-04 22:39:22 +00:00
}
/* Dissect SSN (if present) */
if ( ssni ) {
ssn = tvb_get_guint8 ( tvb , offset ) ;
2006-12-26 22:27:46 +00:00
if ( called & & assoc )
assoc - > called_ssn = ssn ;
else if ( assoc )
assoc - > calling_ssn = ssn ;
2002-03-04 22:39:22 +00:00
2007-03-27 23:00:55 +00:00
if ( is_connectionless ( message_type ) & & sccp_msg ) {
guint * ssn_ptr = called ? & ( sccp_msg - > data . ud . called_ssn ) : & ( sccp_msg - > data . ud . calling_ssn ) ;
* ssn_ptr = ssn ;
}
2002-03-04 22:39:22 +00:00
proto_tree_add_uint ( call_tree , called ? hf_sccp_called_ssn
: hf_sccp_calling_ssn ,
tvb , offset , ADDRESS_SSN_LENGTH , ssn ) ;
2008-05-09 13:59:10 +00:00
hidden_item = proto_tree_add_uint ( call_tree , hf_sccp_ssn , tvb , offset ,
2008-09-15 20:17:47 +00:00
ADDRESS_SSN_LENGTH , ssn ) ;
PROTO_ITEM_SET_HIDDEN ( hidden_item ) ;
2008-05-09 13:59:10 +00:00
2002-03-04 22:39:22 +00:00
offset + = ADDRESS_SSN_LENGTH ;
2006-01-31 18:33:56 +00:00
2006-04-05 16:03:36 +00:00
/* Get the dissector handle of the dissector registered for this ssn
* And print it ' s name .
*/
ssn_dissector = dissector_get_port_handle ( sccp_ssn_dissector_table , ssn ) ;
2007-01-19 17:25:13 +00:00
2006-04-05 16:03:36 +00:00
if ( ssn_dissector ) {
ssn_dissector_short_name = dissector_handle_get_short_name ( ssn_dissector ) ;
2007-01-19 17:25:13 +00:00
2006-04-05 16:03:36 +00:00
if ( ssn_dissector_short_name ) {
2006-12-26 22:27:46 +00:00
item = proto_tree_add_text ( call_tree , tvb , offset - 1 , ADDRESS_SSN_LENGTH , " Linked to %s " , ssn_dissector_short_name ) ;
2006-04-05 16:03:36 +00:00
PROTO_ITEM_SET_GENERATED ( item ) ;
2007-01-19 17:25:13 +00:00
strcasecmp(), strncasecmp(), g_strcasecmp(), and g_strncasecmp() delenda
est. Use g_ascii_strcasecmp() and g_ascii_strncasecmp(), and supply our
own versions if they're missing from GLib (as is the case with GLib
1.x).
In the code to build the list of named fields for Diameter, don't use
g_strdown(); do our own g_ascii_-style upper-case to lower-case mapping
in the hash function and use g_ascii_strcasecmp() in the compare
function.
We do this because there is no guarantee that toupper(), tolower(), and
functions that use them will, for example, map between "I" and "i" in
all locales; in Turkish locales, for example, there are, in both
upper case and lower case, versions of "i" with and without a dot, and
the upper-case version of "i" is "I"-with-a-dot and the lower-case
version of "I" is "i"-without-a-dot. This causes strings that should
match not to match.
This finishes fixing bug 2010 - an earlier checkin prevented the crash
(as there are other ways to produce the same crash, e.g. a bogus
dictionary.xml file), but didn't fix the case-insensitive string matching.
svn path=/trunk/; revision=23623
2007-11-27 18:52:51 +00:00
if ( g_ascii_strncasecmp ( " TCAP " , ssn_dissector_short_name , 4 ) = = 0 ) {
2006-04-05 16:03:36 +00:00
tcap_ssn_dissector = get_itu_tcap_subdissector ( ssn ) ;
2007-01-19 17:25:13 +00:00
2006-04-05 16:03:36 +00:00
if ( tcap_ssn_dissector ) {
tcap_ssn_dissector_short_name = dissector_handle_get_short_name ( tcap_ssn_dissector ) ;
2006-12-26 22:27:46 +00:00
proto_item_append_text ( item , " , TCAP SSN linked to %s " , tcap_ssn_dissector_short_name ) ;
2006-04-05 16:03:36 +00:00
}
}
} /* short name */
} /* ssn_dissector */
} /* ssni */
2002-03-04 22:39:22 +00:00
if ( ! tree )
return ; /* got SSN, that's all we need here... */
/* Dissect GT (if present) */
if ( gti ! = AI_GTI_NO_GT ) {
2003-12-18 00:43:48 +00:00
if ( length < offset )
2007-01-19 17:25:13 +00:00
return ;
2002-03-04 22:39:22 +00:00
gt_tvb = tvb_new_subset ( tvb , offset , ( length - offset ) ,
( length - offset ) ) ;
2003-12-18 00:43:48 +00:00
dissect_sccp_global_title ( gt_tvb , call_tree , ( length - offset ) , gti ,
2002-03-04 22:39:22 +00:00
called ) ;
}
2005-08-19 08:36:38 +00:00
} else if ( decode_mtp3_standard = = ANSI_STANDARD ) {
2002-03-04 22:39:22 +00:00
proto_tree_add_uint ( call_ai_tree , called ? hf_sccp_called_ansi_global_title_indicator
: hf_sccp_calling_ansi_global_title_indicator ,
tvb , 0 , ADDRESS_INDICATOR_LENGTH , gti ) ;
pci = tvb_get_guint8 ( tvb , 0 ) & ANSI_PC_INDICATOR_MASK ;
proto_tree_add_uint ( call_ai_tree , called ? hf_sccp_called_ansi_point_code_indicator
: hf_sccp_calling_ansi_point_code_indicator ,
tvb , 0 , ADDRESS_INDICATOR_LENGTH , pci ) ;
ssni = tvb_get_guint8 ( tvb , 0 ) & ANSI_SSN_INDICATOR_MASK ;
proto_tree_add_uint ( call_ai_tree , called ? hf_sccp_called_ansi_ssn_indicator
: hf_sccp_calling_ansi_ssn_indicator ,
tvb , 0 , ADDRESS_INDICATOR_LENGTH , ssni ) ;
offset = ADDRESS_INDICATOR_LENGTH ;
/* Dissect SSN (if present) */
if ( ssni ) {
ssn = tvb_get_guint8 ( tvb , offset ) ;
2006-12-26 22:27:46 +00:00
if ( called & & assoc )
assoc - > called_ssn = ssn ;
else if ( assoc )
assoc - > calling_ssn = ssn ;
2002-03-04 22:39:22 +00:00
2007-03-27 23:00:55 +00:00
if ( is_connectionless ( message_type ) & & sccp_msg ) {
guint * ssn_ptr = called ? & ( sccp_msg - > data . ud . called_ssn ) : & ( sccp_msg - > data . ud . calling_ssn ) ;
* ssn_ptr = ssn ;
}
proto_tree_add_uint ( call_tree , called ? hf_sccp_called_ssn
2002-03-04 22:39:22 +00:00
: hf_sccp_calling_ssn ,
tvb , offset , ADDRESS_SSN_LENGTH , ssn ) ;
2008-05-09 13:59:10 +00:00
hidden_item = proto_tree_add_uint ( call_tree , hf_sccp_ssn , tvb , offset ,
2002-03-04 22:39:22 +00:00
ADDRESS_SSN_LENGTH , ssn ) ;
2008-09-15 20:17:47 +00:00
PROTO_ITEM_SET_HIDDEN ( hidden_item ) ;
2008-05-09 13:59:10 +00:00
2002-03-04 22:39:22 +00:00
offset + = ADDRESS_SSN_LENGTH ;
}
if ( ! tree )
return ; /* got SSN, that's all we need here... */
/* Dissect PC (if present) */
if ( pci ) {
2003-04-10 18:52:15 +00:00
offset = dissect_sccp_3byte_pc ( tvb , call_tree , offset , called ) ;
2002-03-04 22:39:22 +00:00
}
/* Dissect GT (if present) */
if ( gti ! = AI_GTI_NO_GT ) {
2003-12-18 00:43:48 +00:00
if ( length < offset )
2007-01-19 17:25:13 +00:00
return ;
2002-03-04 22:39:22 +00:00
gt_tvb = tvb_new_subset ( tvb , offset , ( length - offset ) ,
( length - offset ) ) ;
2003-12-18 00:43:48 +00:00
dissect_sccp_global_title ( gt_tvb , call_tree , ( length - offset ) , gti ,
2002-03-04 22:39:22 +00:00
called ) ;
}
}
}
static void
2003-12-18 00:43:48 +00:00
dissect_sccp_called_param ( tvbuff_t * tvb , proto_tree * tree , guint length )
2002-03-04 22:39:22 +00:00
{
dissect_sccp_called_calling_param ( tvb , tree , length , TRUE ) ;
}
static void
2003-12-18 00:43:48 +00:00
dissect_sccp_calling_param ( tvbuff_t * tvb , proto_tree * tree , guint length )
2002-03-04 22:39:22 +00:00
{
dissect_sccp_called_calling_param ( tvb , tree , length , FALSE ) ;
}
static void
2003-12-18 00:43:48 +00:00
dissect_sccp_class_param ( tvbuff_t * tvb , proto_tree * tree , guint length )
2002-03-04 22:39:22 +00:00
{
guint8 class , handling ;
class = tvb_get_guint8 ( tvb , 0 ) & CLASS_CLASS_MASK ;
handling = tvb_get_guint8 ( tvb , 0 ) & CLASS_SPARE_HANDLING_MASK ;
proto_tree_add_uint ( tree , hf_sccp_class , tvb , 0 , length , class ) ;
if ( class = = 0 | | class = = 1 )
proto_tree_add_uint ( tree , hf_sccp_handling , tvb , 0 , length , handling ) ;
}
static void
2003-12-18 00:43:48 +00:00
dissect_sccp_segmenting_reassembling_param ( tvbuff_t * tvb , proto_tree * tree , guint length )
2002-03-04 22:39:22 +00:00
{
2006-02-22 16:25:29 +00:00
proto_tree_add_item ( tree , hf_sccp_more , tvb , 0 , length , FALSE ) ;
2002-03-04 22:39:22 +00:00
}
static void
2003-12-18 00:43:48 +00:00
dissect_sccp_receive_sequence_number_param ( tvbuff_t * tvb , proto_tree * tree , guint length )
2002-03-04 22:39:22 +00:00
{
guint8 rsn ;
rsn = tvb_get_guint8 ( tvb , 0 ) > > 1 ;
proto_tree_add_uint ( tree , hf_sccp_rsn , tvb , 0 , length , rsn ) ;
}
static void
2003-12-18 00:43:48 +00:00
dissect_sccp_sequencing_segmenting_param ( tvbuff_t * tvb , proto_tree * tree , guint length )
2002-03-04 22:39:22 +00:00
{
guint8 rsn , ssn , more ;
proto_item * param_item ;
proto_tree * param_tree ;
ssn = tvb_get_guint8 ( tvb , 0 ) > > 1 ;
rsn = tvb_get_guint8 ( tvb , SEQUENCING_SEGMENTING_SSN_LENGTH ) > > 1 ;
more = tvb_get_guint8 ( tvb , SEQUENCING_SEGMENTING_SSN_LENGTH ) & SEQUENCING_SEGMENTING_MORE_MASK ;
param_item = proto_tree_add_text ( tree , tvb , 0 , length ,
val_to_str ( PARAMETER_SEQUENCING_SEGMENTING ,
sccp_parameter_values , " Unknown " ) ) ;
param_tree = proto_item_add_subtree ( param_item ,
ett_sccp_sequencing_segmenting ) ;
proto_tree_add_uint ( param_tree , hf_sccp_sequencing_segmenting_ssn , tvb , 0 ,
SEQUENCING_SEGMENTING_SSN_LENGTH , ssn ) ;
proto_tree_add_uint ( param_tree , hf_sccp_sequencing_segmenting_rsn , tvb ,
SEQUENCING_SEGMENTING_SSN_LENGTH ,
SEQUENCING_SEGMENTING_RSN_LENGTH , rsn ) ;
proto_tree_add_uint ( param_tree , hf_sccp_sequencing_segmenting_more , tvb ,
SEQUENCING_SEGMENTING_SSN_LENGTH ,
SEQUENCING_SEGMENTING_RSN_LENGTH , more ) ;
}
static void
2003-12-18 00:43:48 +00:00
dissect_sccp_credit_param ( tvbuff_t * tvb , proto_tree * tree , guint length )
2002-03-04 22:39:22 +00:00
{
guint8 credit ;
credit = tvb_get_guint8 ( tvb , 0 ) ;
proto_tree_add_uint ( tree , hf_sccp_credit , tvb , 0 , length , credit ) ;
}
static void
2007-03-22 22:59:20 +00:00
dissect_sccp_release_cause_param ( tvbuff_t * tvb , proto_tree * tree , guint length , packet_info * pinfo )
2002-03-04 22:39:22 +00:00
{
guint8 cause ;
cause = tvb_get_guint8 ( tvb , 0 ) ;
proto_tree_add_uint ( tree , hf_sccp_release_cause , tvb , 0 , length , cause ) ;
2007-03-22 22:59:20 +00:00
if ( show_key_params & & check_col ( pinfo - > cinfo , COL_INFO ) )
col_append_fstr ( pinfo - > cinfo , COL_INFO , " Cause=%d " , cause ) ;
2002-03-04 22:39:22 +00:00
}
static void
2007-03-22 22:59:20 +00:00
dissect_sccp_return_cause_param ( tvbuff_t * tvb , proto_tree * tree , guint length , packet_info * pinfo )
2002-03-04 22:39:22 +00:00
{
guint8 cause ;
cause = tvb_get_guint8 ( tvb , 0 ) ;
proto_tree_add_uint ( tree , hf_sccp_return_cause , tvb , 0 , length , cause ) ;
2007-03-22 22:59:20 +00:00
if ( show_key_params & & check_col ( pinfo - > cinfo , COL_INFO ) )
col_append_fstr ( pinfo - > cinfo , COL_INFO , " Cause=%d " , cause ) ;
2002-03-04 22:39:22 +00:00
}
static void
2007-03-22 22:59:20 +00:00
dissect_sccp_reset_cause_param ( tvbuff_t * tvb , proto_tree * tree , guint length , packet_info * pinfo )
2002-03-04 22:39:22 +00:00
{
guint8 cause ;
cause = tvb_get_guint8 ( tvb , 0 ) ;
proto_tree_add_uint ( tree , hf_sccp_reset_cause , tvb , 0 , length , cause ) ;
2007-03-22 22:59:20 +00:00
if ( show_key_params & & check_col ( pinfo - > cinfo , COL_INFO ) )
col_append_fstr ( pinfo - > cinfo , COL_INFO , " Cause=%d " , cause ) ;
2002-03-04 22:39:22 +00:00
}
static void
2007-03-22 22:59:20 +00:00
dissect_sccp_error_cause_param ( tvbuff_t * tvb , proto_tree * tree , guint length , packet_info * pinfo )
2002-03-04 22:39:22 +00:00
{
guint8 cause ;
cause = tvb_get_guint8 ( tvb , 0 ) ;
proto_tree_add_uint ( tree , hf_sccp_error_cause , tvb , 0 , length , cause ) ;
2007-03-22 22:59:20 +00:00
if ( show_key_params & & check_col ( pinfo - > cinfo , COL_INFO ) )
col_append_fstr ( pinfo - > cinfo , COL_INFO , " Cause=%d " , cause ) ;
2002-03-04 22:39:22 +00:00
}
static void
2007-03-22 22:59:20 +00:00
dissect_sccp_refusal_cause_param ( tvbuff_t * tvb , proto_tree * tree , guint length , packet_info * pinfo )
2002-03-04 22:39:22 +00:00
{
guint8 cause ;
cause = tvb_get_guint8 ( tvb , 0 ) ;
proto_tree_add_uint ( tree , hf_sccp_refusal_cause , tvb , 0 , length , cause ) ;
2007-03-22 22:59:20 +00:00
if ( show_key_params & & check_col ( pinfo - > cinfo , COL_INFO ) )
col_append_fstr ( pinfo - > cinfo , COL_INFO , " Cause=%d " , cause ) ;
2002-03-04 22:39:22 +00:00
}
2007-04-03 19:08:00 +00:00
2002-03-04 22:39:22 +00:00
/* This function is used for both data and long data (ITU only) parameters */
static void
2003-04-19 20:13:23 +00:00
dissect_sccp_data_param ( tvbuff_t * tvb , packet_info * pinfo , proto_tree * tree )
2002-03-04 22:39:22 +00:00
{
2007-03-21 00:48:46 +00:00
guint8 ssn = INVALID_SSN ;
guint8 other_ssn = INVALID_SSN ;
2007-04-03 19:08:00 +00:00
const mtp3_addr_pc_t * dpc ;
const mtp3_addr_pc_t * opc ;
2007-07-26 20:05:54 +00:00
2007-04-23 10:59:26 +00:00
if ( trace_sccp & & assoc & & assoc ! = & no_assoc ) {
2007-12-30 00:02:25 +00:00
pinfo - > sccp_info = assoc - > curr_msg ;
2007-04-23 10:59:26 +00:00
} else {
2007-12-30 00:02:25 +00:00
pinfo - > sccp_info = NULL ;
2007-04-23 10:59:26 +00:00
}
2007-03-24 13:46:41 +00:00
2007-04-23 10:59:26 +00:00
switch ( pinfo - > p2p_dir ) {
case P2P_DIR_SENT :
ssn = assoc - > calling_ssn ;
2007-11-24 15:43:39 +00:00
other_ssn = assoc - > called_ssn ;
2007-04-23 10:59:26 +00:00
dpc = ( const mtp3_addr_pc_t * ) pinfo - > dst . data ;
opc = ( const mtp3_addr_pc_t * ) pinfo - > src . data ;
break ;
case P2P_DIR_RECV :
ssn = assoc - > called_ssn ;
2007-11-24 15:43:39 +00:00
other_ssn = assoc - > calling_ssn ;
2007-04-23 10:59:26 +00:00
dpc = ( const mtp3_addr_pc_t * ) pinfo - > src . data ;
opc = ( const mtp3_addr_pc_t * ) pinfo - > dst . data ;
break ;
default :
ssn = assoc - > called_ssn ;
other_ssn = assoc - > calling_ssn ;
dpc = ( const mtp3_addr_pc_t * ) pinfo - > dst . data ;
opc = ( const mtp3_addr_pc_t * ) pinfo - > src . data ;
break ;
}
2007-04-03 19:08:00 +00:00
2007-07-26 20:05:54 +00:00
2007-04-03 19:08:00 +00:00
if ( num_sccp_users & & pinfo - > src . type = = AT_SS7PC ) {
guint i ;
dissector_handle_t handle = NULL ;
gboolean uses_tcap = FALSE ;
2007-07-26 20:05:54 +00:00
2007-04-03 19:08:00 +00:00
for ( i = 0 ; i < num_sccp_users ; i + + ) {
sccp_user_t * u = & ( sccp_users [ i ] ) ;
2007-07-26 20:05:54 +00:00
2007-04-03 19:08:00 +00:00
if ( dpc - > ni ! = u - > ni ) continue ;
2007-07-26 20:05:54 +00:00
if ( value_is_in_range ( u - > called_ssn , ssn ) & & value_is_in_range ( u - > called_pc , dpc - > pc ) ) {
2007-04-03 19:08:00 +00:00
handle = * ( u - > handlep ) ;
uses_tcap = u - > uses_tcap ;
break ;
2007-07-26 20:05:54 +00:00
} else if ( value_is_in_range ( u - > called_ssn , other_ssn ) & & value_is_in_range ( u - > called_pc , opc - > pc ) ) {
2007-04-03 19:08:00 +00:00
handle = * ( u - > handlep ) ;
uses_tcap = u - > uses_tcap ;
break ;
2007-03-21 00:48:46 +00:00
}
2007-04-03 19:08:00 +00:00
}
2007-03-24 13:46:41 +00:00
2007-04-03 19:08:00 +00:00
if ( handle ) {
if ( uses_tcap ) {
call_tcap_dissector ( handle , tvb , pinfo , tree ) ;
} else {
call_dissector ( handle , tvb , pinfo , tree ) ;
}
return ;
}
2007-03-24 13:46:41 +00:00
2007-04-03 19:08:00 +00:00
}
2007-07-26 20:05:54 +00:00
2006-12-26 22:27:46 +00:00
if ( ssn ! = INVALID_SSN & & dissector_try_port ( sccp_ssn_dissector_table , ssn , tvb , pinfo , tree ) ) {
2007-03-21 00:48:46 +00:00
return ;
2006-12-26 22:27:46 +00:00
}
2007-01-19 17:25:13 +00:00
2006-12-26 22:27:46 +00:00
if ( other_ssn ! = INVALID_SSN & & dissector_try_port ( sccp_ssn_dissector_table , other_ssn , tvb , pinfo , tree ) ) {
2007-03-21 00:48:46 +00:00
return ;
2005-12-13 22:07:09 +00:00
}
2007-01-19 17:25:13 +00:00
2003-10-22 20:12:02 +00:00
/* try heuristic subdissector list to see if there are any takers */
2005-12-13 22:07:09 +00:00
if ( dissector_try_heuristic ( heur_subdissector_list , tvb , pinfo , tree ) ) {
2007-03-21 00:48:46 +00:00
return ;
2003-10-22 20:12:02 +00:00
}
2002-03-04 22:39:22 +00:00
/* No sub-dissection occured, treat it as raw data */
2003-04-19 20:13:23 +00:00
call_dissector ( data_handle , tvb , pinfo , tree ) ;
2007-03-05 23:50:08 +00:00
2002-03-04 22:39:22 +00:00
}
static void
2003-12-18 00:43:48 +00:00
dissect_sccp_segmentation_param ( tvbuff_t * tvb , proto_tree * tree , guint length )
2002-03-04 22:39:22 +00:00
{
guint8 first , class , remaining ;
2008-06-26 00:16:58 +00:00
guint32 slrx ;
2002-03-04 22:39:22 +00:00
proto_item * param_item ;
proto_tree * param_tree ;
first = tvb_get_guint8 ( tvb , 0 ) & SEGMENTATION_FIRST_SEGMENT_MASK ;
class = tvb_get_guint8 ( tvb , 0 ) & SEGMENTATION_CLASS_MASK ;
remaining = tvb_get_guint8 ( tvb , 0 ) & SEGMENTATION_REMAINING_MASK ;
2008-06-26 00:16:58 +00:00
slrx = tvb_get_letoh24 ( tvb , 1 ) ;
2002-03-04 22:39:22 +00:00
param_item = proto_tree_add_text ( tree , tvb , 0 , length ,
val_to_str ( PARAMETER_SEGMENTATION ,
sccp_parameter_values , " Unknown " ) ) ;
param_tree = proto_item_add_subtree ( param_item , ett_sccp_segmentation ) ;
2008-09-19 12:17:32 +00:00
proto_tree_add_uint ( param_tree , hf_sccp_segmentation_first , tvb , 0 , 1 , first ) ;
proto_tree_add_uint ( param_tree , hf_sccp_segmentation_class , tvb , 0 , 1 , class ) ;
proto_tree_add_uint ( param_tree , hf_sccp_segmentation_remaining , tvb , 0 , 1 ,
remaining ) ;
proto_tree_add_uint ( param_tree , hf_sccp_segmentation_slr , tvb , 1 , length - 1 ,
2008-06-26 00:16:58 +00:00
slrx ) ;
2002-03-04 22:39:22 +00:00
}
static void
2003-12-18 00:43:48 +00:00
dissect_sccp_hop_counter_param ( tvbuff_t * tvb , proto_tree * tree , guint length )
2002-03-04 22:39:22 +00:00
{
guint8 hops ;
hops = tvb_get_guint8 ( tvb , 0 ) ;
proto_tree_add_uint ( tree , hf_sccp_hop_counter , tvb , 0 , length , hops ) ;
}
static void
2003-12-18 00:43:48 +00:00
dissect_sccp_importance_param ( tvbuff_t * tvb , proto_tree * tree , guint length )
2002-03-04 22:39:22 +00:00
{
guint8 importance ;
importance = tvb_get_guint8 ( tvb , 0 ) & IMPORTANCE_IMPORTANCE_MASK ;
proto_tree_add_uint ( tree , hf_sccp_importance , tvb , 0 , length , importance ) ;
}
static void
2003-12-18 00:43:48 +00:00
dissect_sccp_isni_param ( tvbuff_t * tvb , proto_tree * tree , guint length )
2002-03-04 22:39:22 +00:00
{
guint8 mi , iri , ti , network , netspec ;
2003-12-18 00:43:48 +00:00
guint offset = 0 ;
2002-03-04 22:39:22 +00:00
proto_item * param_item ;
proto_tree * param_tree ;
/* Create a subtree for ISNI Routing Control */
param_item = proto_tree_add_text ( tree , tvb , offset , ANSI_ISNI_ROUTING_CONTROL_LENGTH ,
" ISNI Routing Control " ) ;
param_tree = proto_item_add_subtree ( param_item ,
ett_sccp_ansi_isni_routing_control ) ;
mi = tvb_get_guint8 ( tvb , offset ) & ANSI_ISNI_MI_MASK ;
proto_tree_add_uint ( param_tree , hf_sccp_ansi_isni_mi , tvb , offset ,
ANSI_ISNI_ROUTING_CONTROL_LENGTH , mi ) ;
iri = tvb_get_guint8 ( tvb , offset ) & ANSI_ISNI_IRI_MASK ;
proto_tree_add_uint ( param_tree , hf_sccp_ansi_isni_iri , tvb , offset ,
ANSI_ISNI_ROUTING_CONTROL_LENGTH , iri ) ;
ti = tvb_get_guint8 ( tvb , offset ) & ANSI_ISNI_TI_MASK ;
proto_tree_add_uint ( param_tree , hf_sccp_ansi_isni_ti , tvb , offset ,
ANSI_ISNI_ROUTING_CONTROL_LENGTH , ti ) ;
2007-08-15 21:07:01 +00:00
proto_tree_add_item ( param_tree , hf_sccp_ansi_isni_counter , tvb , offset ,
ANSI_ISNI_ROUTING_CONTROL_LENGTH , TRUE ) ;
2002-03-04 22:39:22 +00:00
offset + = ANSI_ISNI_ROUTING_CONTROL_LENGTH ;
if ( ( ti > > ANSI_ISNI_TI_SHIFT ) = = ANSI_ISNI_TYPE_1 ) {
netspec = tvb_get_guint8 ( tvb , offset ) & ANSI_ISNI_NETSPEC_MASK ;
proto_tree_add_uint ( param_tree , hf_sccp_ansi_isni_netspec , tvb , offset ,
ANSI_ISNI_ROUTING_CONTROL_LENGTH , ti ) ;
offset + = ANSI_ISNI_ROUTING_CONTROL_LENGTH ;
}
while ( offset < length ) {
network = tvb_get_guint8 ( tvb , offset ) ;
proto_tree_add_text ( tree , tvb , offset , ANSI_NCM_LENGTH ,
" Network ID network: %d " , network ) ;
offset + + ;
network = tvb_get_guint8 ( tvb , offset ) ;
proto_tree_add_text ( tree , tvb , offset , ANSI_NCM_LENGTH ,
" Network ID cluster: %d " , network ) ;
offset + + ;
}
}
/* FUNCTION dissect_sccp_parameter():
* Dissect a parameter given its type , offset into tvb , and length .
*/
static guint16
dissect_sccp_parameter ( tvbuff_t * tvb , packet_info * pinfo , proto_tree * sccp_tree ,
2003-03-21 23:05:25 +00:00
proto_tree * tree , guint8 parameter_type , guint16 offset ,
2002-03-04 22:39:22 +00:00
guint16 parameter_length )
{
tvbuff_t * parameter_tvb ;
switch ( parameter_type ) {
case PARAMETER_CALLED_PARTY_ADDRESS :
case PARAMETER_CALLING_PARTY_ADDRESS :
case PARAMETER_DATA :
case PARAMETER_LONG_DATA :
2005-12-13 22:07:09 +00:00
case PARAMETER_SOURCE_LOCAL_REFERENCE :
case PARAMETER_DESTINATION_LOCAL_REFERENCE :
2007-03-22 22:59:20 +00:00
case PARAMETER_RELEASE_CAUSE :
case PARAMETER_RETURN_CAUSE :
case PARAMETER_RESET_CAUSE :
case PARAMETER_ERROR_CAUSE :
case PARAMETER_REFUSAL_CAUSE :
2007-01-19 17:25:13 +00:00
2002-03-04 22:39:22 +00:00
/* These parameters must be dissected even if !sccp_tree (so that
2006-03-11 15:30:52 +00:00
* assoc information can be created ) .
2002-03-04 22:39:22 +00:00
*/
break ;
default :
2007-03-21 00:48:46 +00:00
if ( ! sccp_tree ) return ( parameter_length ) ;
2002-03-04 22:39:22 +00:00
}
parameter_tvb = tvb_new_subset ( tvb , offset , parameter_length , parameter_length ) ;
switch ( parameter_type ) {
case PARAMETER_END_OF_OPTIONAL_PARAMETERS :
proto_tree_add_text ( sccp_tree , tvb , offset , parameter_length ,
" End of Optional " ) ;
break ;
case PARAMETER_DESTINATION_LOCAL_REFERENCE :
2007-03-22 22:59:20 +00:00
dissect_sccp_dlr_param ( parameter_tvb , sccp_tree , parameter_length , pinfo ) ;
2002-03-04 22:39:22 +00:00
break ;
case PARAMETER_SOURCE_LOCAL_REFERENCE :
2007-03-22 22:59:20 +00:00
dissect_sccp_slr_param ( parameter_tvb , sccp_tree , parameter_length , pinfo ) ;
2002-03-04 22:39:22 +00:00
break ;
case PARAMETER_CALLED_PARTY_ADDRESS :
2003-12-18 00:43:48 +00:00
dissect_sccp_called_param ( parameter_tvb , sccp_tree , parameter_length ) ;
2002-03-04 22:39:22 +00:00
break ;
case PARAMETER_CALLING_PARTY_ADDRESS :
2003-12-18 00:43:48 +00:00
dissect_sccp_calling_param ( parameter_tvb , sccp_tree , parameter_length ) ;
2002-03-04 22:39:22 +00:00
break ;
case PARAMETER_CLASS :
2003-12-18 00:43:48 +00:00
dissect_sccp_class_param ( parameter_tvb , sccp_tree , parameter_length ) ;
2002-03-04 22:39:22 +00:00
break ;
case PARAMETER_SEGMENTING_REASSEMBLING :
dissect_sccp_segmenting_reassembling_param ( parameter_tvb , sccp_tree ,
2003-12-18 00:43:48 +00:00
parameter_length ) ;
2002-03-04 22:39:22 +00:00
break ;
case PARAMETER_RECEIVE_SEQUENCE_NUMBER :
dissect_sccp_receive_sequence_number_param ( parameter_tvb , sccp_tree ,
2003-12-18 00:43:48 +00:00
parameter_length ) ;
2002-03-04 22:39:22 +00:00
break ;
case PARAMETER_SEQUENCING_SEGMENTING :
dissect_sccp_sequencing_segmenting_param ( parameter_tvb , sccp_tree ,
2003-12-18 00:43:48 +00:00
parameter_length ) ;
2002-03-04 22:39:22 +00:00
break ;
case PARAMETER_CREDIT :
2003-12-18 00:43:48 +00:00
dissect_sccp_credit_param ( parameter_tvb , sccp_tree , parameter_length ) ;
2002-03-04 22:39:22 +00:00
break ;
case PARAMETER_RELEASE_CAUSE :
2007-03-22 22:59:20 +00:00
dissect_sccp_release_cause_param ( parameter_tvb , sccp_tree , parameter_length , pinfo ) ;
2002-03-04 22:39:22 +00:00
break ;
case PARAMETER_RETURN_CAUSE :
2007-03-22 22:59:20 +00:00
dissect_sccp_return_cause_param ( parameter_tvb , sccp_tree , parameter_length , pinfo ) ;
2002-03-04 22:39:22 +00:00
break ;
case PARAMETER_RESET_CAUSE :
2007-03-22 22:59:20 +00:00
dissect_sccp_reset_cause_param ( parameter_tvb , sccp_tree , parameter_length , pinfo ) ;
2002-03-04 22:39:22 +00:00
break ;
case PARAMETER_ERROR_CAUSE :
2007-03-22 22:59:20 +00:00
dissect_sccp_error_cause_param ( parameter_tvb , sccp_tree , parameter_length , pinfo ) ;
2002-03-04 22:39:22 +00:00
break ;
case PARAMETER_REFUSAL_CAUSE :
2007-03-22 22:59:20 +00:00
dissect_sccp_refusal_cause_param ( parameter_tvb , sccp_tree , parameter_length , pinfo ) ;
2002-03-04 22:39:22 +00:00
break ;
case PARAMETER_DATA :
2003-04-19 20:13:23 +00:00
dissect_sccp_data_param ( parameter_tvb , pinfo , tree ) ;
2002-03-04 22:39:22 +00:00
/* TODO? Re-adjust length of SCCP item since it may be sub-dissected */
/* sccp_length = proto_item_get_len(sccp_item);
* sccp_length - = parameter_length ;
* proto_item_set_len ( sccp_item , sccp_length ) ;
*/
break ;
case PARAMETER_SEGMENTATION :
2007-12-30 00:02:25 +00:00
dissect_sccp_segmentation_param ( parameter_tvb , sccp_tree , parameter_length ) ;
2002-03-04 22:39:22 +00:00
break ;
case PARAMETER_HOP_COUNTER :
2007-12-30 00:02:25 +00:00
dissect_sccp_hop_counter_param ( parameter_tvb , sccp_tree , parameter_length ) ;
2002-03-04 22:39:22 +00:00
break ;
case PARAMETER_IMPORTANCE :
2005-08-19 08:36:38 +00:00
if ( decode_mtp3_standard ! = ANSI_STANDARD )
2007-12-30 00:02:25 +00:00
dissect_sccp_importance_param ( parameter_tvb , sccp_tree , parameter_length ) ;
2002-03-04 22:39:22 +00:00
else
2007-12-30 00:02:25 +00:00
dissect_sccp_unknown_param ( parameter_tvb , sccp_tree , parameter_type ,
2002-03-04 22:39:22 +00:00
parameter_length ) ;
break ;
case PARAMETER_LONG_DATA :
2005-08-19 08:36:38 +00:00
if ( decode_mtp3_standard ! = ANSI_STANDARD )
2007-12-30 00:02:25 +00:00
dissect_sccp_data_param ( parameter_tvb , pinfo , tree ) ;
2002-03-04 22:39:22 +00:00
else
2007-12-30 00:02:25 +00:00
dissect_sccp_unknown_param ( parameter_tvb , sccp_tree , parameter_type ,
2002-03-04 22:39:22 +00:00
parameter_length ) ;
break ;
case PARAMETER_ISNI :
2005-08-19 08:36:38 +00:00
if ( decode_mtp3_standard ! = ANSI_STANDARD )
2007-12-30 00:02:25 +00:00
dissect_sccp_unknown_param ( parameter_tvb , sccp_tree , parameter_type ,
2002-03-04 22:39:22 +00:00
parameter_length ) ;
2003-04-10 18:52:15 +00:00
else
2007-12-30 00:02:25 +00:00
dissect_sccp_isni_param ( parameter_tvb , sccp_tree , parameter_length ) ;
2002-03-04 22:39:22 +00:00
break ;
default :
2007-12-30 00:02:25 +00:00
dissect_sccp_unknown_param ( parameter_tvb , sccp_tree , parameter_type ,
2002-03-04 22:39:22 +00:00
parameter_length ) ;
break ;
}
return ( parameter_length ) ;
}
/* FUNCTION dissect_sccp_variable_parameter():
* Dissect a variable parameter given its type and offset into tvb . Length
* of the parameter is gotten from tvb [ 0 ] .
* Length returned is sum of ( length + parameter ) .
*/
static guint16
dissect_sccp_variable_parameter ( tvbuff_t * tvb , packet_info * pinfo ,
proto_tree * sccp_tree , proto_tree * tree ,
2003-03-21 23:05:25 +00:00
guint8 parameter_type , guint16 offset )
2002-03-04 22:39:22 +00:00
{
guint16 parameter_length ;
guint8 length_length ;
if ( parameter_type ! = PARAMETER_LONG_DATA )
{
parameter_length = tvb_get_guint8 ( tvb , offset ) ;
length_length = PARAMETER_LENGTH_LENGTH ;
}
else
{
/* Long data parameter has 16 bit length */
2003-03-21 23:05:25 +00:00
parameter_length = tvb_get_letohs ( tvb , offset ) ;
2002-03-04 22:39:22 +00:00
length_length = PARAMETER_LONG_DATA_LENGTH_LENGTH ;
}
2007-01-19 17:25:13 +00:00
if ( sccp_tree & & sccp_show_length )
2003-12-08 21:36:53 +00:00
{
proto_tree_add_text ( sccp_tree , tvb , offset , length_length ,
" %s length: %d " ,
val_to_str ( parameter_type , sccp_parameter_values ,
" Unknown " ) ,
parameter_length ) ;
}
2002-03-04 22:39:22 +00:00
offset + = length_length ;
dissect_sccp_parameter ( tvb , pinfo , sccp_tree , tree , parameter_type , offset ,
parameter_length ) ;
return ( parameter_length + length_length ) ;
}
/* FUNCTION dissect_sccp_optional_parameters():
* Dissect all the optional parameters given the start of the optional
* parameters into tvb . Parameter types and lengths are read from tvb .
*/
static void
dissect_sccp_optional_parameters ( tvbuff_t * tvb , packet_info * pinfo ,
proto_tree * sccp_tree , proto_tree * tree ,
2003-03-21 23:05:25 +00:00
guint16 offset )
2002-03-04 22:39:22 +00:00
{
guint8 parameter_type ;
while ( ( parameter_type = tvb_get_guint8 ( tvb , offset ) ) ! =
PARAMETER_END_OF_OPTIONAL_PARAMETERS ) {
offset + = PARAMETER_TYPE_LENGTH ;
offset + = dissect_sccp_variable_parameter ( tvb , pinfo , sccp_tree , tree ,
parameter_type , offset ) ;
}
/* Process end of optional parameters */
dissect_sccp_parameter ( tvb , pinfo , sccp_tree , tree , parameter_type , offset ,
END_OF_OPTIONAL_PARAMETERS_LENGTH ) ;
}
2007-03-29 18:09:13 +00:00
static sccp_msg_info_t * new_ud_msg ( packet_info * pinfo , guint32 msg_type _U_ ) {
2007-03-27 23:00:55 +00:00
sccp_msg_info_t * m = ep_alloc ( sizeof ( sccp_msg_info_t ) ) ;
m - > framenum = pinfo - > fd - > num ;
m - > offset = 0 ; /* irrelevant */
m - > type = 0 ;
m - > data . ud . calling_gt = NULL ;
m - > data . ud . calling_ssn = 0 ;
m - > data . ud . called_gt = NULL ;
m - > data . ud . called_ssn = 0 ;
2008-03-27 23:09:22 +00:00
register_frame_end_routine ( reset_sccp_assoc ) ;
2007-03-27 23:00:55 +00:00
return m ;
}
2002-03-04 22:39:22 +00:00
static void
2002-04-02 22:42:11 +00:00
dissect_sccp_message ( tvbuff_t * tvb , packet_info * pinfo , proto_tree * sccp_tree ,
proto_tree * tree )
2002-03-04 22:39:22 +00:00
{
2003-03-21 23:05:25 +00:00
guint16 variable_pointer1 = 0 , variable_pointer2 = 0 , variable_pointer3 = 0 ;
2006-04-05 16:03:36 +00:00
guint16 optional_pointer = 0 , orig_opt_ptr = 0 ;
2003-03-21 23:05:25 +00:00
guint16 offset = 0 ;
2006-01-19 05:51:59 +00:00
guint8 parameter_type ;
2006-01-20 19:32:59 +00:00
gboolean save_fragmented ;
2006-02-22 16:25:29 +00:00
tvbuff_t * new_tvb = NULL ;
fragment_data * frag_msg = NULL ;
guint32 source_local_ref = 0 ;
guint8 more ;
2007-03-05 23:50:08 +00:00
guint msg_offset = offset_from_real_beginning ( tvb , 0 ) ;
2007-03-24 13:46:41 +00:00
2002-03-04 22:39:22 +00:00
/* Macro for getting pointer to mandatory variable parameters */
2003-03-21 23:05:25 +00:00
# define VARIABLE_POINTER(var, hf_var, ptr_size) \
if ( ptr_size = = POINTER_LENGTH ) \
var = tvb_get_guint8 ( tvb , offset ) ; \
else \
var = tvb_get_letohs ( tvb , offset ) ; \
2002-03-04 22:39:22 +00:00
proto_tree_add_uint ( sccp_tree , hf_var , tvb , \
2003-03-21 23:05:25 +00:00
offset , ptr_size , var ) ; \
2002-03-04 22:39:22 +00:00
var + = offset ; \
2004-01-08 20:19:04 +00:00
if ( ptr_size = = POINTER_LENGTH_LONG ) \
var + = 1 ; \
2003-03-21 23:05:25 +00:00
offset + = ptr_size ;
2002-03-04 22:39:22 +00:00
/* Macro for getting pointer to optional parameters */
2003-03-21 23:05:25 +00:00
# define OPTIONAL_POINTER(ptr_size) \
if ( ptr_size = = POINTER_LENGTH ) \
2006-04-05 16:03:36 +00:00
orig_opt_ptr = optional_pointer = tvb_get_guint8 ( tvb , offset ) ; \
2003-03-21 23:05:25 +00:00
else \
2006-04-05 16:03:36 +00:00
orig_opt_ptr = optional_pointer = tvb_get_letohs ( tvb , offset ) ; \
2002-03-04 22:39:22 +00:00
proto_tree_add_uint ( sccp_tree , hf_sccp_optional_pointer , tvb , \
2003-03-21 23:05:25 +00:00
offset , ptr_size , optional_pointer ) ; \
2002-03-04 22:39:22 +00:00
optional_pointer + = offset ; \
2004-01-08 20:19:04 +00:00
if ( ptr_size = = POINTER_LENGTH_LONG ) \
optional_pointer + = 1 ; \
2003-03-21 23:05:25 +00:00
offset + = ptr_size ;
2002-03-04 22:39:22 +00:00
/* Extract the message type; all other processing is based on this */
2007-03-21 00:48:46 +00:00
message_type = tvb_get_guint8 ( tvb , SCCP_MSG_TYPE_OFFSET ) ;
offset = SCCP_MSG_TYPE_LENGTH ;
2002-03-04 22:39:22 +00:00
2007-03-22 22:59:20 +00:00
if ( check_col ( pinfo - > cinfo , COL_INFO ) ) {
2007-07-26 20:05:54 +00:00
/* Do not change col_add_fstr() to col_append_fstr() here: we _want_
* this call to overwrite whatever ' s currently in the INFO column ( e . g . ,
* " DATA " from the SCTP dissector ) .
*
* If there ' s something there that should not be overwritten , whoever
* put that info there should call col_set_fence ( ) to protect it .
*/
col_add_fstr ( pinfo - > cinfo , COL_INFO , " %s " ,
2007-01-19 17:25:13 +00:00
val_to_str ( message_type , sccp_message_type_acro_values , " Unknown " ) ) ;
2007-03-22 22:59:20 +00:00
} ;
2002-03-04 22:39:22 +00:00
if ( sccp_tree ) {
/* add the message type to the protocol tree */
proto_tree_add_uint ( sccp_tree , hf_sccp_message_type , tvb ,
2007-03-21 00:48:46 +00:00
SCCP_MSG_TYPE_OFFSET , SCCP_MSG_TYPE_LENGTH , message_type ) ;
2002-03-04 22:39:22 +00:00
} ;
2007-01-19 17:25:13 +00:00
/* Starting a new message dissection; clear the global assoc, SLR, and DLR values */
2007-11-24 15:38:19 +00:00
dlr = INVALID_LR ;
slr = INVALID_LR ;
2006-03-11 15:30:52 +00:00
assoc = NULL ;
2007-03-24 13:46:41 +00:00
2006-04-06 20:50:48 +00:00
no_assoc . calling_dpc = 0 ;
no_assoc . called_dpc = 0 ;
no_assoc . calling_ssn = INVALID_SSN ;
no_assoc . called_ssn = INVALID_SSN ;
2007-03-21 00:48:46 +00:00
no_assoc . has_fw_key = FALSE ;
no_assoc . has_bw_key = FALSE ;
2007-03-22 22:59:20 +00:00
no_assoc . payload = SCCP_PLOAD_NONE ;
2007-03-21 00:48:46 +00:00
no_assoc . called_party = NULL ;
no_assoc . calling_party = NULL ;
no_assoc . extra_info = NULL ;
2006-04-06 20:50:48 +00:00
2002-03-04 22:39:22 +00:00
switch ( message_type ) {
2007-03-21 00:48:46 +00:00
case SCCP_MSG_TYPE_CR :
2006-04-05 16:03:36 +00:00
/* TTC and NTT (Japan) say that the connection-oriented messages are
* deleted ( not standardized ) , but they appear to be used anyway , so
* we ' ll dissect it . . .
2007-01-19 17:25:13 +00:00
*/
2002-03-04 22:39:22 +00:00
offset + = dissect_sccp_parameter ( tvb , pinfo , sccp_tree , tree ,
PARAMETER_SOURCE_LOCAL_REFERENCE ,
offset , SOURCE_LOCAL_REFERENCE_LENGTH ) ;
offset + = dissect_sccp_parameter ( tvb , pinfo , sccp_tree , tree ,
PARAMETER_CLASS , offset ,
PROTOCOL_CLASS_LENGTH ) ;
2007-10-26 22:17:45 +00:00
assoc = get_sccp_assoc ( pinfo , msg_offset , slr , dlr , message_type ) ;
2002-03-04 22:39:22 +00:00
2003-03-21 23:05:25 +00:00
VARIABLE_POINTER ( variable_pointer1 , hf_sccp_variable_pointer1 , POINTER_LENGTH )
OPTIONAL_POINTER ( POINTER_LENGTH )
2002-03-04 22:39:22 +00:00
dissect_sccp_variable_parameter ( tvb , pinfo , sccp_tree , tree ,
PARAMETER_CALLED_PARTY_ADDRESS ,
variable_pointer1 ) ;
break ;
2007-03-21 00:48:46 +00:00
case SCCP_MSG_TYPE_CC :
2002-03-04 22:39:22 +00:00
/* TODO: connection has been established; theoretically we could keep
* keep track of the SLR / DLR with the called / calling from the CR and
* track the connection ( e . g . , on subsequent messages regarding this
* SLR we could set the global vars " call*_ssn " so data could get
* sub - dissected ) .
*/
offset + = dissect_sccp_parameter ( tvb , pinfo , sccp_tree , tree ,
PARAMETER_DESTINATION_LOCAL_REFERENCE ,
offset ,
DESTINATION_LOCAL_REFERENCE_LENGTH ) ;
offset + = dissect_sccp_parameter ( tvb , pinfo , sccp_tree , tree ,
PARAMETER_SOURCE_LOCAL_REFERENCE ,
offset , SOURCE_LOCAL_REFERENCE_LENGTH ) ;
2007-01-19 17:25:13 +00:00
2007-10-26 22:17:45 +00:00
assoc = get_sccp_assoc ( pinfo , msg_offset , slr , dlr , message_type ) ;
2007-01-19 17:25:13 +00:00
2002-03-04 22:39:22 +00:00
offset + = dissect_sccp_parameter ( tvb , pinfo , sccp_tree , tree ,
PARAMETER_CLASS , offset ,
PROTOCOL_CLASS_LENGTH ) ;
2005-12-13 22:07:09 +00:00
OPTIONAL_POINTER ( POINTER_LENGTH ) ;
2002-03-04 22:39:22 +00:00
break ;
2007-03-21 00:48:46 +00:00
case SCCP_MSG_TYPE_CREF :
2002-03-04 22:39:22 +00:00
offset + = dissect_sccp_parameter ( tvb , pinfo , sccp_tree , tree ,
PARAMETER_DESTINATION_LOCAL_REFERENCE ,
offset ,
DESTINATION_LOCAL_REFERENCE_LENGTH ) ;
2007-01-19 17:25:13 +00:00
2007-10-26 22:17:45 +00:00
assoc = get_sccp_assoc ( pinfo , msg_offset , slr , dlr , message_type ) ;
2005-12-13 22:07:09 +00:00
2002-03-04 22:39:22 +00:00
offset + = dissect_sccp_parameter ( tvb , pinfo , sccp_tree , tree ,
PARAMETER_REFUSAL_CAUSE , offset ,
REFUSAL_CAUSE_LENGTH ) ;
2007-01-19 17:25:13 +00:00
OPTIONAL_POINTER ( POINTER_LENGTH ) ;
2002-03-04 22:39:22 +00:00
break ;
2007-03-21 00:48:46 +00:00
case SCCP_MSG_TYPE_RLSD :
2002-03-04 22:39:22 +00:00
offset + = dissect_sccp_parameter ( tvb , pinfo , sccp_tree , tree ,
PARAMETER_DESTINATION_LOCAL_REFERENCE ,
offset ,
DESTINATION_LOCAL_REFERENCE_LENGTH ) ;
offset + = dissect_sccp_parameter ( tvb , pinfo , sccp_tree , tree ,
PARAMETER_SOURCE_LOCAL_REFERENCE ,
offset , SOURCE_LOCAL_REFERENCE_LENGTH ) ;
2007-01-19 17:25:13 +00:00
2007-10-26 22:17:45 +00:00
assoc = get_sccp_assoc ( pinfo , msg_offset , slr , dlr , message_type ) ;
2007-01-19 17:25:13 +00:00
2002-03-04 22:39:22 +00:00
offset + = dissect_sccp_parameter ( tvb , pinfo , sccp_tree , tree ,
PARAMETER_RELEASE_CAUSE , offset ,
RELEASE_CAUSE_LENGTH ) ;
2007-01-19 17:25:13 +00:00
OPTIONAL_POINTER ( POINTER_LENGTH ) ;
2007-10-26 22:17:45 +00:00
assoc = get_sccp_assoc ( pinfo , msg_offset , slr , dlr , message_type ) ;
2002-03-04 22:39:22 +00:00
break ;
2007-03-21 00:48:46 +00:00
case SCCP_MSG_TYPE_RLC :
2002-03-04 22:39:22 +00:00
offset + = dissect_sccp_parameter ( tvb , pinfo , sccp_tree , tree ,
PARAMETER_DESTINATION_LOCAL_REFERENCE ,
offset ,
DESTINATION_LOCAL_REFERENCE_LENGTH ) ;
offset + = dissect_sccp_parameter ( tvb , pinfo , sccp_tree , tree ,
PARAMETER_SOURCE_LOCAL_REFERENCE ,
offset , SOURCE_LOCAL_REFERENCE_LENGTH ) ;
2007-01-19 17:25:13 +00:00
2007-10-26 22:17:45 +00:00
assoc = get_sccp_assoc ( pinfo , msg_offset , slr , dlr , message_type ) ;
2002-03-04 22:39:22 +00:00
break ;
2007-03-21 00:48:46 +00:00
case SCCP_MSG_TYPE_DT1 :
2007-01-19 17:25:13 +00:00
source_local_ref = tvb_get_letoh24 ( tvb , offset ) ;
2002-03-04 22:39:22 +00:00
offset + = dissect_sccp_parameter ( tvb , pinfo , sccp_tree , tree ,
PARAMETER_DESTINATION_LOCAL_REFERENCE ,
offset ,
DESTINATION_LOCAL_REFERENCE_LENGTH ) ;
2006-02-22 16:25:29 +00:00
2007-10-26 22:17:45 +00:00
assoc = get_sccp_assoc ( pinfo , msg_offset , slr , dlr , message_type ) ;
2007-01-19 17:25:13 +00:00
more = tvb_get_guint8 ( tvb , offset ) & SEGMENTING_REASSEMBLING_MASK ;
offset + = dissect_sccp_parameter ( tvb , pinfo , sccp_tree , tree ,
2002-03-04 22:39:22 +00:00
PARAMETER_SEGMENTING_REASSEMBLING ,
offset , SEGMENTING_REASSEMBLING_LENGTH ) ;
2003-03-21 23:05:25 +00:00
VARIABLE_POINTER ( variable_pointer1 , hf_sccp_variable_pointer1 , POINTER_LENGTH )
2006-02-22 16:25:29 +00:00
2007-01-19 17:25:13 +00:00
/* Reasemble */
2007-01-19 23:27:24 +00:00
if ( ! sccp_xudt_desegment ) {
2007-01-19 17:25:13 +00:00
proto_tree_add_text ( sccp_tree , tvb , variable_pointer1 ,
tvb_get_guint8 ( tvb , variable_pointer1 ) + 1 ,
" Segmented Data " ) ;
dissect_sccp_variable_parameter ( tvb , pinfo , sccp_tree , tree ,
PARAMETER_DATA , variable_pointer1 ) ;
2007-01-19 23:27:24 +00:00
} else {
2007-01-19 17:25:13 +00:00
save_fragmented = pinfo - > fragmented ;
pinfo - > fragmented = TRUE ;
frag_msg = fragment_add_seq_next ( tvb , variable_pointer1 + 1 , pinfo ,
source_local_ref , /* ID for fragments belonging together */
sccp_xudt_msg_fragment_table , /* list of message fragments */
sccp_xudt_msg_reassembled_table , /* list of reassembled messages */
tvb_get_guint8 ( tvb , variable_pointer1 ) , /* fragment length - to the end */
more ) ; /* More fragments? */
new_tvb = process_reassembled_data ( tvb , variable_pointer1 + 1 , pinfo ,
" Reassembled Message " , frag_msg ,
& sccp_xudt_msg_frag_items , NULL ,
tree ) ;
2007-01-19 23:27:24 +00:00
if ( frag_msg & & frag_msg - > next ) { /* Reassembled */
2007-01-19 17:25:13 +00:00
if ( check_col ( pinfo - > cinfo , COL_INFO ) )
col_append_str ( pinfo - > cinfo , COL_INFO ,
2007-01-19 23:27:24 +00:00
" (Message reassembled) " ) ;
} else if ( more ) { /* Not last packet of reassembled message */
2007-01-19 17:25:13 +00:00
if ( check_col ( pinfo - > cinfo , COL_INFO ) )
2007-01-19 23:27:24 +00:00
col_append_str ( pinfo - > cinfo , COL_INFO , " (Message fragment) " ) ;
2006-02-22 16:25:29 +00:00
}
2007-01-19 17:25:13 +00:00
pinfo - > fragmented = save_fragmented ;
if ( new_tvb )
dissect_sccp_data_param ( new_tvb , pinfo , tree ) ;
}
/* End reassemble */
2002-03-04 22:39:22 +00:00
break ;
2007-03-21 00:48:46 +00:00
case SCCP_MSG_TYPE_DT2 :
2002-03-04 22:39:22 +00:00
offset + = dissect_sccp_parameter ( tvb , pinfo , sccp_tree , tree ,
PARAMETER_DESTINATION_LOCAL_REFERENCE ,
offset ,
DESTINATION_LOCAL_REFERENCE_LENGTH ) ;
2006-02-22 16:25:29 +00:00
2007-10-26 22:17:45 +00:00
assoc = get_sccp_assoc ( pinfo , msg_offset , slr , dlr , message_type ) ;
2006-02-22 16:25:29 +00:00
2007-01-19 17:25:13 +00:00
offset + = dissect_sccp_parameter ( tvb , pinfo , sccp_tree , tree ,
2002-03-04 22:39:22 +00:00
PARAMETER_SEQUENCING_SEGMENTING , offset ,
SEQUENCING_SEGMENTING_LENGTH ) ;
break ;
2007-03-21 00:48:46 +00:00
case SCCP_MSG_TYPE_AK :
2002-03-04 22:39:22 +00:00
offset + = dissect_sccp_parameter ( tvb , pinfo , sccp_tree , tree ,
PARAMETER_DESTINATION_LOCAL_REFERENCE ,
offset ,
DESTINATION_LOCAL_REFERENCE_LENGTH ) ;
2007-01-19 17:25:13 +00:00
2007-10-26 22:17:45 +00:00
assoc = get_sccp_assoc ( pinfo , msg_offset , slr , dlr , message_type ) ;
2007-01-19 17:25:13 +00:00
2002-03-04 22:39:22 +00:00
offset + = dissect_sccp_parameter ( tvb , pinfo , sccp_tree , tree ,
PARAMETER_RECEIVE_SEQUENCE_NUMBER ,
offset , RECEIVE_SEQUENCE_NUMBER_LENGTH ) ;
offset + = dissect_sccp_parameter ( tvb , pinfo , sccp_tree , tree ,
PARAMETER_CREDIT , offset , CREDIT_LENGTH ) ;
break ;
2007-03-21 00:48:46 +00:00
case SCCP_MSG_TYPE_UDT :
2007-03-27 23:00:55 +00:00
pinfo - > sccp_info = sccp_msg = new_ud_msg ( pinfo , message_type ) ;
2007-07-26 20:05:54 +00:00
2002-03-04 22:39:22 +00:00
offset + = dissect_sccp_parameter ( tvb , pinfo , sccp_tree , tree ,
PARAMETER_CLASS , offset ,
PROTOCOL_CLASS_LENGTH ) ;
2003-03-21 23:05:25 +00:00
VARIABLE_POINTER ( variable_pointer1 , hf_sccp_variable_pointer1 , POINTER_LENGTH )
VARIABLE_POINTER ( variable_pointer2 , hf_sccp_variable_pointer2 , POINTER_LENGTH )
VARIABLE_POINTER ( variable_pointer3 , hf_sccp_variable_pointer3 , POINTER_LENGTH )
2002-03-04 22:39:22 +00:00
2007-10-26 22:17:45 +00:00
assoc = get_sccp_assoc ( pinfo , msg_offset , slr , dlr , message_type ) ;
2007-01-19 17:25:13 +00:00
2002-03-04 22:39:22 +00:00
dissect_sccp_variable_parameter ( tvb , pinfo , sccp_tree , tree ,
PARAMETER_CALLED_PARTY_ADDRESS ,
variable_pointer1 ) ;
dissect_sccp_variable_parameter ( tvb , pinfo , sccp_tree , tree ,
PARAMETER_CALLING_PARTY_ADDRESS ,
variable_pointer2 ) ;
2007-01-19 17:25:13 +00:00
2002-03-04 22:39:22 +00:00
dissect_sccp_variable_parameter ( tvb , pinfo , sccp_tree , tree , PARAMETER_DATA ,
variable_pointer3 ) ;
break ;
2007-03-21 00:48:46 +00:00
case SCCP_MSG_TYPE_UDTS :
2007-03-27 23:00:55 +00:00
pinfo - > sccp_info = sccp_msg = new_ud_msg ( pinfo , message_type ) ;
2007-07-26 20:05:54 +00:00
2002-03-04 22:39:22 +00:00
offset + = dissect_sccp_parameter ( tvb , pinfo , sccp_tree , tree ,
PARAMETER_RETURN_CAUSE , offset ,
RETURN_CAUSE_LENGTH ) ;
2003-03-21 23:05:25 +00:00
VARIABLE_POINTER ( variable_pointer1 , hf_sccp_variable_pointer1 , POINTER_LENGTH )
VARIABLE_POINTER ( variable_pointer2 , hf_sccp_variable_pointer2 , POINTER_LENGTH )
VARIABLE_POINTER ( variable_pointer3 , hf_sccp_variable_pointer3 , POINTER_LENGTH )
2002-03-04 22:39:22 +00:00
2007-03-22 22:59:20 +00:00
assoc = get_sccp_assoc ( pinfo , msg_offset , slr , dlr , message_type ) ;
2005-12-13 22:07:09 +00:00
2002-03-04 22:39:22 +00:00
dissect_sccp_variable_parameter ( tvb , pinfo , sccp_tree , tree ,
PARAMETER_CALLED_PARTY_ADDRESS ,
variable_pointer1 ) ;
dissect_sccp_variable_parameter ( tvb , pinfo , sccp_tree , tree ,
PARAMETER_CALLING_PARTY_ADDRESS ,
variable_pointer2 ) ;
2007-01-19 17:25:13 +00:00
2002-03-04 22:39:22 +00:00
dissect_sccp_variable_parameter ( tvb , pinfo , sccp_tree , tree , PARAMETER_DATA ,
variable_pointer3 ) ;
break ;
2007-03-21 00:48:46 +00:00
case SCCP_MSG_TYPE_ED :
2002-03-04 22:39:22 +00:00
offset + = dissect_sccp_parameter ( tvb , pinfo , sccp_tree , tree ,
PARAMETER_DESTINATION_LOCAL_REFERENCE ,
offset ,
DESTINATION_LOCAL_REFERENCE_LENGTH ) ;
2007-10-26 22:17:45 +00:00
assoc = get_sccp_assoc ( pinfo , msg_offset , slr , dlr , message_type ) ;
2007-01-19 17:25:13 +00:00
VARIABLE_POINTER ( variable_pointer1 , hf_sccp_variable_pointer1 , POINTER_LENGTH ) ;
2005-12-13 22:07:09 +00:00
2002-03-04 22:39:22 +00:00
dissect_sccp_variable_parameter ( tvb , pinfo , sccp_tree , tree , PARAMETER_DATA ,
variable_pointer1 ) ;
break ;
2007-03-21 00:48:46 +00:00
case SCCP_MSG_TYPE_EA :
2002-03-04 22:39:22 +00:00
offset + = dissect_sccp_parameter ( tvb , pinfo , sccp_tree , tree ,
PARAMETER_DESTINATION_LOCAL_REFERENCE ,
offset ,
DESTINATION_LOCAL_REFERENCE_LENGTH ) ;
2007-10-26 22:17:45 +00:00
assoc = get_sccp_assoc ( pinfo , msg_offset , slr , dlr , message_type ) ;
2002-03-04 22:39:22 +00:00
break ;
2007-03-21 00:48:46 +00:00
case SCCP_MSG_TYPE_RSR :
2002-03-04 22:39:22 +00:00
offset + = dissect_sccp_parameter ( tvb , pinfo , sccp_tree , tree ,
PARAMETER_DESTINATION_LOCAL_REFERENCE ,
offset ,
DESTINATION_LOCAL_REFERENCE_LENGTH ) ;
offset + = dissect_sccp_parameter ( tvb , pinfo , sccp_tree , tree ,
PARAMETER_SOURCE_LOCAL_REFERENCE ,
offset , SOURCE_LOCAL_REFERENCE_LENGTH ) ;
offset + = dissect_sccp_parameter ( tvb , pinfo , sccp_tree , tree ,
PARAMETER_RESET_CAUSE , offset ,
RESET_CAUSE_LENGTH ) ;
2007-10-26 22:17:45 +00:00
assoc = get_sccp_assoc ( pinfo , msg_offset , slr , dlr , message_type ) ;
2002-03-04 22:39:22 +00:00
break ;
2007-03-21 00:48:46 +00:00
case SCCP_MSG_TYPE_RSC :
2002-03-04 22:39:22 +00:00
offset + = dissect_sccp_parameter ( tvb , pinfo , sccp_tree , tree ,
PARAMETER_DESTINATION_LOCAL_REFERENCE ,
offset ,
DESTINATION_LOCAL_REFERENCE_LENGTH ) ;
offset + = dissect_sccp_parameter ( tvb , pinfo , sccp_tree , tree ,
PARAMETER_SOURCE_LOCAL_REFERENCE ,
offset , SOURCE_LOCAL_REFERENCE_LENGTH ) ;
2007-10-26 22:17:45 +00:00
assoc = get_sccp_assoc ( pinfo , msg_offset , slr , dlr , message_type ) ;
2002-03-04 22:39:22 +00:00
break ;
2007-03-21 00:48:46 +00:00
case SCCP_MSG_TYPE_ERR :
2002-03-04 22:39:22 +00:00
offset + = dissect_sccp_parameter ( tvb , pinfo , sccp_tree , tree ,
PARAMETER_DESTINATION_LOCAL_REFERENCE ,
offset ,
DESTINATION_LOCAL_REFERENCE_LENGTH ) ;
offset + = dissect_sccp_parameter ( tvb , pinfo , sccp_tree , tree ,
PARAMETER_ERROR_CAUSE , offset ,
ERROR_CAUSE_LENGTH ) ;
2007-10-26 22:17:45 +00:00
assoc = get_sccp_assoc ( pinfo , msg_offset , slr , dlr , message_type ) ;
2002-03-04 22:39:22 +00:00
break ;
2007-03-21 00:48:46 +00:00
case SCCP_MSG_TYPE_IT :
2002-03-04 22:39:22 +00:00
offset + = dissect_sccp_parameter ( tvb , pinfo , sccp_tree , tree ,
PARAMETER_DESTINATION_LOCAL_REFERENCE ,
offset ,
DESTINATION_LOCAL_REFERENCE_LENGTH ) ;
offset + = dissect_sccp_parameter ( tvb , pinfo , sccp_tree , tree ,
PARAMETER_SOURCE_LOCAL_REFERENCE ,
offset , SOURCE_LOCAL_REFERENCE_LENGTH ) ;
2007-10-26 22:17:45 +00:00
assoc = get_sccp_assoc ( pinfo , msg_offset , slr , dlr , message_type ) ;
2002-03-04 22:39:22 +00:00
offset + = dissect_sccp_parameter ( tvb , pinfo , sccp_tree , tree ,
PARAMETER_CLASS , offset ,
PROTOCOL_CLASS_LENGTH ) ;
offset + = dissect_sccp_parameter ( tvb , pinfo , sccp_tree , tree ,
PARAMETER_SEQUENCING_SEGMENTING ,
offset , SEQUENCING_SEGMENTING_LENGTH ) ;
offset + = dissect_sccp_parameter ( tvb , pinfo , sccp_tree , tree ,
PARAMETER_CREDIT , offset , CREDIT_LENGTH ) ;
break ;
2007-03-21 00:48:46 +00:00
case SCCP_MSG_TYPE_XUDT :
2007-03-27 23:00:55 +00:00
pinfo - > sccp_info = sccp_msg = new_ud_msg ( pinfo , message_type ) ;
2002-03-04 22:39:22 +00:00
offset + = dissect_sccp_parameter ( tvb , pinfo , sccp_tree , tree ,
PARAMETER_CLASS , offset ,
PROTOCOL_CLASS_LENGTH ) ;
offset + = dissect_sccp_parameter ( tvb , pinfo , sccp_tree , tree ,
PARAMETER_HOP_COUNTER , offset ,
HOP_COUNTER_LENGTH ) ;
2003-03-21 23:05:25 +00:00
VARIABLE_POINTER ( variable_pointer1 , hf_sccp_variable_pointer1 , POINTER_LENGTH )
VARIABLE_POINTER ( variable_pointer2 , hf_sccp_variable_pointer2 , POINTER_LENGTH )
VARIABLE_POINTER ( variable_pointer3 , hf_sccp_variable_pointer3 , POINTER_LENGTH )
OPTIONAL_POINTER ( POINTER_LENGTH )
2002-03-04 22:39:22 +00:00
2007-01-19 17:25:13 +00:00
/* Optional parameters are Segmentation and Importance
* NOTE 2 - Segmentation Should not be present in case of a single XUDT
* message .
*/
2006-01-19 05:51:59 +00:00
2007-10-26 22:17:45 +00:00
assoc = get_sccp_assoc ( pinfo , msg_offset , slr , dlr , message_type ) ;
2005-12-13 22:07:09 +00:00
2002-03-04 22:39:22 +00:00
dissect_sccp_variable_parameter ( tvb , pinfo , sccp_tree , tree ,
PARAMETER_CALLED_PARTY_ADDRESS ,
variable_pointer1 ) ;
dissect_sccp_variable_parameter ( tvb , pinfo , sccp_tree , tree ,
PARAMETER_CALLING_PARTY_ADDRESS ,
variable_pointer2 ) ;
2006-01-20 19:32:59 +00:00
2007-01-19 17:25:13 +00:00
if ( ( parameter_type = tvb_get_guint8 ( tvb , optional_pointer ) ) = = PARAMETER_SEGMENTATION ) {
2007-12-30 00:02:25 +00:00
if ( ! sccp_xudt_desegment ) {
proto_tree_add_text ( sccp_tree , tvb , variable_pointer3 , tvb_get_guint8 ( tvb , variable_pointer3 ) + 1 , " Segmented Data " ) ;
} else {
guint8 octet ;
gboolean more_frag = TRUE ;
/* Get the first octet of parameter Segmentation, Ch 3.17 in Q.713
* Bit 8 of octet 1 is used for First segment indication
* Bit 7 of octet 1 is used to keep in the message in sequence
* delivery option required by the SCCP user
* Bits 6 and 5 in octet 1 are spare bits .
* Bits 4 - 1 of octet 1 are used to indicate the number of
* remaining segments .
* The values 0000 to 1111 are possible ; the value 0000 indicates
* the last segment .
*/
octet = tvb_get_guint8 ( tvb , optional_pointer + 2 ) ;
source_local_ref = tvb_get_letoh24 ( tvb , optional_pointer + 3 ) ;
if ( ( octet & 0x0f ) = = 0 )
more_frag = FALSE ;
save_fragmented = pinfo - > fragmented ;
pinfo - > fragmented = TRUE ;
frag_msg = fragment_add_seq_next ( tvb , variable_pointer3 + 1 , pinfo ,
source_local_ref , /* ID for fragments belonging together */
sccp_xudt_msg_fragment_table , /* list of message fragments */
sccp_xudt_msg_reassembled_table , /* list of reassembled messages */
tvb_get_guint8 ( tvb , variable_pointer3 ) , /* fragment length - to the end */
more_frag ) ; /* More fragments? */
if ( ( octet & 0x80 ) = = 0x80 ) /*First segment, set number of segments*/
fragment_set_tot_len ( pinfo , source_local_ref , sccp_xudt_msg_fragment_table , ( octet & 0xf ) ) ;
new_tvb = process_reassembled_data ( tvb , variable_pointer3 + 1 ,
2007-01-19 17:25:13 +00:00
pinfo , " Reassembled Message " ,
frag_msg ,
& sccp_xudt_msg_frag_items ,
NULL , tree ) ;
2007-12-30 00:02:25 +00:00
if ( frag_msg ) { /* Reassembled */
if ( check_col ( pinfo - > cinfo , COL_INFO ) )
col_append_str ( pinfo - > cinfo , COL_INFO , " (Message reassembled) " ) ;
} else { /* Not last packet of reassembled message */
if ( check_col ( pinfo - > cinfo , COL_INFO ) )
col_append_str ( pinfo - > cinfo , COL_INFO , " (Message fragment) " ) ;
}
2007-01-19 17:25:13 +00:00
2007-12-30 00:02:25 +00:00
pinfo - > fragmented = save_fragmented ;
2007-01-19 17:25:13 +00:00
2007-12-30 00:02:25 +00:00
if ( new_tvb )
dissect_sccp_data_param ( new_tvb , pinfo , tree ) ;
}
2007-01-19 17:25:13 +00:00
} else {
2007-12-30 00:02:25 +00:00
dissect_sccp_variable_parameter ( tvb , pinfo , sccp_tree , tree ,
2007-01-19 17:25:13 +00:00
PARAMETER_DATA , variable_pointer3 ) ;
}
2002-03-04 22:39:22 +00:00
break ;
2007-03-21 00:48:46 +00:00
case SCCP_MSG_TYPE_XUDTS :
2007-03-27 23:00:55 +00:00
pinfo - > sccp_info = sccp_msg = new_ud_msg ( pinfo , message_type ) ;
2002-03-04 22:39:22 +00:00
offset + = dissect_sccp_parameter ( tvb , pinfo , sccp_tree , tree ,
PARAMETER_RETURN_CAUSE , offset ,
RETURN_CAUSE_LENGTH ) ;
offset + = dissect_sccp_parameter ( tvb , pinfo , sccp_tree , tree ,
PARAMETER_HOP_COUNTER , offset ,
HOP_COUNTER_LENGTH ) ;
2003-03-21 23:05:25 +00:00
VARIABLE_POINTER ( variable_pointer1 , hf_sccp_variable_pointer1 , POINTER_LENGTH )
VARIABLE_POINTER ( variable_pointer2 , hf_sccp_variable_pointer2 , POINTER_LENGTH )
VARIABLE_POINTER ( variable_pointer3 , hf_sccp_variable_pointer3 , POINTER_LENGTH )
OPTIONAL_POINTER ( POINTER_LENGTH )
2002-03-04 22:39:22 +00:00
2007-10-26 22:17:45 +00:00
assoc = get_sccp_assoc ( pinfo , msg_offset , slr , dlr , message_type ) ;
2005-12-13 22:07:09 +00:00
2002-03-04 22:39:22 +00:00
dissect_sccp_variable_parameter ( tvb , pinfo , sccp_tree , tree ,
PARAMETER_CALLED_PARTY_ADDRESS ,
variable_pointer1 ) ;
dissect_sccp_variable_parameter ( tvb , pinfo , sccp_tree , tree ,
PARAMETER_CALLING_PARTY_ADDRESS ,
variable_pointer2 ) ;
2007-12-03 18:12:25 +00:00
if ( ( parameter_type = tvb_get_guint8 ( tvb , optional_pointer ) ) = = PARAMETER_SEGMENTATION ) {
if ( ! sccp_xudt_desegment ) {
proto_tree_add_text ( sccp_tree , tvb , variable_pointer3 , tvb_get_guint8 ( tvb , variable_pointer3 ) + 1 , " Segmented Data " ) ;
} else {
guint8 octet ;
gboolean more_frag = TRUE ;
/* Get the first octet of parameter Segmentation, Ch 3.17 in Q.713
* Bit 8 of octet 1 is used for First segment indication
* Bit 7 of octet 1 is used to keep in the message in sequence
* delivery option required by the SCCP user
* Bits 6 and 5 in octet 1 are spare bits .
* Bits 4 - 1 of octet 1 are used to indicate the number of
* remaining segments .
* The values 0000 to 1111 are possible ; the value 0000 indicates
* the last segment .
*/
octet = tvb_get_guint8 ( tvb , optional_pointer + 2 ) ;
source_local_ref = tvb_get_letoh24 ( tvb , optional_pointer + 3 ) ;
if ( ( octet & 0x0f ) = = 0 )
more_frag = FALSE ;
save_fragmented = pinfo - > fragmented ;
pinfo - > fragmented = TRUE ;
frag_msg = fragment_add_seq_next ( tvb , variable_pointer3 + 1 , pinfo ,
source_local_ref , /* ID for fragments belonging together */
sccp_xudt_msg_fragment_table , /* list of message fragments */
sccp_xudt_msg_reassembled_table , /* list of reassembled messages */
tvb_get_guint8 ( tvb , variable_pointer3 ) , /* fragment length - to the end */
more_frag ) ; /* More fragments? */
if ( ( octet & 0x80 ) = = 0x80 ) /*First segment, set number of segments*/
fragment_set_tot_len ( pinfo , source_local_ref , sccp_xudt_msg_fragment_table , ( octet & 0xf ) ) ;
new_tvb = process_reassembled_data ( tvb , variable_pointer3 + 1 ,
pinfo , " Reassembled Message " ,
frag_msg ,
& sccp_xudt_msg_frag_items ,
NULL , tree ) ;
if ( frag_msg ) { /* Reassembled */
if ( check_col ( pinfo - > cinfo , COL_INFO ) )
col_append_str ( pinfo - > cinfo , COL_INFO ,
" (Message reassembled) " ) ;
} else { /* Not last packet of reassembled message */
if ( check_col ( pinfo - > cinfo , COL_INFO ) )
col_append_str ( pinfo - > cinfo , COL_INFO ,
" (Message fragment) " ) ;
}
pinfo - > fragmented = save_fragmented ;
if ( new_tvb )
dissect_sccp_data_param ( new_tvb , pinfo , tree ) ;
}
} else {
dissect_sccp_variable_parameter ( tvb , pinfo , sccp_tree , tree ,
PARAMETER_DATA , variable_pointer3 ) ;
}
2002-03-04 22:39:22 +00:00
break ;
2007-03-21 00:48:46 +00:00
case SCCP_MSG_TYPE_LUDT :
2007-03-27 23:00:55 +00:00
pinfo - > sccp_info = sccp_msg = new_ud_msg ( pinfo , message_type ) ;
if ( decode_mtp3_standard ! = ANSI_STANDARD )
2002-03-04 22:39:22 +00:00
{
offset + = dissect_sccp_parameter ( tvb , pinfo , sccp_tree , tree ,
PARAMETER_CLASS , offset ,
PROTOCOL_CLASS_LENGTH ) ;
offset + = dissect_sccp_parameter ( tvb , pinfo , sccp_tree , tree ,
PARAMETER_HOP_COUNTER , offset ,
HOP_COUNTER_LENGTH ) ;
2003-03-21 23:05:25 +00:00
VARIABLE_POINTER ( variable_pointer1 , hf_sccp_variable_pointer1 , POINTER_LENGTH_LONG )
VARIABLE_POINTER ( variable_pointer2 , hf_sccp_variable_pointer2 , POINTER_LENGTH_LONG )
VARIABLE_POINTER ( variable_pointer3 , hf_sccp_variable_pointer3 , POINTER_LENGTH_LONG )
OPTIONAL_POINTER ( POINTER_LENGTH_LONG )
2002-03-04 22:39:22 +00:00
2007-03-22 22:59:20 +00:00
assoc = get_sccp_assoc ( pinfo , msg_offset , slr , dlr , message_type ) ;
2005-12-13 22:07:09 +00:00
2002-03-04 22:39:22 +00:00
dissect_sccp_variable_parameter ( tvb , pinfo , sccp_tree , tree ,
PARAMETER_CALLED_PARTY_ADDRESS ,
variable_pointer1 ) ;
dissect_sccp_variable_parameter ( tvb , pinfo , sccp_tree , tree ,
PARAMETER_CALLING_PARTY_ADDRESS ,
variable_pointer2 ) ;
dissect_sccp_variable_parameter ( tvb , pinfo , sccp_tree , tree ,
PARAMETER_LONG_DATA , variable_pointer3 ) ;
} else
dissect_sccp_unknown_message ( tvb , sccp_tree ) ;
break ;
2007-03-21 00:48:46 +00:00
case SCCP_MSG_TYPE_LUDTS :
2007-03-27 23:00:55 +00:00
pinfo - > sccp_info = sccp_msg = new_ud_msg ( pinfo , message_type ) ;
if ( decode_mtp3_standard ! = ANSI_STANDARD )
2002-03-04 22:39:22 +00:00
{
offset + = dissect_sccp_parameter ( tvb , pinfo , sccp_tree , tree ,
PARAMETER_RETURN_CAUSE , offset ,
RETURN_CAUSE_LENGTH ) ;
offset + = dissect_sccp_parameter ( tvb , pinfo , sccp_tree , tree ,
PARAMETER_HOP_COUNTER , offset ,
HOP_COUNTER_LENGTH ) ;
2003-03-21 23:05:25 +00:00
VARIABLE_POINTER ( variable_pointer1 , hf_sccp_variable_pointer1 , POINTER_LENGTH_LONG )
VARIABLE_POINTER ( variable_pointer2 , hf_sccp_variable_pointer2 , POINTER_LENGTH_LONG )
VARIABLE_POINTER ( variable_pointer3 , hf_sccp_variable_pointer3 , POINTER_LENGTH_LONG )
OPTIONAL_POINTER ( POINTER_LENGTH_LONG )
2002-03-04 22:39:22 +00:00
2007-03-22 22:59:20 +00:00
assoc = get_sccp_assoc ( pinfo , msg_offset , slr , dlr , message_type ) ;
2005-12-13 22:07:09 +00:00
2002-03-04 22:39:22 +00:00
dissect_sccp_variable_parameter ( tvb , pinfo , sccp_tree , tree ,
PARAMETER_CALLED_PARTY_ADDRESS ,
variable_pointer1 ) ;
dissect_sccp_variable_parameter ( tvb , pinfo , sccp_tree , tree ,
PARAMETER_CALLING_PARTY_ADDRESS ,
variable_pointer2 ) ;
dissect_sccp_variable_parameter ( tvb , pinfo , sccp_tree , tree ,
PARAMETER_LONG_DATA , variable_pointer3 ) ;
} else
dissect_sccp_unknown_message ( tvb , sccp_tree ) ;
break ;
default :
dissect_sccp_unknown_message ( tvb , sccp_tree ) ;
}
2006-04-05 16:03:36 +00:00
if ( orig_opt_ptr )
2002-03-04 22:39:22 +00:00
dissect_sccp_optional_parameters ( tvb , pinfo , sccp_tree , tree ,
optional_pointer ) ;
2007-03-24 13:46:41 +00:00
2007-03-03 23:38:35 +00:00
if ( trace_sccp & & assoc & & assoc ! = & no_assoc ) {
proto_item * pi = proto_tree_add_uint ( sccp_tree , hf_sccp_assoc_id , tvb , 0 , 0 , assoc - > id ) ;
proto_tree * pt = proto_item_add_subtree ( pi , ett_sccp_assoc ) ;
PROTO_ITEM_SET_GENERATED ( pi ) ;
if ( assoc - > msgs ) {
sccp_msg_info_t * m ;
2007-07-26 20:05:54 +00:00
for ( m = assoc - > msgs ; m ; m = m - > data . co . next ) {
2007-03-03 23:38:35 +00:00
pi = proto_tree_add_uint ( pt , hf_sccp_assoc_msg , tvb , 0 , 0 , m - > framenum ) ;
2007-03-24 13:46:41 +00:00
if ( assoc - > payload ! = SCCP_PLOAD_NONE )
2007-03-22 22:59:20 +00:00
proto_item_append_text ( pi , " %s " , val_to_str ( assoc - > payload , assoc_protos , " Unknown " ) ) ;
2007-03-24 13:46:41 +00:00
2007-03-27 23:00:55 +00:00
if ( m - > data . co . label )
proto_item_append_text ( pi , " %s " , m - > data . co . label ) ;
2007-03-24 13:46:41 +00:00
2007-03-05 23:50:08 +00:00
if ( m - > framenum = = pinfo - > fd - > num & & m - > offset = = msg_offset ) {
2007-03-21 00:48:46 +00:00
tap_queue_packet ( sccp_tap , pinfo , m ) ;
2007-03-03 23:38:35 +00:00
proto_item_append_text ( pi , " (current) " ) ;
}
2007-03-21 00:48:46 +00:00
PROTO_ITEM_SET_GENERATED ( pi ) ;
2007-03-03 23:38:35 +00:00
}
}
}
2002-03-04 22:39:22 +00:00
}
static void
dissect_sccp ( tvbuff_t * tvb , packet_info * pinfo , proto_tree * tree )
{
2007-03-22 22:59:20 +00:00
proto_item * sccp_item = NULL ;
2002-03-04 22:39:22 +00:00
proto_tree * sccp_tree = NULL ;
2003-12-08 21:36:53 +00:00
const mtp3_addr_pc_t * mtp3_addr_p ;
2002-03-04 22:39:22 +00:00
2005-12-14 20:01:21 +00:00
if ( ( pinfo - > src . type = = AT_SS7PC ) & &
( ( mtp3_addr_p = ( const mtp3_addr_pc_t * ) pinfo - > src . data ) - > type < = CHINESE_ITU_STANDARD ) )
2005-08-19 08:36:38 +00:00
{
/*
2007-01-19 17:25:13 +00:00
* Allow a protocol beneath to specify how the SCCP layer should be
* dissected .
*
* It is possible to have multiple sets of SCCP traffic some of which is
* ITU and some of which is ANSI .
* An example is A - interface traffic having ANSI MTP3 / ANSI SCCP / 3 GPP2 IOS
* and at the same time ITU MTP3 / ITU SCCP / ANSI TCAP / ANSI MAP .
*/
2005-08-19 08:36:38 +00:00
decode_mtp3_standard = mtp3_addr_p - > type ;
}
else
{
decode_mtp3_standard = mtp3_standard ;
}
2002-03-04 22:39:22 +00:00
/* Make entry in the Protocol column on summary display */
2003-09-06 00:04:45 +00:00
if ( check_col ( pinfo - > cinfo , COL_PROTOCOL ) )
2005-08-19 08:36:38 +00:00
switch ( decode_mtp3_standard ) {
2003-09-05 20:11:45 +00:00
case ITU_STANDARD :
2007-01-19 17:25:13 +00:00
col_set_str ( pinfo - > cinfo , COL_PROTOCOL , " SCCP (Int. ITU) " ) ;
break ;
2003-09-05 20:11:45 +00:00
case ANSI_STANDARD :
2007-01-19 17:25:13 +00:00
col_set_str ( pinfo - > cinfo , COL_PROTOCOL , " SCCP (ANSI) " ) ;
break ;
2003-09-05 20:11:45 +00:00
case CHINESE_ITU_STANDARD :
2007-01-19 17:25:13 +00:00
col_set_str ( pinfo - > cinfo , COL_PROTOCOL , " SCCP (Chin. ITU) " ) ;
break ;
2006-04-05 16:03:36 +00:00
case JAPAN_STANDARD :
2007-01-19 17:25:13 +00:00
col_set_str ( pinfo - > cinfo , COL_PROTOCOL , " SCCP (Japan) " ) ;
break ;
} ;
2002-03-04 22:39:22 +00:00
/* In the interest of speed, if "tree" is NULL, don't do any work not
necessary to generate protocol tree items . */
if ( tree ) {
/* create the sccp protocol tree */
2002-04-02 22:42:11 +00:00
sccp_item = proto_tree_add_item ( tree , proto_sccp , tvb , 0 , - 1 , FALSE ) ;
2002-03-04 22:39:22 +00:00
sccp_tree = proto_item_add_subtree ( sccp_item , ett_sccp ) ;
}
2003-12-08 21:36:53 +00:00
/* Set whether message is UPLINK, DOWNLINK, or of UNKNOWN direction */
2005-12-14 20:01:21 +00:00
if ( pinfo - > src . type = = AT_SS7PC )
2003-12-08 21:36:53 +00:00
{
/*
* XXX - we assume that the " data " pointers of the source and destination
* addresses are set to point to " mtp3_addr_pc_t " structures , so that
* we can safely cast them .
*/
2005-12-14 20:01:21 +00:00
mtp3_addr_p = ( const mtp3_addr_pc_t * ) pinfo - > src . data ;
2003-12-08 21:36:53 +00:00
if ( sccp_source_pc_global = = mtp3_addr_p - > pc )
{
pinfo - > p2p_dir = P2P_DIR_SENT ;
}
else
{
2005-12-14 20:01:21 +00:00
/* assuming if src was SS7 PC then dst will be too */
mtp3_addr_p = ( const mtp3_addr_pc_t * ) pinfo - > dst . data ;
2003-12-08 21:36:53 +00:00
if ( sccp_source_pc_global = = mtp3_addr_p - > pc )
{
pinfo - > p2p_dir = P2P_DIR_RECV ;
}
else
{
pinfo - > p2p_dir = P2P_DIR_UNKNOWN ;
}
}
}
2002-03-04 22:39:22 +00:00
/* dissect the message */
2002-04-02 22:42:11 +00:00
dissect_sccp_message ( tvb , pinfo , sccp_tree , tree ) ;
2007-03-24 13:46:41 +00:00
2002-03-04 22:39:22 +00:00
}
2007-04-03 19:08:00 +00:00
/*** SccpUsers Table **/
static struct _sccp_ul {
guint id ;
gboolean uses_tcap ;
dissector_handle_t * handlep ;
} user_list [ ] = {
{ SCCP_USER_DATA , FALSE , & data_handle } ,
{ SCCP_USER_TCAP , FALSE , & tcap_handle } ,
{ SCCP_USER_RANAP , FALSE , & ranap_handle } ,
{ SCCP_USER_BSSAP , FALSE , & bssap_handle } ,
{ SCCP_USER_GSMMAP , TRUE , & gsmmap_handle } ,
{ SCCP_USER_CAMEL , TRUE , & camel_handle } ,
{ SCCP_USER_INAP , TRUE , & inap_handle } ,
{ 0 , FALSE , NULL }
} ;
2007-04-23 10:59:26 +00:00
static void sccp_users_update_cb ( void * r , const char * * err _U_ ) {
2007-04-03 19:08:00 +00:00
sccp_user_t * u = r ;
struct _sccp_ul * c ;
2007-07-26 20:05:54 +00:00
2007-04-03 19:08:00 +00:00
for ( c = user_list ; c - > handlep ; c + + ) {
if ( c - > id = = u - > user ) {
u - > uses_tcap = c - > uses_tcap ;
u - > handlep = c - > handlep ;
return ;
}
}
2007-07-26 20:05:54 +00:00
2007-04-03 19:08:00 +00:00
u - > uses_tcap = FALSE ;
u - > handlep = & data_handle ;
}
2007-04-16 08:37:39 +00:00
static void * sccp_users_copy_cb ( void * n , const void * o , unsigned siz _U_ ) {
2007-04-03 19:08:00 +00:00
const sccp_user_t * u = o ;
sccp_user_t * un = n ;
2007-07-26 20:05:54 +00:00
2007-04-03 19:08:00 +00:00
un - > ni = u - > ni ;
un - > user = u - > user ;
un - > uses_tcap = u - > uses_tcap ;
un - > handlep = u - > handlep ;
if ( u - > called_pc ) un - > called_pc = range_copy ( u - > called_pc ) ;
2007-04-16 08:37:39 +00:00
if ( u - > called_ssn ) un - > called_ssn = range_copy ( u - > called_ssn ) ;
2007-07-26 20:05:54 +00:00
2007-04-03 19:08:00 +00:00
return n ;
}
static void sccp_users_free_cb ( void * r ) {
sccp_user_t * u = r ;
if ( u - > called_pc ) g_free ( u - > called_pc ) ;
if ( u - > called_ssn ) g_free ( u - > called_ssn ) ;
}
UAT_DEC_CB_DEF ( sccp_users , ni , sccp_user_t )
UAT_RANGE_CB_DEF ( sccp_users , called_pc , sccp_user_t )
UAT_RANGE_CB_DEF ( sccp_users , called_ssn , sccp_user_t )
UAT_VS_DEF ( sccp_users , user , sccp_user_t , SCCP_USER_DATA , " Data " )
/** End SccpUsersTable **/
2005-12-17 16:55:45 +00:00
static void init_sccp ( void ) {
2007-03-03 23:38:35 +00:00
next_assoc_id = 1 ;
2007-01-19 17:25:13 +00:00
fragment_table_init ( & sccp_xudt_msg_fragment_table ) ;
reassembled_table_init ( & sccp_xudt_msg_reassembled_table ) ;
2005-12-13 22:07:09 +00:00
}
2006-05-21 04:49:01 +00:00
/* Register the protocol with Wireshark */
2002-03-04 22:39:22 +00:00
void
proto_register_sccp ( void )
{
/* Setup list of header fields */
static hf_register_info hf [ ] = {
{ & hf_sccp_message_type ,
{ " Message Type " , " sccp.message_type " ,
FT_UINT8 , BASE_HEX , VALS ( sccp_message_type_values ) , 0x0 ,
" " , HFILL } } ,
{ & hf_sccp_variable_pointer1 ,
{ " Pointer to first Mandatory Variable parameter " , " sccp.variable_pointer1 " ,
2003-03-21 23:05:25 +00:00
FT_UINT16 , BASE_DEC , NULL , 0x0 ,
2002-03-04 22:39:22 +00:00
" " , HFILL } } ,
{ & hf_sccp_variable_pointer2 ,
{ " Pointer to second Mandatory Variable parameter " , " sccp.variable_pointer2 " ,
2003-03-21 23:05:25 +00:00
FT_UINT16 , BASE_DEC , NULL , 0x0 ,
2002-03-04 22:39:22 +00:00
" " , HFILL } } ,
{ & hf_sccp_variable_pointer3 ,
{ " Pointer to third Mandatory Variable parameter " , " sccp.variable_pointer3 " ,
2003-03-21 23:05:25 +00:00
FT_UINT16 , BASE_DEC , NULL , 0x0 ,
2002-03-04 22:39:22 +00:00
" " , HFILL } } ,
{ & hf_sccp_optional_pointer ,
{ " Pointer to Optional parameter " , " sccp.optional_pointer " ,
2003-03-21 23:05:25 +00:00
FT_UINT16 , BASE_DEC , NULL , 0x0 ,
2002-03-04 22:39:22 +00:00
" " , HFILL } } ,
{ & hf_sccp_ssn ,
{ " Called or Calling SubSystem Number " , " sccp.ssn " ,
FT_UINT8 , BASE_DEC , VALS ( sccp_ssn_values ) , 0x0 ,
" " , HFILL } } ,
{ & hf_sccp_gt_digits ,
{ " Called or Calling GT Digits " ,
" sccp.digits " ,
FT_STRING , BASE_NONE , NULL , 0x0 ,
" " , HFILL } } ,
{ & hf_sccp_called_national_indicator ,
{ " National Indicator " , " sccp.called.ni " ,
FT_UINT8 , BASE_HEX , VALS ( sccp_national_indicator_values ) , ANSI_NATIONAL_MASK ,
" " , HFILL } } ,
{ & hf_sccp_called_routing_indicator ,
{ " Routing Indicator " , " sccp.called.ri " ,
FT_UINT8 , BASE_HEX , VALS ( sccp_routing_indicator_values ) , ROUTING_INDICATOR_MASK ,
" " , HFILL } } ,
{ & hf_sccp_called_itu_global_title_indicator ,
{ " Global Title Indicator " , " sccp.called.gti " ,
FT_UINT8 , BASE_HEX , VALS ( sccp_itu_global_title_indicator_values ) , GTI_MASK ,
" " , HFILL } } ,
{ & hf_sccp_called_ansi_global_title_indicator ,
{ " Global Title Indicator " , " sccp.called.gti " ,
FT_UINT8 , BASE_HEX , VALS ( sccp_ansi_global_title_indicator_values ) , GTI_MASK ,
" " , HFILL } } ,
{ & hf_sccp_called_itu_ssn_indicator ,
{ " SubSystem Number Indicator " , " sccp.called.ssni " ,
FT_UINT8 , BASE_HEX , VALS ( sccp_ai_ssni_values ) , ITU_SSN_INDICATOR_MASK ,
" " , HFILL } } ,
{ & hf_sccp_called_itu_point_code_indicator ,
{ " Point Code Indicator " , " sccp.called.pci " ,
FT_UINT8 , BASE_HEX , VALS ( sccp_ai_pci_values ) , ITU_PC_INDICATOR_MASK ,
" " , HFILL } } ,
{ & hf_sccp_called_ansi_ssn_indicator ,
{ " SubSystem Number Indicator " , " sccp.called.ssni " ,
FT_UINT8 , BASE_HEX , VALS ( sccp_ai_ssni_values ) , ANSI_SSN_INDICATOR_MASK ,
" " , HFILL } } ,
{ & hf_sccp_called_ansi_point_code_indicator ,
{ " Point Code Indicator " , " sccp.called.pci " ,
FT_UINT8 , BASE_HEX , VALS ( sccp_ai_pci_values ) , ANSI_PC_INDICATOR_MASK ,
" " , HFILL } } ,
{ & hf_sccp_called_ssn ,
{ " SubSystem Number " , " sccp.called.ssn " ,
FT_UINT8 , BASE_DEC , VALS ( sccp_ssn_values ) , 0x0 ,
" " , HFILL } } ,
{ & hf_sccp_called_itu_pc ,
{ " PC " , " sccp.called.pc " ,
FT_UINT16 , BASE_DEC , NULL , ITU_PC_MASK ,
" " , HFILL } } ,
2003-01-02 20:44:32 +00:00
{ & hf_sccp_called_ansi_pc ,
{ " PC " , " sccp.called.ansi_pc " ,
FT_STRING , BASE_NONE , NULL , 0x0 ,
" " , HFILL } } ,
2003-04-10 18:52:15 +00:00
{ & hf_sccp_called_chinese_pc ,
{ " PC " , " sccp.called.chinese_pc " ,
FT_STRING , BASE_NONE , NULL , 0x0 ,
" " , HFILL } } ,
2006-04-05 16:03:36 +00:00
{ & hf_sccp_called_japan_pc ,
{ " PC " , " sccp.called.pc " ,
FT_UINT16 , BASE_DEC , NULL , 0x0 ,
" " , HFILL } } ,
2002-03-04 22:39:22 +00:00
{ & hf_sccp_called_pc_network ,
{ " PC Network " ,
" sccp.called.network " ,
FT_UINT24 , BASE_DEC , NULL , ANSI_NETWORK_MASK ,
" " , HFILL } } ,
{ & hf_sccp_called_pc_cluster ,
{ " PC Cluster " ,
" sccp.called.cluster " ,
FT_UINT24 , BASE_DEC , NULL , ANSI_CLUSTER_MASK ,
" " , HFILL } } ,
{ & hf_sccp_called_pc_member ,
{ " PC Member " ,
" sccp.called.member " ,
FT_UINT24 , BASE_DEC , NULL , ANSI_MEMBER_MASK ,
" " , HFILL } } ,
{ & hf_sccp_called_gt_nai ,
{ " Nature of Address Indicator " ,
" sccp.called.nai " ,
FT_UINT8 , BASE_HEX , VALS ( sccp_nai_values ) , GT_NAI_MASK ,
" " , HFILL } } ,
{ & hf_sccp_called_gt_oe ,
{ " Odd/Even Indicator " ,
" sccp.called.oe " ,
FT_UINT8 , BASE_HEX , VALS ( sccp_oe_values ) , GT_OE_MASK ,
" " , HFILL } } ,
{ & hf_sccp_called_gt_tt ,
{ " Translation Type " ,
" sccp.called.tt " ,
FT_UINT8 , BASE_HEX , NULL , 0x0 ,
" " , HFILL } } ,
{ & hf_sccp_called_gt_np ,
{ " Numbering Plan " ,
" sccp.called.np " ,
FT_UINT8 , BASE_HEX , VALS ( sccp_np_values ) , GT_NP_MASK ,
" " , HFILL } } ,
{ & hf_sccp_called_gt_es ,
{ " Encoding Scheme " ,
" sccp.called.es " ,
FT_UINT8 , BASE_HEX , VALS ( sccp_es_values ) , GT_ES_MASK ,
" " , HFILL } } ,
{ & hf_sccp_called_gt_digits ,
{ " GT Digits " ,
" sccp.called.digits " ,
FT_STRING , BASE_NONE , NULL , 0x0 ,
" " , HFILL } } ,
{ & hf_sccp_calling_national_indicator ,
{ " National Indicator " , " sccp.calling.ni " ,
FT_UINT8 , BASE_HEX , VALS ( sccp_national_indicator_values ) , ANSI_NATIONAL_MASK ,
" " , HFILL } } ,
{ & hf_sccp_calling_routing_indicator ,
{ " Routing Indicator " , " sccp.calling.ri " ,
FT_UINT8 , BASE_HEX , VALS ( sccp_routing_indicator_values ) , ROUTING_INDICATOR_MASK ,
" " , HFILL } } ,
{ & hf_sccp_calling_itu_global_title_indicator ,
{ " Global Title Indicator " , " sccp.calling.gti " ,
FT_UINT8 , BASE_HEX , VALS ( sccp_itu_global_title_indicator_values ) , GTI_MASK ,
" " , HFILL } } ,
{ & hf_sccp_calling_ansi_global_title_indicator ,
{ " Global Title Indicator " , " sccp.calling.gti " ,
FT_UINT8 , BASE_HEX , VALS ( sccp_ansi_global_title_indicator_values ) , GTI_MASK ,
" " , HFILL } } ,
{ & hf_sccp_calling_itu_ssn_indicator ,
{ " SubSystem Number Indicator " , " sccp.calling.ssni " ,
FT_UINT8 , BASE_HEX , VALS ( sccp_ai_ssni_values ) , ITU_SSN_INDICATOR_MASK ,
" " , HFILL } } ,
{ & hf_sccp_calling_itu_point_code_indicator ,
{ " Point Code Indicator " , " sccp.calling.pci " ,
FT_UINT8 , BASE_HEX , VALS ( sccp_ai_pci_values ) , ITU_PC_INDICATOR_MASK ,
" " , HFILL } } ,
{ & hf_sccp_calling_ansi_ssn_indicator ,
{ " SubSystem Number Indicator " , " sccp.calling.ssni " ,
FT_UINT8 , BASE_HEX , VALS ( sccp_ai_ssni_values ) , ANSI_SSN_INDICATOR_MASK ,
" " , HFILL } } ,
{ & hf_sccp_calling_ansi_point_code_indicator ,
{ " Point Code Indicator " , " sccp.calling.pci " ,
FT_UINT8 , BASE_HEX , VALS ( sccp_ai_pci_values ) , ANSI_PC_INDICATOR_MASK ,
" " , HFILL } } ,
{ & hf_sccp_calling_ssn ,
{ " SubSystem Number " , " sccp.calling.ssn " ,
FT_UINT8 , BASE_DEC , VALS ( sccp_ssn_values ) , 0x0 ,
" " , HFILL } } ,
{ & hf_sccp_calling_itu_pc ,
{ " PC " , " sccp.calling.pc " ,
FT_UINT16 , BASE_DEC , NULL , ITU_PC_MASK ,
" " , HFILL } } ,
2003-01-02 20:44:32 +00:00
{ & hf_sccp_calling_ansi_pc ,
{ " PC " , " sccp.calling.ansi_pc " ,
FT_STRING , BASE_NONE , NULL , 0x0 ,
" " , HFILL } } ,
2003-04-10 18:52:15 +00:00
{ & hf_sccp_calling_chinese_pc ,
{ " PC " , " sccp.calling.chinese_pc " ,
FT_STRING , BASE_NONE , NULL , 0x0 ,
" " , HFILL } } ,
2006-04-05 16:03:36 +00:00
{ & hf_sccp_calling_japan_pc ,
{ " PC " , " sccp.calling.pc " ,
FT_UINT16 , BASE_DEC , NULL , 0x0 ,
" " , HFILL } } ,
2002-03-04 22:39:22 +00:00
{ & hf_sccp_calling_pc_network ,
{ " PC Network " ,
" sccp.calling.network " ,
FT_UINT24 , BASE_DEC , NULL , ANSI_NETWORK_MASK ,
" " , HFILL } } ,
{ & hf_sccp_calling_pc_cluster ,
{ " PC Cluster " ,
" sccp.calling.cluster " ,
FT_UINT24 , BASE_DEC , NULL , ANSI_CLUSTER_MASK ,
" " , HFILL } } ,
{ & hf_sccp_calling_pc_member ,
{ " PC Member " ,
" sccp.calling.member " ,
FT_UINT24 , BASE_DEC , NULL , ANSI_MEMBER_MASK ,
" " , HFILL } } ,
{ & hf_sccp_calling_gt_nai ,
{ " Nature of Address Indicator " ,
" sccp.calling.nai " ,
FT_UINT8 , BASE_HEX , VALS ( sccp_nai_values ) , GT_NAI_MASK ,
" " , HFILL } } ,
{ & hf_sccp_calling_gt_oe ,
{ " Odd/Even Indicator " ,
" sccp.calling.oe " ,
FT_UINT8 , BASE_HEX , VALS ( sccp_oe_values ) , GT_OE_MASK ,
" " , HFILL } } ,
{ & hf_sccp_calling_gt_tt ,
{ " Translation Type " ,
" sccp.calling.tt " ,
FT_UINT8 , BASE_HEX , NULL , 0x0 ,
" " , HFILL } } ,
{ & hf_sccp_calling_gt_np ,
{ " Numbering Plan " ,
" sccp.calling.np " ,
FT_UINT8 , BASE_HEX , VALS ( sccp_np_values ) , GT_NP_MASK ,
" " , HFILL } } ,
{ & hf_sccp_calling_gt_es ,
{ " Encoding Scheme " ,
" sccp.calling.es " ,
FT_UINT8 , BASE_HEX , VALS ( sccp_es_values ) , GT_ES_MASK ,
" " , HFILL } } ,
{ & hf_sccp_calling_gt_digits ,
{ " GT Digits " ,
" sccp.calling.digits " ,
FT_STRING , BASE_NONE , NULL , 0x0 ,
" " , HFILL } } ,
{ & hf_sccp_dlr ,
{ " Destination Local Reference " , " sccp.dlr " ,
FT_UINT24 , BASE_HEX , NULL , 0x0 ,
" " , HFILL } } ,
{ & hf_sccp_slr ,
{ " Source Local Reference " , " sccp.slr " ,
FT_UINT24 , BASE_HEX , NULL , 0x0 ,
" " , HFILL } } ,
2005-12-13 22:07:09 +00:00
{ & hf_sccp_lr ,
{ " Local Reference " , " sccp.lr " ,
FT_UINT24 , BASE_HEX , NULL , 0x0 ,
" " , HFILL } } ,
2002-03-04 22:39:22 +00:00
{ & hf_sccp_class ,
{ " Class " , " sccp.class " ,
FT_UINT8 , BASE_HEX , NULL , CLASS_CLASS_MASK ,
" " , HFILL } } ,
{ & hf_sccp_handling ,
{ " Message handling " , " sccp.handling " ,
FT_UINT8 , BASE_HEX , VALS ( sccp_class_handling_values ) , CLASS_SPARE_HANDLING_MASK ,
" " , HFILL } } ,
{ & hf_sccp_more ,
{ " More data " , " sccp.more " ,
FT_UINT8 , BASE_HEX , VALS ( sccp_segmenting_reassembling_values ) , SEGMENTING_REASSEMBLING_MASK ,
" " , HFILL } } ,
{ & hf_sccp_rsn ,
{ " Receive Sequence Number " , " sccp.rsn " ,
FT_UINT8 , BASE_HEX , NULL , RSN_MASK ,
" " , HFILL } } ,
{ & hf_sccp_sequencing_segmenting_ssn ,
{ " Sequencing Segmenting: Send Sequence Number " , " sccp.sequencing_segmenting.ssn " ,
FT_UINT8 , BASE_HEX , NULL , SEND_SEQUENCE_NUMBER_MASK ,
" " , HFILL } } ,
{ & hf_sccp_sequencing_segmenting_rsn ,
{ " Sequencing Segmenting: Receive Sequence Number " , " sccp.sequencing_segmenting.rsn " ,
FT_UINT8 , BASE_HEX , NULL , RECEIVE_SEQUENCE_NUMBER_MASK ,
" " , HFILL } } ,
{ & hf_sccp_sequencing_segmenting_more ,
{ " Sequencing Segmenting: More " , " sccp.sequencing_segmenting.more " ,
FT_UINT8 , BASE_HEX , VALS ( sccp_segmenting_reassembling_values ) , SEQUENCING_SEGMENTING_MORE_MASK ,
" " , HFILL } } ,
{ & hf_sccp_credit ,
{ " Credit " , " sccp.credit " ,
FT_UINT8 , BASE_HEX , NULL , 0x0 ,
" " , HFILL } } ,
{ & hf_sccp_release_cause ,
{ " Release Cause " , " sccp.release_cause " ,
FT_UINT8 , BASE_HEX , VALS ( sccp_release_cause_values ) , 0x0 ,
" " , HFILL } } ,
{ & hf_sccp_return_cause ,
{ " Return Cause " , " sccp.return_cause " ,
FT_UINT8 , BASE_HEX , VALS ( sccp_return_cause_values ) , 0x0 ,
" " , HFILL } } ,
{ & hf_sccp_reset_cause ,
{ " Reset Cause " , " sccp.reset_cause " ,
FT_UINT8 , BASE_HEX , VALS ( sccp_reset_cause_values ) , 0x0 ,
" " , HFILL } } ,
{ & hf_sccp_error_cause ,
{ " Error Cause " , " sccp.error_cause " ,
FT_UINT8 , BASE_HEX , VALS ( sccp_error_cause_values ) , 0x0 ,
" " , HFILL } } ,
{ & hf_sccp_refusal_cause ,
{ " Refusal Cause " , " sccp.refusal_cause " ,
FT_UINT8 , BASE_HEX , VALS ( sccp_refusal_cause_values ) , 0x0 ,
" " , HFILL } } ,
{ & hf_sccp_segmentation_first ,
{ " Segmentation: First " , " sccp.segmentation.first " ,
FT_UINT8 , BASE_HEX , VALS ( sccp_segmentation_first_segment_values ) , SEGMENTATION_FIRST_SEGMENT_MASK ,
" " , HFILL } } ,
{ & hf_sccp_segmentation_class ,
{ " Segmentation: Class " , " sccp.segmentation.class " ,
FT_UINT8 , BASE_HEX , VALS ( sccp_segmentation_class_values ) , SEGMENTATION_CLASS_MASK ,
" " , HFILL } } ,
{ & hf_sccp_segmentation_remaining ,
{ " Segmentation: Remaining " , " sccp.segmentation.remaining " ,
FT_UINT8 , BASE_HEX , NULL , SEGMENTATION_REMAINING_MASK ,
" " , HFILL } } ,
{ & hf_sccp_segmentation_slr ,
{ " Segmentation: Source Local Reference " , " sccp.segmentation.slr " ,
FT_UINT24 , BASE_HEX , NULL , 0x0 ,
" " , HFILL } } ,
{ & hf_sccp_hop_counter ,
{ " Hop Counter " , " sccp.hops " ,
FT_UINT8 , BASE_HEX , NULL , 0x0 ,
" " , HFILL } } ,
{ & hf_sccp_importance ,
{ " Importance " , " sccp.importance " ,
FT_UINT8 , BASE_HEX , NULL , IMPORTANCE_IMPORTANCE_MASK ,
" " , HFILL } } ,
/* ISNI is ANSI only */
{ & hf_sccp_ansi_isni_mi ,
{ " ISNI Mark for Identification Indicator " , " sccp.isni.mi " ,
2003-06-26 06:28:47 +00:00
FT_UINT8 , BASE_HEX , VALS ( sccp_isni_mark_for_id_values ) , ANSI_ISNI_MI_MASK ,
2002-03-04 22:39:22 +00:00
" " , HFILL } } ,
{ & hf_sccp_ansi_isni_iri ,
{ " ISNI Routing Indicator " , " sccp.isni.iri " ,
2003-06-26 06:28:47 +00:00
FT_UINT8 , BASE_HEX , VALS ( sccp_isni_iri_values ) , ANSI_ISNI_IRI_MASK ,
2002-03-04 22:39:22 +00:00
" " , HFILL } } ,
{ & hf_sccp_ansi_isni_ti ,
{ " ISNI Type Indicator " , " sccp.isni.ti " ,
2003-06-26 06:28:47 +00:00
FT_UINT8 , BASE_HEX , VALS ( sccp_isni_ti_values ) , ANSI_ISNI_TI_MASK ,
2002-03-04 22:39:22 +00:00
" " , HFILL } } ,
{ & hf_sccp_ansi_isni_netspec ,
{ " ISNI Network Specific (Type 1) " , " sccp.isni.netspec " ,
FT_UINT8 , BASE_HEX , NULL , ANSI_ISNI_NETSPEC_MASK ,
" " , HFILL } } ,
{ & hf_sccp_ansi_isni_counter ,
{ " ISNI Counter " , " sccp.isni.counter " ,
2007-08-15 21:07:01 +00:00
FT_UINT8 , BASE_DEC , NULL , ANSI_ISNI_COUNTER_MASK ,
2002-03-04 22:39:22 +00:00
" " , HFILL } } ,
2007-01-19 17:25:13 +00:00
{ & hf_sccp_xudt_msg_fragments ,
{ " Message fragments " , " sccp.msg.fragments " ,
FT_NONE , BASE_NONE , NULL , 0x00 , NULL , HFILL }
} ,
{ & hf_sccp_xudt_msg_fragment ,
{ " Message fragment " , " sccp.msg.fragment " ,
FT_FRAMENUM , BASE_NONE , NULL , 0x00 , NULL , HFILL }
} ,
{ & hf_sccp_xudt_msg_fragment_overlap ,
{ " Message fragment overlap " , " sccp.msg.fragment.overlap " ,
FT_BOOLEAN , BASE_NONE , NULL , 0x00 , NULL , HFILL }
} ,
{ & hf_sccp_xudt_msg_fragment_overlap_conflicts ,
{ " Message fragment overlapping with conflicting data " , " sccp.msg.fragment.overlap.conflicts " ,
FT_BOOLEAN , BASE_NONE , NULL , 0x00 , NULL , HFILL }
} ,
{ & hf_sccp_xudt_msg_fragment_multiple_tails ,
{ " Message has multiple tail fragments " , " sccp.msg.fragment.multiple_tails " ,
FT_BOOLEAN , BASE_NONE , NULL , 0x00 , NULL , HFILL }
} ,
{ & hf_sccp_xudt_msg_fragment_too_long_fragment ,
{ " Message fragment too long " , " sccp.msg.fragment.too_long_fragment " ,
FT_BOOLEAN , BASE_NONE , NULL , 0x00 , NULL , HFILL }
} ,
{ & hf_sccp_xudt_msg_fragment_error ,
{ " Message defragmentation error " , " sccp.msg.fragment.error " ,
FT_FRAMENUM , BASE_NONE , NULL , 0x00 , NULL , HFILL }
} ,
{ & hf_sccp_xudt_msg_reassembled_in ,
{ " Reassembled in " , " sccp.msg.reassembled.in " ,
FT_FRAMENUM , BASE_NONE , NULL , 0x00 , NULL , HFILL }
2007-03-03 23:38:35 +00:00
} ,
{ & hf_sccp_assoc_id ,
{ " Association ID " , " sccp.assoc.id " ,
FT_UINT32 , BASE_DEC , NULL , 0x0 , " " , HFILL } } ,
{ & hf_sccp_assoc_msg ,
{ " Message in frame " , " sccp.assoc.msg " ,
FT_FRAMENUM , BASE_NONE , NULL , 0x00 , " " , HFILL }
} ,
2002-03-04 22:39:22 +00:00
} ;
/* Setup protocol subtree array */
static gint * ett [ ] = {
& ett_sccp ,
& ett_sccp_called ,
& ett_sccp_called_ai ,
& ett_sccp_called_pc ,
& ett_sccp_called_gt ,
& ett_sccp_calling ,
& ett_sccp_calling_ai ,
& ett_sccp_calling_pc ,
& ett_sccp_calling_gt ,
& ett_sccp_sequencing_segmenting ,
2002-04-13 22:34:17 +00:00
& ett_sccp_segmentation ,
& ett_sccp_ansi_isni_routing_control ,
2006-01-19 05:51:59 +00:00
& ett_sccp_xudt_msg_fragment ,
2007-03-03 23:38:35 +00:00
& ett_sccp_xudt_msg_fragments ,
2008-01-09 22:01:57 +00:00
& ett_sccp_assoc ,
& ett_sccp_digits
2002-03-04 22:39:22 +00:00
} ;
2007-07-26 20:05:54 +00:00
2007-04-03 19:08:00 +00:00
static uat_field_t users_flds [ ] = {
UAT_FLD_DEC ( sccp_users , ni , " Network Indicator " ) ,
UAT_FLD_RANGE ( sccp_users , called_pc , 65535 , " DPCs for which this protocol is to be used " ) ,
UAT_FLD_RANGE ( sccp_users , called_ssn , 65535 , " Called SSNs for which this protocol is to be used " ) ,
UAT_FLD_VS ( sccp_users , user , sccp_users_vals , " The User Protocol " ) ,
UAT_END_FIELDS
} ;
uat_t * users_uat = uat_new ( " SCCP Users Table " ,
sizeof ( sccp_user_t ) ,
" sccp_users " ,
2008-03-06 22:13:24 +00:00
TRUE ,
2007-04-03 19:08:00 +00:00
( void * * ) & sccp_users ,
& num_sccp_users ,
UAT_CAT_PORTS ,
" ChSccpUsers " ,
sccp_users_copy_cb ,
sccp_users_update_cb ,
sccp_users_free_cb ,
users_flds ) ;
2007-07-26 20:05:54 +00:00
2007-04-03 19:08:00 +00:00
/* Register the protocol name and description */
2002-03-04 22:39:22 +00:00
proto_sccp = proto_register_protocol ( " Signalling Connection Control Part " ,
" SCCP " , " sccp " ) ;
2003-11-06 09:28:40 +00:00
register_dissector ( " sccp " , dissect_sccp , proto_sccp ) ;
2002-03-04 22:39:22 +00:00
/* Required function calls to register the header fields and subtrees used */
proto_register_field_array ( proto_sccp , hf , array_length ( hf ) ) ;
proto_register_subtree_array ( ett , array_length ( ett ) ) ;
2007-04-03 19:08:00 +00:00
2002-03-04 22:39:22 +00:00
sccp_ssn_dissector_table = register_dissector_table ( " sccp.ssn " , " SCCP SSN " , FT_UINT8 , BASE_DEC ) ;
2003-10-22 20:12:02 +00:00
register_heur_dissector_list ( " sccp " , & heur_subdissector_list ) ;
2003-12-08 21:36:53 +00:00
sccp_module = prefs_register_protocol ( proto_sccp , NULL ) ;
prefs_register_uint_preference ( sccp_module , " source_pc " ,
" Source PC " ,
" The source point code (usually MSC) (to determine whether message is uplink or downlink) " ,
16 , & sccp_source_pc_global ) ;
2007-01-19 17:25:13 +00:00
prefs_register_bool_preference ( sccp_module , " show_length " , " Show length " ,
" Show parameter length in the protocol tree " ,
& sccp_show_length ) ;
2006-01-20 19:32:59 +00:00
prefs_register_bool_preference ( sccp_module , " defragment_xudt " ,
2007-01-19 17:25:13 +00:00
" Reassemble XUDT messages " ,
" Whether XUDT messages should be reassembled " ,
& sccp_xudt_desegment ) ;
2005-12-13 22:07:09 +00:00
2007-03-03 23:38:35 +00:00
prefs_register_bool_preference ( sccp_module , " trace_sccp " ,
" Trace Associations " ,
" Whether to keep infomation about messages and their associations " ,
& trace_sccp ) ;
2007-03-24 13:46:41 +00:00
2007-03-22 22:59:20 +00:00
prefs_register_bool_preference ( sccp_module , " show_more_info " ,
2007-04-16 08:37:39 +00:00
" Show key parameters in Info Column " ,
" Show SLR, DLR, and CAUSE Parameters in the Information Column of the Summary " ,
& show_key_params ) ;
2007-03-24 13:46:41 +00:00
2007-04-03 19:08:00 +00:00
prefs_register_uat_preference ( sccp_module , " users_table " , " Users Table " ,
2007-04-16 08:37:39 +00:00
" A table that enumerates user protocols to be used against specific PCs and SSNs " ,
users_uat ) ;
2007-03-03 23:38:35 +00:00
2005-12-13 22:07:09 +00:00
register_init_routine ( & init_sccp ) ;
2007-01-19 17:25:13 +00:00
2006-08-14 08:29:29 +00:00
assocs = se_tree_create ( EMEM_TREE_TYPE_RED_BLACK , " sccp_associations " ) ;
2006-03-11 15:30:52 +00:00
2007-03-21 00:48:46 +00:00
sccp_tap = register_tap ( " sccp " ) ;
2002-03-04 22:39:22 +00:00
}
void
proto_reg_handoff_sccp ( void )
{
dissector_handle_t sccp_handle ;
2003-11-06 09:28:40 +00:00
sccp_handle = find_dissector ( " sccp " ) ;
2002-03-04 22:39:22 +00:00
2008-03-27 23:09:22 +00:00
dissector_add ( " wtap_encap " , WTAP_ENCAP_SCCP , sccp_handle ) ;
2002-03-04 22:39:22 +00:00
dissector_add ( " mtp3.service_indicator " , SCCP_SI , sccp_handle ) ;
2004-09-16 19:17:42 +00:00
dissector_add_string ( " tali.opcode " , " sccp " , sccp_handle ) ;
2002-03-04 22:39:22 +00:00
data_handle = find_dissector ( " data " ) ;
2007-04-03 19:08:00 +00:00
tcap_handle = find_dissector ( " tcap " ) ;
ranap_handle = find_dissector ( " ranap " ) ;
bssap_handle = find_dissector ( " bssap " ) ;
gsmmap_handle = find_dissector ( " gsm_map " ) ;
camel_handle = find_dissector ( " camel " ) ;
inap_handle = find_dissector ( " inap " ) ;
2002-03-04 22:39:22 +00:00
}
2007-01-19 17:25:13 +00:00