diff options
Diffstat (limited to 'epan/dissectors/packet-sccp.c')
-rw-r--r-- | epan/dissectors/packet-sccp.c | 4295 |
1 files changed, 2197 insertions, 2098 deletions
diff --git a/epan/dissectors/packet-sccp.c b/epan/dissectors/packet-sccp.c index ba37d39acd..0d45ca988d 100644 --- a/epan/dissectors/packet-sccp.c +++ b/epan/dissectors/packet-sccp.c @@ -35,11 +35,11 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ + #ifdef HAVE_CONFIG_H # include "config.h" #endif -#include <stdlib.h> #include <string.h> #include <glib.h> @@ -52,14 +52,14 @@ #include <epan/uat.h> #include <epan/strutil.h> #include <epan/expert.h> +#include <epan/tap.h> +#include <address.h> #include "packet-mtp3.h" #include "packet-tcap.h" #include "packet-sccp.h" #include "packet-e164.h" #include "packet-e212.h" #include "packet-frame.h" -#include <epan/tap.h> -#include <address.h> /* function prototypes */ void proto_reg_handoff_sccp(void); @@ -68,174 +68,174 @@ static Standard_Type decode_mtp3_standard; #define SCCP_MSG_TYPE_OFFSET 0 #define SCCP_MSG_TYPE_LENGTH 1 -#define POINTER_LENGTH 1 -#define POINTER_LENGTH_LONG 2 +#define POINTER_LENGTH 1 +#define POINTER_LENGTH_LONG 2 #define INVALID_LR 0xffffff /* a reserved value */ /* Same as below but with names typed out */ static const value_string sccp_message_type_values[] = { - { 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" }, - { SCCP_MSG_TYPE_LUDTS, "Long Unitdata Service" }, - { 0, NULL } }; + { 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" }, + { SCCP_MSG_TYPE_LUDTS, "Long Unitdata Service" }, + { 0, NULL } }; /* Same as above but in acronym form (for the Info column) */ 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" }, - { 0, NULL } }; - -#define PARAMETER_LENGTH_LENGTH 1 -#define PARAMETER_LONG_DATA_LENGTH_LENGTH 2 -#define PARAMETER_TYPE_LENGTH 1 - -#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 -#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 + { 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" }, + { 0, NULL } }; + +#define PARAMETER_LENGTH_LENGTH 1 +#define PARAMETER_LONG_DATA_LENGTH_LENGTH 2 +#define PARAMETER_TYPE_LENGTH 1 + +#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 +#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 /* Importance is ITU only */ -#define PARAMETER_IMPORTANCE 0x12 -#define PARAMETER_LONG_DATA 0x13 +#define PARAMETER_IMPORTANCE 0x12 +#define PARAMETER_LONG_DATA 0x13 /* ISNI is ANSI only */ -#define PARAMETER_ISNI 0xfa +#define PARAMETER_ISNI 0xfa static const value_string sccp_parameter_values[] = { - { 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" }, - { PARAMETER_ISNI, "Intermediate Signaling Network Identification (ANSI)" }, - { 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 + { 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" }, + { PARAMETER_ISNI, "Intermediate Signaling Network Identification (ANSI)" }, + { 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 /* Parts of the Called and Calling Address parameters */ /* Address Indicator */ -#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 +#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 static const value_string sccp_national_indicator_values[] = { { 0x0, "Address coded to International standard" }, { 0x1, "Address coded to National standard" }, { 0, NULL } }; -#define ROUTE_ON_GT 0x0 -#define ROUTE_ON_SSN 0x1 -#define ROUTING_INDICATOR_SHIFT 6 +#define ROUTE_ON_GT 0x0 +#define ROUTE_ON_SSN 0x1 +#define ROUTING_INDICATOR_SHIFT 6 static const value_string sccp_routing_indicator_values[] = { { ROUTE_ON_GT, "Route on GT" }, { ROUTE_ON_SSN, "Route on SSN" }, - { 0, NULL } }; + { 0, NULL } }; -#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 +#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 static const value_string sccp_itu_global_title_indicator_values[] = { - { 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 */ + { 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 */ static const value_string sccp_ansi_global_title_indicator_values[] = { - { 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 } }; + { 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 } }; static const value_string sccp_ai_pci_values[] = { { 0x1, "Point Code present" }, @@ -247,12 +247,12 @@ static const value_string sccp_ai_ssni_values[] = { { 0x0, "SSN not present" }, { 0, NULL } }; -#define ADDRESS_SSN_LENGTH 1 -#define INVALID_SSN 0xff - /* Some values from 3GPP TS 23.003 */ - /* Japan TTC and NTT define a lot of SSNs, some of which conflict with - * these. They are not added for now. - */ +#define ADDRESS_SSN_LENGTH 1 +#define INVALID_SSN 0xff +/* Some values from 3GPP TS 23.003 */ +/* Japan TTC and NTT define a lot of SSNs, some of which conflict with + * these. They are not added for now. + */ static const value_string sccp_ssn_values[] = { { 0x00, "SSN not known/not used" }, { 0x01, "SCCP management" }, @@ -295,27 +295,27 @@ static const value_string sccp_ssn_values[] = { * * * * * * * * * * * * * * * * */ #define GT_NAI_MASK 0x7F #define GT_NAI_LENGTH 1 -#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 +#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 static const value_string sccp_nai_values[] = { - { 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 } }; + { 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 } }; #define GT_OE_MASK 0x80 #define GT_OE_EVEN 0 #define GT_OE_ODD 1 static const value_string sccp_oe_values[] = { - { GT_OE_EVEN, "Even number of address signals" }, - { GT_OE_ODD, "Odd number of address signals" }, - { 0, NULL } }; + { GT_OE_EVEN, "Even number of address signals" }, + { GT_OE_ODD, "Odd number of address signals" }, + { 0, NULL } }; const value_string sccp_address_signal_values[] = { { 0, "0" }, @@ -346,31 +346,31 @@ const value_string sccp_address_signal_values[] = { /* * * * * * * * * * * * * * * * * * * * * * * * * * * Global Title: ITU GTI == 0011, ANSI GTI == 0001 * * * * * * * * * * * * * * * * * * * * * * * * * * */ -#define GT_NP_MASK 0xf0 -#define GT_NP_SHIFT 4 -#define GT_NP_ES_LENGTH 1 -#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 +#define GT_NP_MASK 0xf0 +#define GT_NP_SHIFT 4 +#define GT_NP_ES_LENGTH 1 +#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 static const value_string sccp_np_values[] = { - { 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 } }; + { 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 } }; #define GT_ES_MASK 0x0f #define GT_ES_UNKNOWN 0x0 @@ -379,12 +379,12 @@ static const value_string sccp_np_values[] = { #define GT_ES_NATIONAL 0x3 #define GT_ES_RESERVED 0xf static const value_string sccp_es_values[] = { - { 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 } }; + { 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 } }; /* Address signals above */ @@ -398,9 +398,9 @@ static const value_string sccp_es_values[] = { /* Address signals above */ -#define CLASS_CLASS_MASK 0xf -#define CLASS_SPARE_HANDLING_MASK 0xf0 -#define CLASS_SPARE_HANDLING_SHIFT 4 +#define CLASS_CLASS_MASK 0xf +#define CLASS_SPARE_HANDLING_MASK 0xf0 +#define CLASS_SPARE_HANDLING_SHIFT 4 static const value_string sccp_class_handling_values [] = { { 0x0, "No special options" }, { 0x8, "Return message on error" }, @@ -413,20 +413,20 @@ static const value_string sccp_class_handling_values [] = { #define MORE_DATA 1 /* This is also used by sequencing-segmenting parameter */ static const value_string sccp_segmenting_reassembling_values [] = { - { NO_MORE_DATA, "No more data" }, - { MORE_DATA, "More data" }, - { 0, NULL } }; + { NO_MORE_DATA, "No more data" }, + { MORE_DATA, "More data" }, + { 0, NULL } }; -#define RECEIVE_SEQUENCE_NUMBER_LENGTH 1 -#define RSN_MASK 0xfe +#define RECEIVE_SEQUENCE_NUMBER_LENGTH 1 +#define RSN_MASK 0xfe -#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 +#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 #define CREDIT_LENGTH 1 @@ -534,11 +534,11 @@ const value_string sccp_refusal_cause_values [] = { { 0, NULL } }; -#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 +#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 static const value_string sccp_segmentation_first_segment_values [] = { { 1, "First segment" }, { 0, "Not first segment" }, @@ -551,18 +551,18 @@ static const value_string sccp_segmentation_class_values [] = { #define HOP_COUNTER_LENGTH 1 -#define IMPORTANCE_LENGTH 1 -#define IMPORTANCE_IMPORTANCE_MASK 0x7 +#define IMPORTANCE_LENGTH 1 +#define IMPORTANCE_IMPORTANCE_MASK 0x7 #define ANSI_ISNI_ROUTING_CONTROL_LENGTH 1 -#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 +#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 static const value_string sccp_isni_mark_for_id_values [] = { { 0x0, "Do not identify networks" }, @@ -579,9 +579,9 @@ static const value_string sccp_isni_iri_values [] = { #define ANSI_ISNI_TYPE_0 0x0 #define ANSI_ISNI_TYPE_1 0x1 static const value_string sccp_isni_ti_values [] = { - { ANSI_ISNI_TYPE_0, "Type zero ISNI parameter format" }, - { ANSI_ISNI_TYPE_1, "Type one ISNI parameter format" }, - { 0, NULL } }; + { ANSI_ISNI_TYPE_0, "Type zero ISNI parameter format" }, + { ANSI_ISNI_TYPE_1, "Type one ISNI parameter format" }, + { 0, NULL } }; /* Initialize the protocol and registered fields */ @@ -716,49 +716,49 @@ static int sccp_tap = -1; 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, - &hf_sccp_xudt_msg_fragment_count, - /* Reassembled in field */ - &hf_sccp_xudt_msg_reassembled_in, - /* Reassembled length field */ - &hf_sccp_xudt_msg_reassembled_length, - /* Tag */ - "SCCP XUDT Message fragments" + /* 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, + &hf_sccp_xudt_msg_fragment_count, + /* Reassembled in field */ + &hf_sccp_xudt_msg_reassembled_in, + /* Reassembled length field */ + &hf_sccp_xudt_msg_reassembled_length, + /* Tag */ + "SCCP XUDT Message fragments" }; static GHashTable *sccp_xudt_msg_fragment_table = NULL; static GHashTable *sccp_xudt_msg_reassembled_table = NULL; -#define SCCP_USER_DATA 0 -#define SCCP_USER_TCAP 1 -#define SCCP_USER_RANAP 2 -#define SCCP_USER_BSSAP 3 +#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 +#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; + 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 sccp_user_t *sccp_users; +static guint num_sccp_users; static dissector_handle_t data_handle; static dissector_handle_t tcap_handle; @@ -769,25 +769,25 @@ static dissector_handle_t camel_handle; static dissector_handle_t inap_handle; static dissector_handle_t default_handle; -static const char *default_payload=NULL; +static const char *default_payload = NULL; static const 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 } + { 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 } }; /* * 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 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; @@ -803,670 +803,670 @@ static guint slr = 0; static dissector_table_t sccp_ssn_dissector_table; -static emem_tree_t* assocs = NULL; -static sccp_assoc_info_t* assoc; -static sccp_msg_info_t* sccp_msg; -static sccp_assoc_info_t no_assoc = {0,0,0,0,0,FALSE,FALSE,NULL,NULL,SCCP_PLOAD_NONE,NULL,NULL,NULL,0}; -static gboolean trace_sccp = FALSE; -static guint32 next_assoc_id = 0; +static emem_tree_t *assocs = NULL; +static sccp_assoc_info_t *assoc; +static sccp_msg_info_t *sccp_msg; +static sccp_assoc_info_t no_assoc = {0,0,0,0,0,FALSE,FALSE,NULL,NULL,SCCP_PLOAD_NONE,NULL,NULL,NULL,0}; +static gboolean trace_sccp = FALSE; +static guint32 next_assoc_id = 0; static const value_string assoc_protos[] = { - { SCCP_PLOAD_BSSAP, "BSSAP" }, - { SCCP_PLOAD_RANAP, "RANAP" }, - { 0, NULL } + { SCCP_PLOAD_BSSAP, "BSSAP" }, + { SCCP_PLOAD_RANAP, "RANAP" }, + { 0, NULL } }; #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) + ( 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) #define RETURN_FALSE \ - { \ - /*g_warning("Frame %d not protocol %d @ line %d", frame_num, my_mtp3_standard, __LINE__);*/ \ - return FALSE; \ - } + do { \ + /*g_warning("Frame %d not protocol %d @ line %d", frame_num, my_mtp3_standard, __LINE__);*/ \ + return FALSE; \ + } while (0) static gboolean sccp_called_calling_looks_valid(guint32 frame_num _U_, tvbuff_t *tvb, guint8 my_mtp3_standard, gboolean is_co) { - guint8 ai, ri, gti, ssni, pci; - guint8 len_needed = 1; /* need at least the Address Indicator */ - guint len = tvb_length(tvb); - - ai = tvb_get_guint8(tvb, 0); - if (my_mtp3_standard == ANSI_STANDARD && (ai & ANSI_NATIONAL_MASK) == 0) - RETURN_FALSE; - - gti = (ai & GTI_MASK) >> GTI_SHIFT; - if (my_mtp3_standard == ANSI_STANDARD) { - if (gti > 2) - RETURN_FALSE; - } else { - if (gti > 4) - RETURN_FALSE; - } - - ri = (ai & ROUTING_INDICATOR_MASK) >> ROUTING_INDICATOR_SHIFT; - if (my_mtp3_standard == ANSI_STANDARD) { - pci = ai & ANSI_PC_INDICATOR_MASK; - ssni = ai & ANSI_SSN_INDICATOR_MASK; - } else { - ssni = ai & ITU_SSN_INDICATOR_MASK; - pci = ai & ITU_PC_INDICATOR_MASK; - } + guint8 ai, ri, gti, ssni, pci; + guint8 len_needed = 1; /* need at least the Address Indicator */ + guint len = tvb_length(tvb); + + ai = tvb_get_guint8(tvb, 0); + if ((my_mtp3_standard == ANSI_STANDARD) && ((ai & ANSI_NATIONAL_MASK) == 0)) + RETURN_FALSE; + + gti = (ai & GTI_MASK) >> GTI_SHIFT; + if (my_mtp3_standard == ANSI_STANDARD) { + if (gti > 2) + RETURN_FALSE; + } else { + if (gti > 4) + RETURN_FALSE; + } - /* Route on SSN with no SSN? */ - if (ri == ROUTE_ON_SSN && ssni == 0) - RETURN_FALSE; + ri = (ai & ROUTING_INDICATOR_MASK) >> ROUTING_INDICATOR_SHIFT; + if (my_mtp3_standard == ANSI_STANDARD) { + pci = ai & ANSI_PC_INDICATOR_MASK; + ssni = ai & ANSI_SSN_INDICATOR_MASK; + } else { + ssni = ai & ITU_SSN_INDICATOR_MASK; + pci = ai & ITU_PC_INDICATOR_MASK; + } - /* Route on GT with no GT? */ - if (ri == ROUTE_ON_GT && gti == AI_GTI_NO_GT) - RETURN_FALSE; + /* Route on SSN with no SSN? */ + if ((ri == ROUTE_ON_SSN) && (ssni == 0)) + RETURN_FALSE; - /* GT routed and connection-oriented (Class-2)? - * Yes, that's theoretically possible, but it's not used. - */ - if (ri == ROUTE_ON_GT && is_co) - RETURN_FALSE; + /* Route on GT with no GT? */ + if ((ri == ROUTE_ON_GT) && (gti == AI_GTI_NO_GT)) + RETURN_FALSE; - if (ssni) - len_needed += ADDRESS_SSN_LENGTH; - if (pci) { - if (my_mtp3_standard == ANSI_STANDARD || - my_mtp3_standard == CHINESE_ITU_STANDARD) - len_needed += ANSI_PC_LENGTH; - else - len_needed += ITU_PC_LENGTH; - } - if (gti) - len_needed += 2; + /* GT routed and connection-oriented (Class-2)? + * Yes, that's theoretically possible, but it's not used. + */ + if ((ri == ROUTE_ON_GT) && is_co) + RETURN_FALSE; + + if (ssni) + len_needed += ADDRESS_SSN_LENGTH; + if (pci) { + if (my_mtp3_standard == ANSI_STANDARD || + my_mtp3_standard == CHINESE_ITU_STANDARD) + len_needed += ANSI_PC_LENGTH; + else + len_needed += ITU_PC_LENGTH; + } + if (gti) + len_needed += 2; - if (len_needed > len) - RETURN_FALSE; + if (len_needed > len) + RETURN_FALSE; - return TRUE; + return TRUE; } gboolean looks_like_valid_sccp(guint32 frame_num _U_, tvbuff_t *tvb, guint8 my_mtp3_standard) { - guint offset; - guint8 msgtype, msg_class, cause; - guint called_ptr = 0; - guint calling_ptr = 0; - guint data_ptr = 0; - guint opt_ptr = 0; - guint8 pointer_length = POINTER_LENGTH; - guint len = tvb_length(tvb); - - /* Ensure we can do some basic checks without throwing an exception. - * Accesses beyond this length need to check the length first because - * we don't want to throw an exception in here... - */ - if (len < 6) - RETURN_FALSE; + guint offset; + guint8 msgtype, msg_class, cause; + guint called_ptr = 0; + guint calling_ptr = 0; + guint data_ptr = 0; + guint opt_ptr = 0; + guint8 pointer_length = POINTER_LENGTH; + guint len = tvb_length(tvb); + + /* Ensure we can do some basic checks without throwing an exception. + * Accesses beyond this length need to check the length first because + * we don't want to throw an exception in here... + */ + if (len < 6) + RETURN_FALSE; + + msgtype = tvb_get_guint8(tvb, SCCP_MSG_TYPE_OFFSET); + if (!match_strval(msgtype, sccp_message_type_acro_values)) { + RETURN_FALSE; + } + offset = SCCP_MSG_TYPE_LENGTH; - msgtype = tvb_get_guint8(tvb, SCCP_MSG_TYPE_OFFSET); - if (!match_strval(msgtype, sccp_message_type_acro_values)) { - RETURN_FALSE; + switch (msgtype) { + case SCCP_MSG_TYPE_UDT: + case SCCP_MSG_TYPE_XUDT: + case SCCP_MSG_TYPE_LUDT: + case SCCP_MSG_TYPE_UDTS: + case SCCP_MSG_TYPE_XUDTS: + case SCCP_MSG_TYPE_LUDTS: + { + if (msgtype == SCCP_MSG_TYPE_XUDT || msgtype == SCCP_MSG_TYPE_XUDTS) { + if (SCCP_MSG_TYPE_LENGTH + + PROTOCOL_CLASS_LENGTH + /* or Cause for XUDTS */ + HOP_COUNTER_LENGTH + + POINTER_LENGTH + + POINTER_LENGTH + + POINTER_LENGTH + + POINTER_LENGTH > len) + RETURN_FALSE; } - offset = SCCP_MSG_TYPE_LENGTH; - - switch (msgtype) { - case SCCP_MSG_TYPE_UDT: - case SCCP_MSG_TYPE_XUDT: - case SCCP_MSG_TYPE_LUDT: - case SCCP_MSG_TYPE_UDTS: - case SCCP_MSG_TYPE_XUDTS: - case SCCP_MSG_TYPE_LUDTS: - { - if (msgtype == SCCP_MSG_TYPE_XUDT || msgtype == SCCP_MSG_TYPE_XUDTS) { - if (SCCP_MSG_TYPE_LENGTH + - PROTOCOL_CLASS_LENGTH + /* or Cause for XUDTS */ - HOP_COUNTER_LENGTH + - POINTER_LENGTH + - POINTER_LENGTH + - POINTER_LENGTH + - POINTER_LENGTH > len) - RETURN_FALSE; - } - - if (msgtype == SCCP_MSG_TYPE_LUDT || msgtype == SCCP_MSG_TYPE_LUDTS) { - if (SCCP_MSG_TYPE_LENGTH + - PROTOCOL_CLASS_LENGTH + /* or Cause for LUDTS */ - HOP_COUNTER_LENGTH + - POINTER_LENGTH_LONG + - POINTER_LENGTH_LONG + - POINTER_LENGTH_LONG + - POINTER_LENGTH_LONG > len) - RETURN_FALSE; - - pointer_length = POINTER_LENGTH_LONG; - } - - if (msgtype == SCCP_MSG_TYPE_UDT || msgtype == SCCP_MSG_TYPE_XUDT || - msgtype == SCCP_MSG_TYPE_LUDT) { - - msg_class = tvb_get_guint8(tvb, offset) & CLASS_CLASS_MASK; - if (msg_class > 1) - RETURN_FALSE; - offset += PROTOCOL_CLASS_LENGTH; - } - - if (msgtype == SCCP_MSG_TYPE_XUDT || msgtype == SCCP_MSG_TYPE_LUDT) - offset += HOP_COUNTER_LENGTH; - - if (msgtype == SCCP_MSG_TYPE_UDTS || - msgtype == SCCP_MSG_TYPE_XUDTS || - msgtype == SCCP_MSG_TYPE_LUDTS) { - - cause = tvb_get_guint8(tvb, offset); - if (!match_strval(cause, sccp_return_cause_values)) - RETURN_FALSE; - offset += RETURN_CAUSE_LENGTH; - } - - if (msgtype == SCCP_MSG_TYPE_XUDTS || msgtype == SCCP_MSG_TYPE_LUDTS) - offset += HOP_COUNTER_LENGTH; - - if (msgtype == SCCP_MSG_TYPE_LUDT || msgtype == SCCP_MSG_TYPE_LUDTS) - called_ptr = tvb_get_letohs(tvb, offset); - else - called_ptr = tvb_get_guint8(tvb, offset); - if (called_ptr == 0) /* Mandatory variable parameters must be present */ - RETURN_FALSE; - called_ptr += offset; - offset += pointer_length; - - if (msgtype == SCCP_MSG_TYPE_LUDT || msgtype == SCCP_MSG_TYPE_LUDTS) - calling_ptr = tvb_get_letohs(tvb, offset); - else - calling_ptr = tvb_get_guint8(tvb, offset); - if (calling_ptr == 0) /* Mandatory variable parameters must be present */ - RETURN_FALSE; - calling_ptr += offset; - offset += pointer_length; - - if (msgtype == SCCP_MSG_TYPE_LUDT || msgtype == SCCP_MSG_TYPE_LUDTS) - data_ptr = tvb_get_letohs(tvb, offset); - else - data_ptr = tvb_get_guint8(tvb, offset); - if (data_ptr == 0) /* Mandatory variable parameters must be present */ - RETURN_FALSE; - data_ptr += offset; - offset += pointer_length; - - if (msgtype == SCCP_MSG_TYPE_XUDT || msgtype == SCCP_MSG_TYPE_XUDTS) { - opt_ptr = tvb_get_guint8(tvb, offset); - offset += POINTER_LENGTH; - } else if (msgtype == SCCP_MSG_TYPE_LUDT || msgtype == SCCP_MSG_TYPE_LUDTS) { - opt_ptr = tvb_get_letohs(tvb, offset); - offset += POINTER_LENGTH_LONG; - } - - if (msgtype == SCCP_MSG_TYPE_LUDT || msgtype == SCCP_MSG_TYPE_LUDTS) { - /* Long pointers count from the 2nd (MSB) octet of the pointer */ - called_ptr += 1; - calling_ptr += 1; - data_ptr += 1; - if (opt_ptr) - opt_ptr += 1; - } - - /* Check that the variable pointers are within bounds */ - if (called_ptr > len || calling_ptr > len || data_ptr > len) - RETURN_FALSE; - - /* Check that the lengths of the variable parameters are within bounds */ - if (tvb_get_guint8(tvb, called_ptr)+called_ptr > len || - tvb_get_guint8(tvb, calling_ptr)+calling_ptr > len) - RETURN_FALSE; - if (msgtype == SCCP_MSG_TYPE_LUDT || msgtype == SCCP_MSG_TYPE_LUDTS) { - if (tvb_get_letohs(tvb, data_ptr)+data_ptr > len) - RETURN_FALSE; - } else { - if (tvb_get_guint8(tvb, data_ptr)+data_ptr > len) - RETURN_FALSE; - } - } - break; - case SCCP_MSG_TYPE_CR: - { - offset += DESTINATION_LOCAL_REFERENCE_LENGTH; - - /* Class is only the lower 4 bits, but the upper 4 bits are spare - * in Class-2. Don't mask them off so the below comparison also - * fails if any of those spare bits are set. - */ - msg_class = tvb_get_guint8(tvb, offset); - if (msg_class != 2) - RETURN_FALSE; - } - break; - case SCCP_MSG_TYPE_CC: - { - if (len < SCCP_MSG_TYPE_LENGTH - + DESTINATION_LOCAL_REFERENCE_LENGTH - + SOURCE_LOCAL_REFERENCE_LENGTH - + PROTOCOL_CLASS_LENGTH - + POINTER_LENGTH) - RETURN_FALSE; - - offset += DESTINATION_LOCAL_REFERENCE_LENGTH; - offset += SOURCE_LOCAL_REFERENCE_LENGTH; - - /* Class is only the lower 4 bits, but the upper 4 bits are spare - * in Class-2. Don't mask them off so the below comparison also - * fails if any of those spare bits are set. - */ - msg_class = tvb_get_guint8(tvb, offset); - if (msg_class != 2) - RETURN_FALSE; - offset += PROTOCOL_CLASS_LENGTH; - - opt_ptr = tvb_get_guint8(tvb, offset); - offset += POINTER_LENGTH; - - /* If the pointer isn't 0 (no optional parameters) or 1 (optional - * parameter starts immediately after the pointer) then what would - * be between the pointer and the parameter? - */ - if (opt_ptr > 1) - RETURN_FALSE; - - /* If there are no optional parameters, are we at the end of the - * message? - */ - if (opt_ptr == 0 && offset != len) - RETURN_FALSE; - } - break; - case SCCP_MSG_TYPE_CREF: - { - offset += DESTINATION_LOCAL_REFERENCE_LENGTH; - - cause = tvb_get_guint8(tvb, offset); - if (!match_strval(cause, sccp_refusal_cause_values)) - RETURN_FALSE; - offset += REFUSAL_CAUSE_LENGTH; - - opt_ptr = tvb_get_guint8(tvb, offset); - offset += POINTER_LENGTH; - - /* If the pointer isn't 0 (no optional parameters) or 1 (optional - * parameter starts immediately after the pointer) then what would - * be between the pointer and the parameter? - */ - if (opt_ptr > 1) - RETURN_FALSE; - - /* If there are no optional parameters, are we at the end of the - * message? - */ - if (opt_ptr == 0 && offset != len) - RETURN_FALSE; - } - break; - case SCCP_MSG_TYPE_RLSD: - { - if (len < SCCP_MSG_TYPE_LENGTH - + DESTINATION_LOCAL_REFERENCE_LENGTH - + SOURCE_LOCAL_REFERENCE_LENGTH - + RELEASE_CAUSE_LENGTH - + POINTER_LENGTH) - RETURN_FALSE; - - offset += DESTINATION_LOCAL_REFERENCE_LENGTH; - offset += SOURCE_LOCAL_REFERENCE_LENGTH; - - cause = tvb_get_guint8(tvb, offset); - if (!match_strval(cause, sccp_release_cause_values)) - RETURN_FALSE; - offset += RELEASE_CAUSE_LENGTH; - - opt_ptr = tvb_get_guint8(tvb, offset); - offset += POINTER_LENGTH; - - /* If the pointer isn't 0 (no optional parameters) or 1 (optional - * parameter starts immediately after the pointer) then what would - * be between the pointer and the parameter? - */ - if (opt_ptr > 1) - RETURN_FALSE; - - /* If there are no optional parameters, are we at the end of the - * message? - */ - if (opt_ptr == 0 && offset != len) - RETURN_FALSE; - } - break; - case SCCP_MSG_TYPE_RLC: - { - if (len != SCCP_MSG_TYPE_LENGTH - + DESTINATION_LOCAL_REFERENCE_LENGTH - + SOURCE_LOCAL_REFERENCE_LENGTH) - RETURN_FALSE; - } - break; - case SCCP_MSG_TYPE_ERR: - { - if (len != SCCP_MSG_TYPE_LENGTH - + DESTINATION_LOCAL_REFERENCE_LENGTH - + ERROR_CAUSE_LENGTH) - RETURN_FALSE; - - offset += DESTINATION_LOCAL_REFERENCE_LENGTH; - - cause = tvb_get_guint8(tvb, offset); - if (!match_strval(cause, sccp_error_cause_values)) - RETURN_FALSE; - } - break; - case SCCP_MSG_TYPE_DT1: - { - if (len < SCCP_MSG_TYPE_LENGTH - + DESTINATION_LOCAL_REFERENCE_LENGTH - + SEGMENTING_REASSEMBLING_LENGTH - + POINTER_LENGTH - + PARAMETER_LENGTH_LENGTH - + 1) /* At least 1 byte of payload */ - RETURN_FALSE; - offset += DESTINATION_LOCAL_REFERENCE_LENGTH; - - /* Are any of the spare bits in set? */ - if (tvb_get_guint8(tvb, offset) & ~SEGMENTING_REASSEMBLING_MASK) - RETURN_FALSE; - offset += SEGMENTING_REASSEMBLING_LENGTH; - - data_ptr = tvb_get_guint8(tvb, offset) + offset; - /* Verify the data pointer is within bounds */ - if (data_ptr > len) - RETURN_FALSE; - offset += POINTER_LENGTH; - - /* Verify the data length uses the rest of the message */ - if (tvb_get_guint8(tvb, data_ptr) + offset + 1U != len) - RETURN_FALSE; - } - break; - case SCCP_MSG_TYPE_IT: - { - if (len < SCCP_MSG_TYPE_LENGTH - + DESTINATION_LOCAL_REFERENCE_LENGTH - + SOURCE_LOCAL_REFERENCE_LENGTH - + PROTOCOL_CLASS_LENGTH - + SEQUENCING_SEGMENTING_LENGTH - + CREDIT_LENGTH) - RETURN_FALSE; - - offset += DESTINATION_LOCAL_REFERENCE_LENGTH; - offset += SOURCE_LOCAL_REFERENCE_LENGTH; - - /* Class is only the lower 4 bits, but the upper 4 bits are spare - * in Class-2. Don't mask them off so the below comparison also - * fails if any of those spare bits are set. - */ - msg_class = tvb_get_guint8(tvb, offset); - if (msg_class != 2) - RETURN_FALSE; - offset += PROTOCOL_CLASS_LENGTH; - } - break; - case SCCP_MSG_TYPE_AK: - case SCCP_MSG_TYPE_DT2: - case SCCP_MSG_TYPE_EA: - case SCCP_MSG_TYPE_ED: - case SCCP_MSG_TYPE_RSC: - case SCCP_MSG_TYPE_RSR: - /* Class-3 is never actually used in the real world */ - RETURN_FALSE; - break; - default: - DISSECTOR_ASSERT_NOT_REACHED(); + if (msgtype == SCCP_MSG_TYPE_LUDT || msgtype == SCCP_MSG_TYPE_LUDTS) { + if (SCCP_MSG_TYPE_LENGTH + + PROTOCOL_CLASS_LENGTH + /* or Cause for LUDTS */ + HOP_COUNTER_LENGTH + + POINTER_LENGTH_LONG + + POINTER_LENGTH_LONG + + POINTER_LENGTH_LONG + + POINTER_LENGTH_LONG > len) + RETURN_FALSE; + + pointer_length = POINTER_LENGTH_LONG; } - if (called_ptr) { - guint8 param_len = tvb_get_guint8(tvb, called_ptr); - tvbuff_t *param_tvb; + if (msgtype == SCCP_MSG_TYPE_UDT || msgtype == SCCP_MSG_TYPE_XUDT || + msgtype == SCCP_MSG_TYPE_LUDT) { + + msg_class = tvb_get_guint8(tvb, offset) & CLASS_CLASS_MASK; + if (msg_class > 1) + RETURN_FALSE; + offset += PROTOCOL_CLASS_LENGTH; + } - if (param_len == 0) - RETURN_FALSE; - param_tvb = tvb_new_subset(tvb, called_ptr+1, param_len, param_len); + if (msgtype == SCCP_MSG_TYPE_XUDT || msgtype == SCCP_MSG_TYPE_LUDT) + offset += HOP_COUNTER_LENGTH; - if (!sccp_called_calling_looks_valid(frame_num, param_tvb, my_mtp3_standard, !is_connectionless(msgtype))) - RETURN_FALSE; + if (msgtype == SCCP_MSG_TYPE_UDTS || + msgtype == SCCP_MSG_TYPE_XUDTS || + msgtype == SCCP_MSG_TYPE_LUDTS) { + + cause = tvb_get_guint8(tvb, offset); + if (!match_strval(cause, sccp_return_cause_values)) + RETURN_FALSE; + offset += RETURN_CAUSE_LENGTH; } - if (calling_ptr) { - guint8 param_len = tvb_get_guint8(tvb, calling_ptr); - tvbuff_t *param_tvb; + if (msgtype == SCCP_MSG_TYPE_XUDTS || msgtype == SCCP_MSG_TYPE_LUDTS) + offset += HOP_COUNTER_LENGTH; - if (param_len == 0) - RETURN_FALSE; - param_tvb = tvb_new_subset(tvb, calling_ptr+1, param_len, param_len); + if (msgtype == SCCP_MSG_TYPE_LUDT || msgtype == SCCP_MSG_TYPE_LUDTS) + called_ptr = tvb_get_letohs(tvb, offset); + else + called_ptr = tvb_get_guint8(tvb, offset); + if (called_ptr == 0) /* Mandatory variable parameters must be present */ + RETURN_FALSE; + called_ptr += offset; + offset += pointer_length; + + if (msgtype == SCCP_MSG_TYPE_LUDT || msgtype == SCCP_MSG_TYPE_LUDTS) + calling_ptr = tvb_get_letohs(tvb, offset); + else + calling_ptr = tvb_get_guint8(tvb, offset); + if (calling_ptr == 0) /* Mandatory variable parameters must be present */ + RETURN_FALSE; + calling_ptr += offset; + offset += pointer_length; + + if (msgtype == SCCP_MSG_TYPE_LUDT || msgtype == SCCP_MSG_TYPE_LUDTS) + data_ptr = tvb_get_letohs(tvb, offset); + else + data_ptr = tvb_get_guint8(tvb, offset); + if (data_ptr == 0) /* Mandatory variable parameters must be present */ + RETURN_FALSE; + data_ptr += offset; + offset += pointer_length; + + if (msgtype == SCCP_MSG_TYPE_XUDT || msgtype == SCCP_MSG_TYPE_XUDTS) { + opt_ptr = tvb_get_guint8(tvb, offset); + offset += POINTER_LENGTH; + } else if (msgtype == SCCP_MSG_TYPE_LUDT || msgtype == SCCP_MSG_TYPE_LUDTS) { + opt_ptr = tvb_get_letohs(tvb, offset); + offset += POINTER_LENGTH_LONG; + } - if (!sccp_called_calling_looks_valid(frame_num, param_tvb, my_mtp3_standard, !is_connectionless(msgtype))) - RETURN_FALSE; + if (msgtype == SCCP_MSG_TYPE_LUDT || msgtype == SCCP_MSG_TYPE_LUDTS) { + /* Long pointers count from the 2nd (MSB) octet of the pointer */ + called_ptr += 1; + calling_ptr += 1; + data_ptr += 1; + if (opt_ptr) + opt_ptr += 1; } - if (opt_ptr) { - guint8 opt_param; + /* Check that the variable pointers are within bounds */ + if (called_ptr > len || calling_ptr > len || data_ptr > len) + RETURN_FALSE; + + /* Check that the lengths of the variable parameters are within bounds */ + if (tvb_get_guint8(tvb, called_ptr)+called_ptr > len || + tvb_get_guint8(tvb, calling_ptr)+calling_ptr > len) + RETURN_FALSE; + if (msgtype == SCCP_MSG_TYPE_LUDT || msgtype == SCCP_MSG_TYPE_LUDTS) { + if (tvb_get_letohs(tvb, data_ptr)+data_ptr > len) + RETURN_FALSE; + } else { + if (tvb_get_guint8(tvb, data_ptr)+data_ptr > len) + RETURN_FALSE; + } + } + break; + case SCCP_MSG_TYPE_CR: + { + offset += DESTINATION_LOCAL_REFERENCE_LENGTH; - opt_ptr += offset-1; /* (offset was already incremented) */ + /* Class is only the lower 4 bits, but the upper 4 bits are spare + * in Class-2. Don't mask them off so the below comparison also + * fails if any of those spare bits are set. + */ + msg_class = tvb_get_guint8(tvb, offset); + if (msg_class != 2) + RETURN_FALSE; + } + break; + case SCCP_MSG_TYPE_CC: + { + if (len < SCCP_MSG_TYPE_LENGTH + + DESTINATION_LOCAL_REFERENCE_LENGTH + + SOURCE_LOCAL_REFERENCE_LENGTH + + PROTOCOL_CLASS_LENGTH + + POINTER_LENGTH) + RETURN_FALSE; + + offset += DESTINATION_LOCAL_REFERENCE_LENGTH; + offset += SOURCE_LOCAL_REFERENCE_LENGTH; + + /* Class is only the lower 4 bits, but the upper 4 bits are spare + * in Class-2. Don't mask them off so the below comparison also + * fails if any of those spare bits are set. + */ + msg_class = tvb_get_guint8(tvb, offset); + if (msg_class != 2) + RETURN_FALSE; + offset += PROTOCOL_CLASS_LENGTH; - /* Check that the optional pointer is within bounds */ - if (opt_ptr > len) - RETURN_FALSE; + opt_ptr = tvb_get_guint8(tvb, offset); + offset += POINTER_LENGTH; - opt_param = tvb_get_guint8(tvb, opt_ptr); - /* Check if the (1st) optional parameter tag is valid */ - if (!match_strval(opt_param, sccp_parameter_values)) - RETURN_FALSE; + /* If the pointer isn't 0 (no optional parameters) or 1 (optional + * parameter starts immediately after the pointer) then what would + * be between the pointer and the parameter? + */ + if (opt_ptr > 1) + RETURN_FALSE; - /* Check that the (1st) parameter length is within bounds */ - if (opt_param != PARAMETER_END_OF_OPTIONAL_PARAMETERS && - opt_ptr+1U <= len && - tvb_get_guint8(tvb, opt_ptr+1U)+offset > len) - RETURN_FALSE; + /* If there are no optional parameters, are we at the end of the + * message? + */ + if ((opt_ptr == 0) && (offset != len)) + RETURN_FALSE; + } + break; + case SCCP_MSG_TYPE_CREF: + { + offset += DESTINATION_LOCAL_REFERENCE_LENGTH; - /* If we're at the end of the parameters, are we also at the end of the - * message? - */ - if (opt_param == PARAMETER_END_OF_OPTIONAL_PARAMETERS && opt_ptr+1U != len) - RETURN_FALSE; - } + cause = tvb_get_guint8(tvb, offset); + if (!match_strval(cause, sccp_refusal_cause_values)) + RETURN_FALSE; + offset += REFUSAL_CAUSE_LENGTH; + + opt_ptr = tvb_get_guint8(tvb, offset); + offset += POINTER_LENGTH; + + /* If the pointer isn't 0 (no optional parameters) or 1 (optional + * parameter starts immediately after the pointer) then what would + * be between the pointer and the parameter? + */ + if (opt_ptr > 1) + RETURN_FALSE; + + /* If there are no optional parameters, are we at the end of the + * message? + */ + if ((opt_ptr == 0) && (offset != len)) + RETURN_FALSE; + } + break; + case SCCP_MSG_TYPE_RLSD: + { + if (len < SCCP_MSG_TYPE_LENGTH + + DESTINATION_LOCAL_REFERENCE_LENGTH + + SOURCE_LOCAL_REFERENCE_LENGTH + + RELEASE_CAUSE_LENGTH + + POINTER_LENGTH) + RETURN_FALSE; + + offset += DESTINATION_LOCAL_REFERENCE_LENGTH; + offset += SOURCE_LOCAL_REFERENCE_LENGTH; + + cause = tvb_get_guint8(tvb, offset); + if (!match_strval(cause, sccp_release_cause_values)) + RETURN_FALSE; + offset += RELEASE_CAUSE_LENGTH; + + opt_ptr = tvb_get_guint8(tvb, offset); + offset += POINTER_LENGTH; + + /* If the pointer isn't 0 (no optional parameters) or 1 (optional + * parameter starts immediately after the pointer) then what would + * be between the pointer and the parameter? + */ + if (opt_ptr > 1) + RETURN_FALSE; + + /* If there are no optional parameters, are we at the end of the + * message? + */ + if ((opt_ptr == 0) && (offset != len)) + RETURN_FALSE; + } + break; + case SCCP_MSG_TYPE_RLC: + { + if (len != SCCP_MSG_TYPE_LENGTH + + DESTINATION_LOCAL_REFERENCE_LENGTH + + SOURCE_LOCAL_REFERENCE_LENGTH) + RETURN_FALSE; + } + break; + case SCCP_MSG_TYPE_ERR: + { + if (len != SCCP_MSG_TYPE_LENGTH + + DESTINATION_LOCAL_REFERENCE_LENGTH + + ERROR_CAUSE_LENGTH) + RETURN_FALSE; + + offset += DESTINATION_LOCAL_REFERENCE_LENGTH; + + cause = tvb_get_guint8(tvb, offset); + if (!match_strval(cause, sccp_error_cause_values)) + RETURN_FALSE; + } + break; + case SCCP_MSG_TYPE_DT1: + { + if (len < SCCP_MSG_TYPE_LENGTH + + DESTINATION_LOCAL_REFERENCE_LENGTH + + SEGMENTING_REASSEMBLING_LENGTH + + POINTER_LENGTH + + PARAMETER_LENGTH_LENGTH + + 1) /* At least 1 byte of payload */ + RETURN_FALSE; + offset += DESTINATION_LOCAL_REFERENCE_LENGTH; + + /* Are any of the spare bits in set? */ + if (tvb_get_guint8(tvb, offset) & ~SEGMENTING_REASSEMBLING_MASK) + RETURN_FALSE; + offset += SEGMENTING_REASSEMBLING_LENGTH; + + data_ptr = tvb_get_guint8(tvb, offset) + offset; + /* Verify the data pointer is within bounds */ + if (data_ptr > len) + RETURN_FALSE; + offset += POINTER_LENGTH; + + /* Verify the data length uses the rest of the message */ + if (tvb_get_guint8(tvb, data_ptr) + offset + 1U != len) + RETURN_FALSE; + } + break; + case SCCP_MSG_TYPE_IT: + { + if (len < SCCP_MSG_TYPE_LENGTH + + DESTINATION_LOCAL_REFERENCE_LENGTH + + SOURCE_LOCAL_REFERENCE_LENGTH + + PROTOCOL_CLASS_LENGTH + + SEQUENCING_SEGMENTING_LENGTH + + CREDIT_LENGTH) + RETURN_FALSE; + + offset += DESTINATION_LOCAL_REFERENCE_LENGTH; + offset += SOURCE_LOCAL_REFERENCE_LENGTH; + + /* Class is only the lower 4 bits, but the upper 4 bits are spare + * in Class-2. Don't mask them off so the below comparison also + * fails if any of those spare bits are set. + */ + msg_class = tvb_get_guint8(tvb, offset); + if (msg_class != 2) + RETURN_FALSE; + offset += PROTOCOL_CLASS_LENGTH; + } + break; + case SCCP_MSG_TYPE_AK: + case SCCP_MSG_TYPE_DT2: + case SCCP_MSG_TYPE_EA: + case SCCP_MSG_TYPE_ED: + case SCCP_MSG_TYPE_RSC: + case SCCP_MSG_TYPE_RSR: + /* Class-3 is never actually used in the real world */ + RETURN_FALSE; + break; + + default: + DISSECTOR_ASSERT_NOT_REACHED(); + } + + if (called_ptr) { + guint8 param_len = tvb_get_guint8(tvb, called_ptr); + tvbuff_t *param_tvb; + + if (param_len == 0) + RETURN_FALSE; + param_tvb = tvb_new_subset(tvb, called_ptr+1, param_len, param_len); + + if (!sccp_called_calling_looks_valid(frame_num, param_tvb, my_mtp3_standard, !is_connectionless(msgtype))) + RETURN_FALSE; + } + + if (calling_ptr) { + guint8 param_len = tvb_get_guint8(tvb, calling_ptr); + tvbuff_t *param_tvb; + + if (param_len == 0) + RETURN_FALSE; + param_tvb = tvb_new_subset(tvb, calling_ptr+1, param_len, param_len); + + if (!sccp_called_calling_looks_valid(frame_num, param_tvb, my_mtp3_standard, !is_connectionless(msgtype))) + RETURN_FALSE; + } + + if (opt_ptr) { + guint8 opt_param; + + opt_ptr += offset-1; /* (offset was already incremented) */ + + /* Check that the optional pointer is within bounds */ + if (opt_ptr > len) + RETURN_FALSE; - return TRUE; + opt_param = tvb_get_guint8(tvb, opt_ptr); + /* Check if the (1st) optional parameter tag is valid */ + if (!match_strval(opt_param, sccp_parameter_values)) + RETURN_FALSE; + + /* Check that the (1st) parameter length is within bounds */ + if ((opt_param != PARAMETER_END_OF_OPTIONAL_PARAMETERS) && + ((opt_ptr+1U) <= len) && + ((tvb_get_guint8(tvb, opt_ptr+1U)+offset) > len)) + RETURN_FALSE; + + /* If we're at the end of the parameters, are we also at the end of the + * message? + */ + if ((opt_param == PARAMETER_END_OF_OPTIONAL_PARAMETERS) && ((opt_ptr+1U) != len)) + RETURN_FALSE; + } + + return TRUE; } static sccp_assoc_info_t * new_assoc(guint32 calling, guint32 called) { - sccp_assoc_info_t* a = se_alloc0(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->msgs = NULL; - a->curr_msg = NULL; - a->payload = SCCP_PLOAD_NONE; - a->calling_party = NULL; - a->called_party = NULL; - a->extra_info = NULL; - - return a; + sccp_assoc_info_t *a = se_alloc0(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->msgs = NULL; + a->curr_msg = NULL; + a->payload = SCCP_PLOAD_NONE; + a->calling_party = NULL; + a->called_party = NULL; + a->extra_info = NULL; + + return a; } void reset_sccp_assoc(void) { - assoc = NULL; + assoc = NULL; } sccp_assoc_info_t * -get_sccp_assoc(packet_info* pinfo, guint offset, guint32 src_lr, guint32 dst_lr, guint msg_type) +get_sccp_assoc(packet_info *pinfo, guint offset, guint32 src_lr, guint32 dst_lr, guint msg_type) { - guint32 opck, dpck; - address* opc = &(pinfo->src); - address* dpc = &(pinfo->dst); - guint framenum = PINFO_FD_NUM(pinfo); - - if(assoc) - return assoc; - - opck = opc->type == AT_SS7PC ? mtp3_pc_hash((const mtp3_addr_pc_t *)opc->data) : g_str_hash(ep_address_to_str(opc)); - dpck = dpc->type == AT_SS7PC ? mtp3_pc_hash((const mtp3_addr_pc_t *)dpc->data) : g_str_hash(ep_address_to_str(dpc)); - - - switch (msg_type) { - 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} - }; - - if (! ( assoc = se_tree_lookup32_array(assocs,bw_key) ) && ! PINFO_FD_VISITED(pinfo) ) { - assoc = new_assoc(opck, dpck); - se_tree_insert32_array(assocs, bw_key, assoc); - assoc->has_bw_key = TRUE; - } - - pinfo->p2p_dir = P2P_DIR_SENT; - - break; - } - 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} - }; - - if ( ( assoc = se_tree_lookup32_array(assocs, bw_key) ) ) { - goto got_assoc; - } - - if ( (assoc = se_tree_lookup32_array(assocs, fw_key) ) ) { - goto got_assoc; - } - - assoc = new_assoc(dpck,opck); - - got_assoc: - - pinfo->p2p_dir = P2P_DIR_RECV; - - if ( ! PINFO_FD_VISITED(pinfo) && ! assoc->has_bw_key ) { - se_tree_insert32_array(assocs, bw_key, assoc); - assoc->has_bw_key = TRUE; - } - - if ( ! PINFO_FD_VISITED(pinfo) && ! assoc->has_fw_key ) { - se_tree_insert32_array(assocs, fw_key, assoc); - assoc->has_fw_key = TRUE; - } - - break; - } - case SCCP_MSG_TYPE_RLC: - { - emem_tree_key_t bw_key[] = { - {1, &dpck}, {1, &opck}, {1, &src_lr}, {0, NULL} - }; - emem_tree_key_t fw_key[] = { - {1, &opck}, {1, &dpck}, {1, &dst_lr}, {0, NULL} - }; - if ( ( assoc = se_tree_lookup32_array(assocs, bw_key) ) ) { - goto got_assoc_rlc; - } - - if ( (assoc = se_tree_lookup32_array(assocs, fw_key) ) ) { - goto got_assoc_rlc; - } - - assoc = new_assoc(dpck, opck); - - got_assoc_rlc: - - pinfo->p2p_dir = P2P_DIR_SENT; - - if ( ! PINFO_FD_VISITED(pinfo) && ! assoc->has_bw_key ) { - se_tree_insert32_array(assocs, bw_key, assoc); - assoc->has_bw_key = TRUE; - } - - if ( ! PINFO_FD_VISITED(pinfo) && ! 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} - }; - - assoc = se_tree_lookup32_array(assocs, key); - - if (assoc) { - if (assoc->calling_dpc == dpck) { - pinfo->p2p_dir = P2P_DIR_RECV; - } else { - pinfo->p2p_dir = P2P_DIR_SENT; - } - } - - break; - } + guint32 opck, dpck; + address *opc = &(pinfo->src); + address *dpc = &(pinfo->dst); + guint framenum = PINFO_FD_NUM(pinfo); + + if (assoc) + return assoc; + + opck = opc->type == AT_SS7PC ? mtp3_pc_hash((const mtp3_addr_pc_t *)opc->data) : g_str_hash(ep_address_to_str(opc)); + dpck = dpc->type == AT_SS7PC ? mtp3_pc_hash((const mtp3_addr_pc_t *)dpc->data) : g_str_hash(ep_address_to_str(dpc)); + + + switch (msg_type) { + 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} + }; + + if (! ( assoc = se_tree_lookup32_array(assocs,bw_key) ) && ! PINFO_FD_VISITED(pinfo) ) { + assoc = new_assoc(opck, dpck); + se_tree_insert32_array(assocs, bw_key, assoc); + assoc->has_bw_key = TRUE; + } + + pinfo->p2p_dir = P2P_DIR_SENT; + + break; + } + 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} + }; + + if ( ( assoc = se_tree_lookup32_array(assocs, bw_key) ) ) { + goto got_assoc; + } + + if ( (assoc = se_tree_lookup32_array(assocs, fw_key) ) ) { + goto got_assoc; + } + + assoc = new_assoc(dpck,opck); + + got_assoc: + + pinfo->p2p_dir = P2P_DIR_RECV; + + if ( ! PINFO_FD_VISITED(pinfo) && ! assoc->has_bw_key ) { + se_tree_insert32_array(assocs, bw_key, assoc); + assoc->has_bw_key = TRUE; + } + + if ( ! PINFO_FD_VISITED(pinfo) && ! assoc->has_fw_key ) { + se_tree_insert32_array(assocs, fw_key, assoc); + assoc->has_fw_key = TRUE; } - if (assoc && trace_sccp) { - if ( ! PINFO_FD_VISITED(pinfo)) { - sccp_msg_info_t* msg = se_alloc0(sizeof(sccp_msg_info_t)); - msg->framenum = framenum; - msg->offset = offset; - msg->data.co.next = NULL; - msg->data.co.assoc = assoc; - msg->data.co.label = NULL; - msg->data.co.comment = NULL; - msg->type = msg_type; - - if (assoc->msgs) { - sccp_msg_info_t* m; - for (m = assoc->msgs; m->data.co.next; m = m->data.co.next) ; - m->data.co.next = msg; - } else { - assoc->msgs = msg; - } - - assoc->curr_msg = msg; - - } else { - - sccp_msg_info_t* m; - - for (m = assoc->msgs; m; m = m->data.co.next) { - if (m->framenum == framenum && m->offset == offset) { - assoc->curr_msg = m; - break; - } - } - } + break; + } + case SCCP_MSG_TYPE_RLC: + { + emem_tree_key_t bw_key[] = { + {1, &dpck}, {1, &opck}, {1, &src_lr}, {0, NULL} + }; + emem_tree_key_t fw_key[] = { + {1, &opck}, {1, &dpck}, {1, &dst_lr}, {0, NULL} + }; + if ( ( assoc = se_tree_lookup32_array(assocs, bw_key) ) ) { + goto got_assoc_rlc; + } + + if ( (assoc = se_tree_lookup32_array(assocs, fw_key) ) ) { + goto got_assoc_rlc; + } + + assoc = new_assoc(dpck, opck); + + got_assoc_rlc: + + pinfo->p2p_dir = P2P_DIR_SENT; + + if ( ! PINFO_FD_VISITED(pinfo) && ! assoc->has_bw_key ) { + se_tree_insert32_array(assocs, bw_key, assoc); + assoc->has_bw_key = TRUE; + } + + if ( ! PINFO_FD_VISITED(pinfo) && ! 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} + }; + + assoc = se_tree_lookup32_array(assocs, key); + + if (assoc) { + if (assoc->calling_dpc == dpck) { + pinfo->p2p_dir = P2P_DIR_RECV; + } else { + pinfo->p2p_dir = P2P_DIR_SENT; + } + } + + break; + } + } + + if (assoc && trace_sccp) { + if ( ! PINFO_FD_VISITED(pinfo)) { + sccp_msg_info_t *msg = se_alloc0(sizeof(sccp_msg_info_t)); + msg->framenum = framenum; + msg->offset = offset; + msg->data.co.next = NULL; + msg->data.co.assoc = assoc; + msg->data.co.label = NULL; + msg->data.co.comment = NULL; + msg->type = msg_type; + + if (assoc->msgs) { + sccp_msg_info_t *m; + for (m = assoc->msgs; m->data.co.next; m = m->data.co.next) ; + m->data.co.next = msg; + } else { + assoc->msgs = msg; + } + + assoc->curr_msg = msg; + + } else { + + sccp_msg_info_t *m; + + for (m = assoc->msgs; m; m = m->data.co.next) { + if ((m->framenum == framenum) && (m->offset == offset)) { + assoc->curr_msg = m; + break; + } + } } + } - return assoc ? assoc : &no_assoc; + return assoc ? assoc : &no_assoc; } @@ -1478,15 +1478,15 @@ dissect_sccp_unknown_message(tvbuff_t *message_tvb, proto_tree *sccp_tree) 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")); + "Unknown message (%u byte%s)", + message_length, plurality(message_length, "", "s")); } static void dissect_sccp_unknown_param(tvbuff_t *tvb, proto_tree *tree, guint8 type, guint length) { proto_tree_add_text(tree, tvb, 0, length, "Unknown parameter 0x%x (%u byte%s)", - type, length, plurality(length, "", "s")); + type, length, plurality(length, "", "s")); } static void @@ -1533,9 +1533,9 @@ dissect_sccp_slr_param(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guin static proto_tree * dissect_sccp_gt_address_information(tvbuff_t *tvb, packet_info *pinfo, - proto_tree *tree, guint length, - gboolean even_length, gboolean called, - gboolean route_on_gt) + proto_tree *tree, guint length, + gboolean even_length, gboolean called, + gboolean route_on_gt) { guint offset = 0; guint8 odd_signal, even_signal; @@ -1545,33 +1545,33 @@ dissect_sccp_gt_address_information(tvbuff_t *tvb, packet_info *pinfo, gt_digits = ep_alloc0(GT_MAX_SIGNALS+1); - while(offset < length) { + 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; g_strlcat(gt_digits, val_to_str(odd_signal, sccp_address_signal_values, - "Unknown: %d"), GT_MAX_SIGNALS+1); + "Unknown: %d"), GT_MAX_SIGNALS+1); /* If the last signal is NOT filler */ if (offset != (length - 1) || even_length == TRUE) g_strlcat(gt_digits, val_to_str(even_signal, sccp_address_signal_values, - "Unknown: %d"), GT_MAX_SIGNALS+1); + "Unknown: %d"), GT_MAX_SIGNALS+1); offset += GT_SIGNAL_LENGTH; } if (is_connectionless(message_type) && sccp_msg) { - guint8** gt_ptr = called ? &(sccp_msg->data.ud.called_gt) : &(sccp_msg->data.ud.calling_gt); + guint8 **gt_ptr = called ? &(sccp_msg->data.ud.called_gt) : &(sccp_msg->data.ud.calling_gt); - *gt_ptr = (guint8 *)ep_strdup(gt_digits); + *gt_ptr = (guint8 *)ep_strdup(gt_digits); } digits_item = proto_tree_add_string(tree, called ? hf_sccp_called_gt_digits - : hf_sccp_calling_gt_digits, - tvb, 0, length, gt_digits); + : hf_sccp_calling_gt_digits, + tvb, 0, length, gt_digits); digits_tree = proto_item_add_subtree(digits_item, called ? ett_sccp_called_gt_digits - : ett_sccp_calling_gt_digits); + : ett_sccp_calling_gt_digits); if (set_addresses && route_on_gt) { if (called) { @@ -1583,42 +1583,42 @@ dissect_sccp_gt_address_information(tvbuff_t *tvb, packet_info *pinfo, proto_tree_add_string(digits_tree, hf_sccp_gt_digits, tvb, 0, length, gt_digits); proto_tree_add_uint(digits_tree, called ? hf_sccp_called_gt_digits_length - : hf_sccp_calling_gt_digits_length, - tvb, 0, length, (guint32)strlen(gt_digits)); + : hf_sccp_calling_gt_digits_length, + tvb, 0, length, (guint32)strlen(gt_digits)); return digits_tree; } static void dissect_sccp_global_title(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint length, - guint8 gti, gboolean route_on_gt, gboolean called) + guint8 gti, gboolean route_on_gt, gboolean called) { proto_item *gt_item; proto_tree *gt_tree; proto_tree *digits_tree; - tvbuff_t *signals_tvb; - guint offset = 0; - guint8 odd_even, nai = 0, np = 0, es; - gboolean even = TRUE; + tvbuff_t *signals_tvb; + guint offset = 0; + guint8 odd_even, nai = 0, np = 0, es; + 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")); + "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); + : ett_sccp_calling_gt); /* Decode Transation Type (if present) */ 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)) { + ((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))) { proto_tree_add_item(gt_tree, called ? hf_sccp_called_gt_tt - : hf_sccp_calling_gt_tt, - tvb, offset, GT_TT_LENGTH, ENC_NA); + : hf_sccp_calling_gt_tt, + tvb, offset, GT_TT_LENGTH, ENC_NA); offset += GT_TT_LENGTH; } @@ -1628,19 +1628,19 @@ dissect_sccp_global_title(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, g } /* Decode Numbering Plan and Encoding Scheme (if present) */ - 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)) { + 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))) { 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); + : 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); + : hf_sccp_calling_gt_es, + tvb, offset, GT_NP_ES_LENGTH, es); even = (es == GT_ES_BCD_EVEN) ? TRUE : FALSE; @@ -1648,22 +1648,22 @@ dissect_sccp_global_title(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, g } /* Decode Nature of Address Indicator (if present) */ - if (decode_mtp3_standard != ANSI_STANDARD && - (gti == ITU_AI_GTI_NAI || gti == ITU_AI_GTI_TT_NP_ES_NAI)) { + 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); + : hf_sccp_calling_gt_oe, + tvb, offset, GT_NAI_LENGTH, odd_even); even = (odd_even == GT_OE_EVEN) ? TRUE : FALSE; } 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); + : hf_sccp_calling_gt_nai, + tvb, offset, GT_NAI_LENGTH, nai); offset += GT_NAI_LENGTH; } @@ -1673,31 +1673,31 @@ dissect_sccp_global_title(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, g return; signals_tvb = tvb_new_subset(tvb, offset, (length - offset), - (length - offset)); + (length - offset)); digits_tree = dissect_sccp_gt_address_information(signals_tvb, pinfo, gt_tree, - (length - offset), - even, called, route_on_gt); + (length - offset), + even, called, route_on_gt); /* 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) { - dissect_e164_cc(signals_tvb, digits_tree, 0, TRUE); - } - break; - case GT_NP_LAND_MOBILE: - dissect_e212_mcc_mnc_in_address(signals_tvb, pinfo, digits_tree, 0); - break; - default: - break; + switch (np >> GT_NP_SHIFT) { + case GT_NP_ISDN: + case GT_NP_ISDN_MOBILE: + if (nai == GT_NAI_INTERNATIONAL_NUM) { + dissect_e164_cc(signals_tvb, digits_tree, 0, TRUE); + } + break; + case GT_NP_LAND_MOBILE: + dissect_e212_mcc_mnc_in_address(signals_tvb, pinfo, digits_tree, 0); + break; + default: + break; } } static int dissect_sccp_3byte_pc(tvbuff_t *tvb, proto_tree *call_tree, guint offset, - gboolean called) + gboolean called) { int hf_pc; @@ -1716,12 +1716,12 @@ dissect_sccp_3byte_pc(tvbuff_t *tvb, proto_tree *call_tree, guint offset, /* 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); + 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); } @@ -1742,242 +1742,251 @@ dissect_sccp_3byte_pc(tvbuff_t *tvb, proto_tree *call_tree, guint offset, */ static void dissect_sccp_called_calling_param(tvbuff_t *tvb, proto_tree *tree, packet_info *pinfo, - guint length, gboolean called) + guint length, gboolean called) { - proto_item *call_item = 0, *call_ai_item = 0, *item, *hidden_item, *expert_item; - proto_tree *call_tree = 0, *call_ai_tree = 0; - guint offset; - guint8 national = 0xFFU, routing_ind, gti, pci, ssni, ssn; - tvbuff_t *gt_tvb; - 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; - - 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); - - if (decode_mtp3_standard == ANSI_STANDARD) { - national = tvb_get_guint8(tvb, 0) & ANSI_NATIONAL_MASK; - expert_item = proto_tree_add_uint(call_ai_tree, called ? hf_sccp_called_national_indicator - : hf_sccp_calling_national_indicator, - tvb, 0, ADDRESS_INDICATOR_LENGTH, national); - if (national == 0) - expert_add_info_format(pinfo, expert_item, PI_MALFORMED, PI_WARN, "Address is coded to " - "international standards. This doesn't normally happen in ANSI " - "networks."); + proto_item *call_item = 0, *call_ai_item = 0, *item, *hidden_item, *expert_item; + proto_tree *call_tree = 0, *call_ai_tree = 0; + guint offset; + guint8 national = 0xFFU, routing_ind, gti, pci, ssni, ssn; + tvbuff_t *gt_tvb; + 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; + + 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); + + if (decode_mtp3_standard == ANSI_STANDARD) { + national = tvb_get_guint8(tvb, 0) & ANSI_NATIONAL_MASK; + expert_item = proto_tree_add_uint(call_ai_tree, called ? hf_sccp_called_national_indicator + : hf_sccp_calling_national_indicator, + tvb, 0, ADDRESS_INDICATOR_LENGTH, national); + if (national == 0) + expert_add_info_format(pinfo, expert_item, PI_MALFORMED, PI_WARN, "Address is coded to " + "international standards. This doesn't normally happen in ANSI " + "networks."); + } + + 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); + /* Only shift off the other bits after adding the item */ + routing_ind >>= ROUTING_INDICATOR_SHIFT; + + gti = tvb_get_guint8(tvb, 0) & GTI_MASK; + + if (decode_mtp3_standard == ITU_STANDARD || + decode_mtp3_standard == CHINESE_ITU_STANDARD || + decode_mtp3_standard == JAPAN_STANDARD || + national == 0) { + + proto_tree_add_uint(call_ai_tree, + called ? hf_sccp_called_itu_global_title_indicator : hf_sccp_calling_itu_global_title_indicator, + tvb, 0, ADDRESS_INDICATOR_LENGTH, gti); + + ssni = tvb_get_guint8(tvb, 0) & ITU_SSN_INDICATOR_MASK; + expert_item = 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); + if ((routing_ind == ROUTE_ON_SSN) && (ssni == 0)) { + expert_add_info_format(pinfo, expert_item, PI_PROTOCOL, PI_WARN, + "Message is routed on SSN, but SSN is not present"); + } + + 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) { + if (decode_mtp3_standard == ITU_STANDARD || national == 0) { + if (length < offset + ITU_PC_LENGTH) { + expert_item = proto_tree_add_text(call_tree, tvb, 0, -1, + "Wrong length indicated (%u) should be at least %u, PC is %u octets", + length, offset + ITU_PC_LENGTH, ITU_PC_LENGTH); + expert_add_info_format(pinfo, expert_item, PI_MALFORMED, PI_ERROR, "Wrong length indicated"); + PROTO_ITEM_SET_GENERATED(expert_item); + return; + } + proto_tree_add_item(call_tree, called ? hf_sccp_called_itu_pc : hf_sccp_calling_itu_pc, + tvb, offset, ITU_PC_LENGTH, ENC_LITTLE_ENDIAN); + offset += ITU_PC_LENGTH; + + } else if (decode_mtp3_standard == JAPAN_STANDARD) { + + if (length < offset + JAPAN_PC_LENGTH) { + expert_item = proto_tree_add_text(call_tree, tvb, 0, -1, + "Wrong length indicated (%u) should be at least %u, PC is %u octets", + length, offset + JAPAN_PC_LENGTH, JAPAN_PC_LENGTH); + expert_add_info_format(pinfo, expert_item, PI_MALFORMED, PI_ERROR, "Wrong length indicated"); + PROTO_ITEM_SET_GENERATED(expert_item); + return; + } + proto_tree_add_item(call_tree, called ? hf_sccp_called_japan_pc : hf_sccp_calling_japan_pc, + tvb, offset, JAPAN_PC_LENGTH, ENC_LITTLE_ENDIAN); + + offset += JAPAN_PC_LENGTH; + + } else /* CHINESE_ITU_STANDARD */ { + + if (length < offset + ANSI_PC_LENGTH) { + expert_item = proto_tree_add_text(call_tree, tvb, 0, -1, + "Wrong length indicated (%u) should be at least %u, PC is %u octets", + length, offset + ANSI_PC_LENGTH, ANSI_PC_LENGTH); + expert_add_info_format(pinfo, expert_item, PI_MALFORMED, PI_ERROR, "Wrong length indicated"); + PROTO_ITEM_SET_GENERATED(expert_item); + return; + } + offset = dissect_sccp_3byte_pc(tvb, call_tree, offset, called); + + } + } + + /* Dissect SSN (if present) */ + if (ssni) { + ssn = tvb_get_guint8(tvb, offset); + + if ((routing_ind == ROUTE_ON_SSN) && (ssn == 0)) { + expert_add_info_format(pinfo, expert_item, PI_PROTOCOL, PI_WARN, + "Message is routed on SSN, but SSN is zero (unspecified)"); + } + + if (called && assoc) + assoc->called_ssn = ssn; + else if (assoc) + assoc->calling_ssn = ssn; + + 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 + : hf_sccp_calling_ssn, + tvb, offset, ADDRESS_SSN_LENGTH, ssn); + hidden_item = proto_tree_add_uint(call_tree, hf_sccp_ssn, tvb, offset, + ADDRESS_SSN_LENGTH, ssn); + PROTO_ITEM_SET_HIDDEN(hidden_item); + + offset += ADDRESS_SSN_LENGTH; + + /* Get the dissector handle of the dissector registered for this ssn + * And print it's name. + */ + ssn_dissector = dissector_get_uint_handle(sccp_ssn_dissector_table, ssn); + + if (ssn_dissector) { + ssn_dissector_short_name = dissector_handle_get_short_name(ssn_dissector); + + if (ssn_dissector_short_name) { + item = proto_tree_add_text(call_tree, tvb, offset - 1, ADDRESS_SSN_LENGTH, + "Linked to %s", ssn_dissector_short_name); + PROTO_ITEM_SET_GENERATED(item); + + if (g_ascii_strncasecmp("TCAP", ssn_dissector_short_name, 4)== 0) { + tcap_ssn_dissector = get_itu_tcap_subdissector(ssn); + + if (tcap_ssn_dissector) { + tcap_ssn_dissector_short_name = dissector_handle_get_short_name(tcap_ssn_dissector); + proto_item_append_text(item,", TCAP SSN linked to %s", tcap_ssn_dissector_short_name); + } + } + } /* short name */ + } /* ssn_dissector */ + } /* ssni */ + + /* Dissect GT (if present) */ + if (gti != AI_GTI_NO_GT) { + if (length < offset) + return; + + gt_tvb = tvb_new_subset(tvb, offset, (length - offset), + (length - offset)); + dissect_sccp_global_title(gt_tvb, pinfo, call_tree, (length - offset), gti, + (routing_ind == ROUTE_ON_GT), called); + } + + } else if (decode_mtp3_standard == ANSI_STANDARD) { + + 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; + expert_item = 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); + if ((routing_ind == ROUTE_ON_SSN) && (ssni == 0)) { + expert_add_info_format(pinfo, expert_item, PI_PROTOCOL, PI_WARN, + "Message is routed on SSN, but SSN is not present"); + } + + offset = ADDRESS_INDICATOR_LENGTH; + + /* Dissect SSN (if present) */ + if (ssni) { + ssn = tvb_get_guint8(tvb, offset); + + if ((routing_ind == ROUTE_ON_SSN) && (ssn == 0)) { + expert_add_info_format(pinfo, expert_item, PI_PROTOCOL, PI_WARN, + "Message is routed on SSN, but SSN is zero (unspecified)"); + } + + if (called && assoc) { + assoc->called_ssn = ssn; + } else if (assoc) { + assoc->calling_ssn = ssn; + } + + 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 + : hf_sccp_calling_ssn, + tvb, offset, ADDRESS_SSN_LENGTH, ssn); + hidden_item = proto_tree_add_uint(call_tree, hf_sccp_ssn, tvb, offset, + ADDRESS_SSN_LENGTH, ssn); + PROTO_ITEM_SET_HIDDEN(hidden_item); + + offset += ADDRESS_SSN_LENGTH; } - 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); - /* Only shift off the other bits after adding the item */ - routing_ind >>= ROUTING_INDICATOR_SHIFT; - - gti = tvb_get_guint8(tvb, 0) & GTI_MASK; - - if (decode_mtp3_standard == ITU_STANDARD || - decode_mtp3_standard == CHINESE_ITU_STANDARD || - decode_mtp3_standard == JAPAN_STANDARD || - national == 0) { - - proto_tree_add_uint(call_ai_tree, called ? hf_sccp_called_itu_global_title_indicator : hf_sccp_calling_itu_global_title_indicator, - tvb, 0, ADDRESS_INDICATOR_LENGTH, gti); - - ssni = tvb_get_guint8(tvb, 0) & ITU_SSN_INDICATOR_MASK; - expert_item = 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); - if (routing_ind == ROUTE_ON_SSN && ssni == 0) { - expert_add_info_format(pinfo, expert_item, PI_PROTOCOL, PI_WARN, - "Message is routed on SSN, but SSN is not present"); - } - - 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) { - if (decode_mtp3_standard == ITU_STANDARD || national == 0) { - if (length < offset + ITU_PC_LENGTH){ - expert_item = proto_tree_add_text(call_tree, tvb, 0, -1, "Wrong length indicated (%u) should be at least %u, PC is %u octets", length, offset + ITU_PC_LENGTH, ITU_PC_LENGTH); - expert_add_info_format(pinfo, expert_item, PI_MALFORMED, PI_ERROR, "Wrong length indicated"); - PROTO_ITEM_SET_GENERATED(expert_item); - return; - } - proto_tree_add_item(call_tree, called ? hf_sccp_called_itu_pc : hf_sccp_calling_itu_pc, - tvb, offset, ITU_PC_LENGTH, ENC_LITTLE_ENDIAN); - offset += ITU_PC_LENGTH; - - } else if (decode_mtp3_standard == JAPAN_STANDARD) { - - if (length < offset + JAPAN_PC_LENGTH){ - expert_item = proto_tree_add_text(call_tree, tvb, 0, -1, "Wrong length indicated (%u) should be at least %u, PC is %u octets", length, offset + JAPAN_PC_LENGTH, JAPAN_PC_LENGTH); - expert_add_info_format(pinfo, expert_item, PI_MALFORMED, PI_ERROR, "Wrong length indicated"); - PROTO_ITEM_SET_GENERATED(expert_item); - return; - } - proto_tree_add_item(call_tree, called ? hf_sccp_called_japan_pc : hf_sccp_calling_japan_pc, - tvb, offset, JAPAN_PC_LENGTH, ENC_LITTLE_ENDIAN); - - offset += JAPAN_PC_LENGTH; - - } else /* CHINESE_ITU_STANDARD */ { - - if (length < offset + ANSI_PC_LENGTH){ - expert_item = proto_tree_add_text(call_tree, tvb, 0, -1, "Wrong length indicated (%u) should be at least %u, PC is %u octets", length, offset + ANSI_PC_LENGTH, ANSI_PC_LENGTH); - expert_add_info_format(pinfo, expert_item, PI_MALFORMED, PI_ERROR, "Wrong length indicated"); - PROTO_ITEM_SET_GENERATED(expert_item); - return; - } - offset = dissect_sccp_3byte_pc(tvb, call_tree, offset, called); - - } - } - - /* Dissect SSN (if present) */ - if (ssni) { - ssn = tvb_get_guint8(tvb, offset); - - if (routing_ind == ROUTE_ON_SSN && ssn == 0) { - expert_add_info_format(pinfo, expert_item, PI_PROTOCOL, PI_WARN, - "Message is routed on SSN, but SSN is zero (unspecified)"); - } - - if (called && assoc) - assoc->called_ssn = ssn; - else if (assoc) - assoc->calling_ssn = ssn; - - 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 - : hf_sccp_calling_ssn, - tvb, offset, ADDRESS_SSN_LENGTH, ssn); - hidden_item = proto_tree_add_uint(call_tree, hf_sccp_ssn, tvb, offset, - ADDRESS_SSN_LENGTH, ssn); - PROTO_ITEM_SET_HIDDEN(hidden_item); - - offset += ADDRESS_SSN_LENGTH; - - /* Get the dissector handle of the dissector registered for this ssn - * And print it's name. - */ - ssn_dissector = dissector_get_uint_handle(sccp_ssn_dissector_table, ssn); - - if (ssn_dissector) { - ssn_dissector_short_name = dissector_handle_get_short_name(ssn_dissector); - - if(ssn_dissector_short_name) { - item = proto_tree_add_text(call_tree, tvb, offset - 1, ADDRESS_SSN_LENGTH, "Linked to %s", ssn_dissector_short_name); - PROTO_ITEM_SET_GENERATED(item); - - if (g_ascii_strncasecmp("TCAP", ssn_dissector_short_name, 4)== 0) { - tcap_ssn_dissector = get_itu_tcap_subdissector(ssn); - - if(tcap_ssn_dissector) { - tcap_ssn_dissector_short_name = dissector_handle_get_short_name(tcap_ssn_dissector); - proto_item_append_text(item,", TCAP SSN linked to %s", tcap_ssn_dissector_short_name); - } - } - } /* short name */ - } /* ssn_dissector */ - } /* ssni */ - - /* Dissect GT (if present) */ - if (gti != AI_GTI_NO_GT) { - if (length < offset) - return; - - gt_tvb = tvb_new_subset(tvb, offset, (length - offset), - (length - offset)); - dissect_sccp_global_title(gt_tvb, pinfo, call_tree, (length - offset), gti, - (routing_ind == ROUTE_ON_GT), called); - } - - } else if (decode_mtp3_standard == ANSI_STANDARD) { - - 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; - expert_item = 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); - if (routing_ind == ROUTE_ON_SSN && ssni == 0) { - expert_add_info_format(pinfo, expert_item, PI_PROTOCOL, PI_WARN, - "Message is routed on SSN, but SSN is not present"); - } - - offset = ADDRESS_INDICATOR_LENGTH; - - /* Dissect SSN (if present) */ - if (ssni) { - ssn = tvb_get_guint8(tvb, offset); - - if (routing_ind == ROUTE_ON_SSN && ssn == 0) { - expert_add_info_format(pinfo, expert_item, PI_PROTOCOL, PI_WARN, - "Message is routed on SSN, but SSN is zero (unspecified)"); - } - - if (called && assoc) { - assoc->called_ssn = ssn; - } else if (assoc) { - assoc->calling_ssn = ssn; - } - - 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 - : hf_sccp_calling_ssn, - tvb, offset, ADDRESS_SSN_LENGTH, ssn); - hidden_item = proto_tree_add_uint(call_tree, hf_sccp_ssn, tvb, offset, - ADDRESS_SSN_LENGTH, ssn); - PROTO_ITEM_SET_HIDDEN(hidden_item); - - offset += ADDRESS_SSN_LENGTH; - } - - /* Dissect PC (if present) */ - if (pci) { - offset = dissect_sccp_3byte_pc(tvb, call_tree, offset, called); - } - - /* Dissect GT (if present) */ - if (gti != AI_GTI_NO_GT) { - if (length < offset) - return; - gt_tvb = tvb_new_subset(tvb, offset, (length - offset), - (length - offset)); - dissect_sccp_global_title(gt_tvb, pinfo, call_tree, (length - offset), gti, - (routing_ind == ROUTE_ON_GT), called); - } + /* Dissect PC (if present) */ + if (pci) { + offset = dissect_sccp_3byte_pc(tvb, call_tree, offset, called); + } + /* Dissect GT (if present) */ + if (gti != AI_GTI_NO_GT) { + if (length < offset) + return; + gt_tvb = tvb_new_subset(tvb, offset, (length - offset), + (length - offset)); + dissect_sccp_global_title(gt_tvb, pinfo, call_tree, (length - offset), gti, + (routing_ind == ROUTE_ON_GT), called); } + } + } static void @@ -1995,9 +2004,9 @@ dissect_sccp_calling_param(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, static void dissect_sccp_class_param(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint length) { - guint8 msg_class; + guint8 msg_class; proto_item *pi; - gboolean invalid_class = FALSE; + gboolean invalid_class = FALSE; if (length != 1) { pi = proto_tree_add_text(tree, tvb, 0, length, "Wrong length indicated. Expected 1, got %u", length); @@ -2009,7 +2018,7 @@ dissect_sccp_class_param(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, gu msg_class = tvb_get_guint8(tvb, 0) & CLASS_CLASS_MASK; pi = proto_tree_add_uint(tree, hf_sccp_class, tvb, 0, length, msg_class); - switch(message_type) { + switch (message_type) { case SCCP_MSG_TYPE_DT1: if (msg_class != 2) invalid_class = TRUE; @@ -2030,7 +2039,7 @@ dissect_sccp_class_param(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, gu case SCCP_MSG_TYPE_RLC: case SCCP_MSG_TYPE_ERR: case SCCP_MSG_TYPE_IT: - if (msg_class != 2 && msg_class != 3) + if ((msg_class != 2) && (msg_class != 3)) invalid_class = TRUE; break; case SCCP_MSG_TYPE_UDT: @@ -2039,7 +2048,7 @@ dissect_sccp_class_param(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, gu case SCCP_MSG_TYPE_XUDTS: case SCCP_MSG_TYPE_LUDT: case SCCP_MSG_TYPE_LUDTS: - if (msg_class != 0 && msg_class != 1) + if ((msg_class != 0) && (msg_class != 1)) invalid_class = TRUE; break; } @@ -2093,7 +2102,7 @@ dissect_sccp_receive_sequence_number_param(tvbuff_t *tvb, packet_info *pinfo, pr static void dissect_sccp_sequencing_segmenting_param(tvbuff_t *tvb, proto_tree *tree, guint length) { - guint8 rsn, ssn; + guint8 rsn, ssn; proto_item *param_item; proto_tree *param_tree; @@ -2101,19 +2110,19 @@ dissect_sccp_sequencing_segmenting_param(tvbuff_t *tvb, proto_tree *tree, guint rsn = tvb_get_guint8(tvb, SEQUENCING_SEGMENTING_SSN_LENGTH) >> 1; param_item = proto_tree_add_text(tree, tvb, 0, length, "%s", - val_to_str(PARAMETER_SEQUENCING_SEGMENTING, - sccp_parameter_values, "Unknown: %d")); + val_to_str(PARAMETER_SEQUENCING_SEGMENTING, + sccp_parameter_values, "Unknown: %d")); param_tree = proto_item_add_subtree(param_item, - ett_sccp_sequencing_segmenting); + ett_sccp_sequencing_segmenting); proto_tree_add_uint(param_tree, hf_sccp_sequencing_segmenting_ssn, tvb, 0, - SEQUENCING_SEGMENTING_SSN_LENGTH, ssn); + 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); + SEQUENCING_SEGMENTING_SSN_LENGTH, + SEQUENCING_SEGMENTING_RSN_LENGTH, rsn); proto_tree_add_item(param_tree, hf_sccp_sequencing_segmenting_more, tvb, - SEQUENCING_SEGMENTING_SSN_LENGTH, - SEQUENCING_SEGMENTING_RSN_LENGTH, ENC_NA); + SEQUENCING_SEGMENTING_SSN_LENGTH, + SEQUENCING_SEGMENTING_RSN_LENGTH, ENC_NA); } static void @@ -2122,7 +2131,8 @@ dissect_sccp_credit_param(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, g if (length != 1) { proto_item *expert_item; expert_item = proto_tree_add_text(tree, tvb, 0, length, "Wrong length indicated. Expected 1, got %u", length); - expert_add_info_format(pinfo, expert_item, PI_MALFORMED, PI_ERROR, "Wrong length indicated. Expected 1, got %u", length); + expert_add_info_format(pinfo, expert_item, PI_MALFORMED, PI_ERROR, + "Wrong length indicated. Expected 1, got %u", length); PROTO_ITEM_SET_GENERATED(expert_item); return; } @@ -2137,8 +2147,10 @@ dissect_sccp_release_cause_param(tvbuff_t *tvb, packet_info *pinfo, proto_tree * if (length != 1) { proto_item *expert_item; - expert_item = proto_tree_add_text(tree, tvb, 0, length, "Wrong length indicated. Expected 1, got %u", length); - expert_add_info_format(pinfo, expert_item, PI_MALFORMED, PI_ERROR, "Wrong length indicated. Expected 1, got %u", length); + expert_item = proto_tree_add_text(tree, tvb, 0, length, + "Wrong length indicated. Expected 1, got %u", length); + expert_add_info_format(pinfo, expert_item, PI_MALFORMED, PI_ERROR, + "Wrong length indicated. Expected 1, got %u", length); PROTO_ITEM_SET_GENERATED(expert_item); return; } @@ -2158,7 +2170,8 @@ dissect_sccp_return_cause_param(tvbuff_t *tvb, packet_info *pinfo, proto_tree *t if (length != 1) { proto_item *expert_item; expert_item = proto_tree_add_text(tree, tvb, 0, length, "Wrong length indicated. Expected 1, got %u", length); - expert_add_info_format(pinfo, expert_item, PI_MALFORMED, PI_ERROR, "Wrong length indicated. Expected 1, got %u", length); + expert_add_info_format(pinfo, expert_item, PI_MALFORMED, PI_ERROR, + "Wrong length indicated. Expected 1, got %u", length); PROTO_ITEM_SET_GENERATED(expert_item); return; } @@ -2178,7 +2191,8 @@ dissect_sccp_reset_cause_param(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tr if (length != 1) { proto_item *expert_item; expert_item = proto_tree_add_text(tree, tvb, 0, length, "Wrong length indicated. Expected 1, got %u", length); - expert_add_info_format(pinfo, expert_item, PI_MALFORMED, PI_ERROR, "Wrong length indicated. Expected 1, got %u", length); + expert_add_info_format(pinfo, expert_item, PI_MALFORMED, PI_ERROR, + "Wrong length indicated. Expected 1, got %u", length); PROTO_ITEM_SET_GENERATED(expert_item); return; } @@ -2235,94 +2249,94 @@ dissect_sccp_refusal_cause_param(tvbuff_t *tvb, packet_info *pinfo, proto_tree * static void dissect_sccp_data_param(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) { - guint8 ssn = INVALID_SSN; - guint8 other_ssn = INVALID_SSN; - const mtp3_addr_pc_t* dpc = NULL; - const mtp3_addr_pc_t* opc = NULL; + guint8 ssn = INVALID_SSN; + guint8 other_ssn = INVALID_SSN; + const mtp3_addr_pc_t *dpc = NULL; + const mtp3_addr_pc_t *opc = NULL; - if (trace_sccp && assoc && assoc != &no_assoc) { - pinfo->sccp_info = assoc->curr_msg; - } else { - pinfo->sccp_info = NULL; - } + if ((trace_sccp) && (assoc && assoc != &no_assoc)) { + pinfo->sccp_info = assoc->curr_msg; + } else { + pinfo->sccp_info = NULL; + } - if (assoc) { - switch (pinfo->p2p_dir) { - case P2P_DIR_SENT: - ssn = assoc->calling_ssn; - other_ssn = assoc->called_ssn; - 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; - other_ssn = assoc->calling_ssn; - 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; - } + if (assoc) { + switch (pinfo->p2p_dir) { + case P2P_DIR_SENT: + ssn = assoc->calling_ssn; + other_ssn = assoc->called_ssn; + 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; + other_ssn = assoc->calling_ssn; + 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; } + } - if (num_sccp_users && pinfo->src.type == AT_SS7PC) { - guint i; - dissector_handle_t handle = NULL; - gboolean uses_tcap = FALSE; - - for (i=0; i < num_sccp_users; i++) { - sccp_user_t* u = &(sccp_users[i]); - - if (!dpc || dpc->ni != u->ni) continue; - - if (value_is_in_range(u->called_ssn, ssn) && value_is_in_range(u->called_pc, dpc->pc) ) { - handle = *(u->handlep); - uses_tcap = u->uses_tcap; - break; - } else if (value_is_in_range(u->called_ssn, other_ssn) && opc && value_is_in_range(u->called_pc, opc->pc) ) { - handle = *(u->handlep); - uses_tcap = u->uses_tcap; - break; - } - } - - if (handle) { - if (uses_tcap) { - call_tcap_dissector(handle, tvb, pinfo, tree); - } else { - call_dissector(handle, tvb, pinfo, tree); - } - return; - } - - } - - if (ssn != INVALID_SSN && dissector_try_uint(sccp_ssn_dissector_table, ssn, tvb, pinfo, tree)) { - return; - } + if ((num_sccp_users) && (pinfo->src.type == AT_SS7PC)) { + guint i; + dissector_handle_t handle = NULL; + gboolean uses_tcap = FALSE; - if (other_ssn != INVALID_SSN && dissector_try_uint(sccp_ssn_dissector_table, other_ssn, tvb, pinfo, tree)) { - return; - } + for (i=0; i < num_sccp_users; i++) { + sccp_user_t *u = &(sccp_users[i]); + + if (!dpc || dpc->ni != u->ni) continue; - /* try heuristic subdissector list to see if there are any takers */ - if (dissector_try_heuristic(heur_subdissector_list, tvb, pinfo, tree)) { - return; + if (value_is_in_range(u->called_ssn, ssn) && value_is_in_range(u->called_pc, dpc->pc) ) { + handle = *(u->handlep); + uses_tcap = u->uses_tcap; + break; + } else if (value_is_in_range(u->called_ssn, other_ssn) && opc && value_is_in_range(u->called_pc, opc->pc) ) { + handle = *(u->handlep); + uses_tcap = u->uses_tcap; + break; + } } - /* try user default subdissector */ - if (default_handle) { - call_dissector(default_handle, tvb, pinfo, tree); - return; + if (handle) { + if (uses_tcap) { + call_tcap_dissector(handle, tvb, pinfo, tree); + } else { + call_dissector(handle, tvb, pinfo, tree); + } + return; } - /* No sub-dissection occured, treat it as raw data */ - call_dissector(data_handle, tvb, pinfo, tree); + } + + if ((ssn != INVALID_SSN) && dissector_try_uint(sccp_ssn_dissector_table, ssn, tvb, pinfo, tree)) { + return; + } + + if ((other_ssn != INVALID_SSN) && dissector_try_uint(sccp_ssn_dissector_table, other_ssn, tvb, pinfo, tree)) { + return; + } + + /* try heuristic subdissector list to see if there are any takers */ + if (dissector_try_heuristic(heur_subdissector_list, tvb, pinfo, tree)) { + return; + } + + /* try user default subdissector */ + if (default_handle) { + call_dissector(default_handle, tvb, pinfo, tree); + return; + } + + /* No sub-dissection occured, treat it as raw data */ + call_dissector(data_handle, tvb, pinfo, tree); } @@ -2333,8 +2347,8 @@ dissect_sccp_segmentation_param(tvbuff_t *tvb, packet_info *pinfo, proto_tree *t proto_tree *param_tree; param_item = proto_tree_add_text(tree, tvb, 0, length, "%s", - val_to_str(PARAMETER_SEGMENTATION, - sccp_parameter_values, "Unknown: %d")); + val_to_str(PARAMETER_SEGMENTATION, + sccp_parameter_values, "Unknown: %d")); param_tree = proto_item_add_subtree(param_item, ett_sccp_segmentation); proto_tree_add_item(param_tree, hf_sccp_segmentation_first, tvb, 0, 1, ENC_NA); @@ -2385,39 +2399,39 @@ dissect_sccp_isni_param(tvbuff_t *tvb, proto_tree *tree, guint length) /* Create a subtree for ISNI Routing Control */ param_item = proto_tree_add_text(tree, tvb, offset, ANSI_ISNI_ROUTING_CONTROL_LENGTH, - "ISNI Routing Control"); + "ISNI Routing Control"); param_tree = proto_item_add_subtree(param_item, - ett_sccp_ansi_isni_routing_control); + ett_sccp_ansi_isni_routing_control); proto_tree_add_item(param_tree, hf_sccp_ansi_isni_mi, tvb, offset, - ANSI_ISNI_ROUTING_CONTROL_LENGTH, ENC_NA); + ANSI_ISNI_ROUTING_CONTROL_LENGTH, ENC_NA); proto_tree_add_item(param_tree, hf_sccp_ansi_isni_iri, tvb, offset, - ANSI_ISNI_ROUTING_CONTROL_LENGTH, ENC_NA); + ANSI_ISNI_ROUTING_CONTROL_LENGTH, ENC_NA); 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); + ANSI_ISNI_ROUTING_CONTROL_LENGTH, ti); proto_tree_add_item(param_tree, hf_sccp_ansi_isni_counter, tvb, offset, - ANSI_ISNI_ROUTING_CONTROL_LENGTH, ENC_NA); + ANSI_ISNI_ROUTING_CONTROL_LENGTH, ENC_NA); offset += ANSI_ISNI_ROUTING_CONTROL_LENGTH; if ((ti >> ANSI_ISNI_TI_SHIFT) == ANSI_ISNI_TYPE_1) { proto_tree_add_uint(param_tree, hf_sccp_ansi_isni_netspec, tvb, offset, - ANSI_ISNI_ROUTING_CONTROL_LENGTH, ti); + ANSI_ISNI_ROUTING_CONTROL_LENGTH, ti); offset += ANSI_ISNI_ROUTING_CONTROL_LENGTH; } while (offset < length) { proto_tree_add_item(tree, hf_sccp_ansi_isni_network, tvb, offset, - ANSI_NCM_LENGTH, ENC_NA); + ANSI_NCM_LENGTH, ENC_NA); offset++; proto_tree_add_item(tree, hf_sccp_ansi_isni_cluster, tvb, offset, - ANSI_NCM_LENGTH, ENC_NA); + ANSI_NCM_LENGTH, ENC_NA); offset++; } @@ -2428,147 +2442,147 @@ dissect_sccp_isni_param(tvbuff_t *tvb, proto_tree *tree, guint length) */ static guint16 dissect_sccp_parameter(tvbuff_t *tvb, packet_info *pinfo, proto_tree *sccp_tree, - proto_tree *tree, guint8 parameter_type, guint16 offset, - guint16 parameter_length) + proto_tree *tree, guint8 parameter_type, guint16 offset, + 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: - case PARAMETER_SOURCE_LOCAL_REFERENCE: - case PARAMETER_DESTINATION_LOCAL_REFERENCE: - case PARAMETER_RELEASE_CAUSE: - case PARAMETER_RETURN_CAUSE: - case PARAMETER_RESET_CAUSE: - case PARAMETER_ERROR_CAUSE: - case PARAMETER_REFUSAL_CAUSE: - - /* These parameters must be dissected even if !sccp_tree (so that - * assoc information can be created). - */ - break; + tvbuff_t *parameter_tvb; + + switch (parameter_type) { + case PARAMETER_CALLED_PARTY_ADDRESS: + case PARAMETER_CALLING_PARTY_ADDRESS: + case PARAMETER_DATA: + case PARAMETER_LONG_DATA: + case PARAMETER_SOURCE_LOCAL_REFERENCE: + case PARAMETER_DESTINATION_LOCAL_REFERENCE: + case PARAMETER_RELEASE_CAUSE: + case PARAMETER_RETURN_CAUSE: + case PARAMETER_RESET_CAUSE: + case PARAMETER_ERROR_CAUSE: + case PARAMETER_REFUSAL_CAUSE: + + /* These parameters must be dissected even if !sccp_tree (so that + * assoc information can be created). + */ + break; - default: - if (!sccp_tree) return(parameter_length); + default: + if (!sccp_tree) return(parameter_length); - } + } - parameter_tvb = tvb_new_subset(tvb, offset, parameter_length, parameter_length); + parameter_tvb = tvb_new_subset(tvb, offset, parameter_length, parameter_length); - switch (parameter_type) { + 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_END_OF_OPTIONAL_PARAMETERS: + proto_tree_add_text(sccp_tree, tvb, offset, parameter_length, + "End of Optional"); + break; - case PARAMETER_DESTINATION_LOCAL_REFERENCE: - dissect_sccp_dlr_param(parameter_tvb, pinfo, sccp_tree, parameter_length); - break; + case PARAMETER_DESTINATION_LOCAL_REFERENCE: + dissect_sccp_dlr_param(parameter_tvb, pinfo, sccp_tree, parameter_length); + break; - case PARAMETER_SOURCE_LOCAL_REFERENCE: - dissect_sccp_slr_param(parameter_tvb, pinfo, sccp_tree, parameter_length); - break; + case PARAMETER_SOURCE_LOCAL_REFERENCE: + dissect_sccp_slr_param(parameter_tvb, pinfo, sccp_tree, parameter_length); + break; - case PARAMETER_CALLED_PARTY_ADDRESS: - dissect_sccp_called_param(parameter_tvb, pinfo, sccp_tree, parameter_length); - break; + case PARAMETER_CALLED_PARTY_ADDRESS: + dissect_sccp_called_param(parameter_tvb, pinfo, sccp_tree, parameter_length); + break; - case PARAMETER_CALLING_PARTY_ADDRESS: - dissect_sccp_calling_param(parameter_tvb, pinfo, sccp_tree, parameter_length); - break; + case PARAMETER_CALLING_PARTY_ADDRESS: + dissect_sccp_calling_param(parameter_tvb, pinfo, sccp_tree, parameter_length); + break; - case PARAMETER_CLASS: - dissect_sccp_class_param(parameter_tvb, pinfo, sccp_tree, parameter_length); - break; + case PARAMETER_CLASS: + dissect_sccp_class_param(parameter_tvb, pinfo, sccp_tree, parameter_length); + break; - case PARAMETER_SEGMENTING_REASSEMBLING: - dissect_sccp_segmenting_reassembling_param(parameter_tvb, pinfo, sccp_tree, - parameter_length); - break; + case PARAMETER_SEGMENTING_REASSEMBLING: + dissect_sccp_segmenting_reassembling_param(parameter_tvb, pinfo, sccp_tree, + parameter_length); + break; - case PARAMETER_RECEIVE_SEQUENCE_NUMBER: - dissect_sccp_receive_sequence_number_param(parameter_tvb, pinfo, sccp_tree, - parameter_length); - break; + case PARAMETER_RECEIVE_SEQUENCE_NUMBER: + dissect_sccp_receive_sequence_number_param(parameter_tvb, pinfo, sccp_tree, + parameter_length); + break; - case PARAMETER_SEQUENCING_SEGMENTING: - dissect_sccp_sequencing_segmenting_param(parameter_tvb, sccp_tree, - parameter_length); - break; + case PARAMETER_SEQUENCING_SEGMENTING: + dissect_sccp_sequencing_segmenting_param(parameter_tvb, sccp_tree, + parameter_length); + break; - case PARAMETER_CREDIT: - dissect_sccp_credit_param(parameter_tvb, pinfo, sccp_tree, parameter_length); - break; + case PARAMETER_CREDIT: + dissect_sccp_credit_param(parameter_tvb, pinfo, sccp_tree, parameter_length); + break; - case PARAMETER_RELEASE_CAUSE: - dissect_sccp_release_cause_param(parameter_tvb, pinfo, sccp_tree, parameter_length); - break; + case PARAMETER_RELEASE_CAUSE: + dissect_sccp_release_cause_param(parameter_tvb, pinfo, sccp_tree, parameter_length); + break; - case PARAMETER_RETURN_CAUSE: - dissect_sccp_return_cause_param(parameter_tvb, pinfo, sccp_tree, parameter_length); - break; + case PARAMETER_RETURN_CAUSE: + dissect_sccp_return_cause_param(parameter_tvb, pinfo, sccp_tree, parameter_length); + break; - case PARAMETER_RESET_CAUSE: - dissect_sccp_reset_cause_param(parameter_tvb, pinfo, sccp_tree, parameter_length); - break; + case PARAMETER_RESET_CAUSE: + dissect_sccp_reset_cause_param(parameter_tvb, pinfo, sccp_tree, parameter_length); + break; - case PARAMETER_ERROR_CAUSE: - dissect_sccp_error_cause_param(parameter_tvb, pinfo, sccp_tree, parameter_length); - break; + case PARAMETER_ERROR_CAUSE: + dissect_sccp_error_cause_param(parameter_tvb, pinfo, sccp_tree, parameter_length); + break; - case PARAMETER_REFUSAL_CAUSE: - dissect_sccp_refusal_cause_param(parameter_tvb, pinfo, sccp_tree, parameter_length); - break; + case PARAMETER_REFUSAL_CAUSE: + dissect_sccp_refusal_cause_param(parameter_tvb, pinfo, sccp_tree, parameter_length); + break; - case PARAMETER_DATA: - dissect_sccp_data_param(parameter_tvb, pinfo, tree); + case PARAMETER_DATA: + dissect_sccp_data_param(parameter_tvb, pinfo, tree); - /* 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; + /* 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: - dissect_sccp_segmentation_param(parameter_tvb, pinfo, sccp_tree, parameter_length); - break; + case PARAMETER_SEGMENTATION: + dissect_sccp_segmentation_param(parameter_tvb, pinfo, sccp_tree, parameter_length); + break; - case PARAMETER_HOP_COUNTER: - dissect_sccp_hop_counter_param(parameter_tvb, sccp_tree, parameter_length); - break; + case PARAMETER_HOP_COUNTER: + dissect_sccp_hop_counter_param(parameter_tvb, sccp_tree, parameter_length); + break; - case PARAMETER_IMPORTANCE: - if (decode_mtp3_standard != ANSI_STANDARD) - dissect_sccp_importance_param(parameter_tvb, pinfo, sccp_tree, parameter_length); - else - dissect_sccp_unknown_param(parameter_tvb, sccp_tree, parameter_type, - parameter_length); - break; + case PARAMETER_IMPORTANCE: + if (decode_mtp3_standard != ANSI_STANDARD) + dissect_sccp_importance_param(parameter_tvb, pinfo, sccp_tree, parameter_length); + else + dissect_sccp_unknown_param(parameter_tvb, sccp_tree, parameter_type, + parameter_length); + break; - case PARAMETER_LONG_DATA: - dissect_sccp_data_param(parameter_tvb, pinfo, tree); - break; + case PARAMETER_LONG_DATA: + dissect_sccp_data_param(parameter_tvb, pinfo, tree); + break; - case PARAMETER_ISNI: - if (decode_mtp3_standard != ANSI_STANDARD) - dissect_sccp_unknown_param(parameter_tvb, sccp_tree, parameter_type, - parameter_length); - else - dissect_sccp_isni_param(parameter_tvb, sccp_tree, parameter_length); - break; + case PARAMETER_ISNI: + if (decode_mtp3_standard != ANSI_STANDARD) + dissect_sccp_unknown_param(parameter_tvb, sccp_tree, parameter_type, + parameter_length); + else + dissect_sccp_isni_param(parameter_tvb, sccp_tree, parameter_length); + break; - default: - dissect_sccp_unknown_param(parameter_tvb, sccp_tree, parameter_type, - parameter_length); - break; - } + default: + dissect_sccp_unknown_param(parameter_tvb, sccp_tree, parameter_type, + parameter_length); + break; + } - return(parameter_length); + return(parameter_length); } /* FUNCTION dissect_sccp_variable_parameter(): @@ -2578,11 +2592,11 @@ dissect_sccp_parameter(tvbuff_t *tvb, packet_info *pinfo, proto_tree *sccp_tree, */ static guint16 dissect_sccp_variable_parameter(tvbuff_t *tvb, packet_info *pinfo, - proto_tree *sccp_tree, proto_tree *tree, - guint8 parameter_type, guint16 offset) + proto_tree *sccp_tree, proto_tree *tree, + guint8 parameter_type, guint16 offset) { - guint16 parameter_length; - guint8 length_length; + guint16 parameter_length; + guint8 length_length; proto_item *pi; if (parameter_type != PARAMETER_LONG_DATA) { @@ -2595,10 +2609,10 @@ dissect_sccp_variable_parameter(tvbuff_t *tvb, packet_info *pinfo, } pi = proto_tree_add_uint_format(sccp_tree, hf_sccp_param_length, tvb, offset, - length_length, parameter_length, "%s length: %d", - val_to_str(parameter_type, sccp_parameter_values, - "Unknown: %d"), - parameter_length); + length_length, parameter_length, "%s length: %d", + val_to_str(parameter_type, sccp_parameter_values, + "Unknown: %d"), + parameter_length); if (!sccp_show_length) { /* The user doesn't want to see it... */ PROTO_ITEM_SET_HIDDEN(pi); @@ -2607,7 +2621,7 @@ dissect_sccp_variable_parameter(tvbuff_t *tvb, packet_info *pinfo, offset += length_length; dissect_sccp_parameter(tvb, pinfo, sccp_tree, tree, parameter_type, offset, - parameter_length); + parameter_length); return(parameter_length + length_length); } @@ -2618,76 +2632,80 @@ dissect_sccp_variable_parameter(tvbuff_t *tvb, packet_info *pinfo, */ static void dissect_sccp_optional_parameters(tvbuff_t *tvb, packet_info *pinfo, - proto_tree *sccp_tree, proto_tree *tree, - guint16 offset) + proto_tree *sccp_tree, proto_tree *tree, + guint16 offset) { guint8 parameter_type; while ((parameter_type = tvb_get_guint8(tvb, offset)) != - PARAMETER_END_OF_OPTIONAL_PARAMETERS) { + PARAMETER_END_OF_OPTIONAL_PARAMETERS) { offset += PARAMETER_TYPE_LENGTH; offset += dissect_sccp_variable_parameter(tvb, pinfo, sccp_tree, tree, - parameter_type, offset); + parameter_type, offset); } /* Process end of optional parameters */ dissect_sccp_parameter(tvb, pinfo, sccp_tree, tree, parameter_type, offset, - END_OF_OPTIONAL_PARAMETERS_LENGTH); + END_OF_OPTIONAL_PARAMETERS_LENGTH); } static sccp_msg_info_t * -new_ud_msg(packet_info* pinfo, guint32 msg_type _U_) +new_ud_msg(packet_info *pinfo, guint32 msg_type _U_) { - sccp_msg_info_t* m = ep_alloc0(sizeof(sccp_msg_info_t)); - m->framenum = PINFO_FD_NUM(pinfo); - m->data.ud.calling_gt = NULL; - m->data.ud.called_gt = NULL; + sccp_msg_info_t *m = ep_alloc0(sizeof(sccp_msg_info_t)); + m->framenum = PINFO_FD_NUM(pinfo); + m->data.ud.calling_gt = NULL; + m->data.ud.called_gt = NULL; - register_frame_end_routine(reset_sccp_assoc); - return m; + register_frame_end_routine(reset_sccp_assoc); + return m; } static void dissect_sccp_message(tvbuff_t *tvb, packet_info *pinfo, proto_tree *sccp_tree, - proto_tree *tree) + proto_tree *tree) { - guint16 variable_pointer1 = 0, variable_pointer2 = 0, variable_pointer3 = 0; - guint16 optional_pointer = 0, orig_opt_ptr = 0; - guint16 offset = 0; - gboolean save_fragmented; + guint16 variable_pointer1 = 0, variable_pointer2 = 0, variable_pointer3 = 0; + guint16 optional_pointer = 0, orig_opt_ptr = 0; + guint16 offset = 0; + gboolean save_fragmented; tvbuff_t *new_tvb = NULL; fragment_data *frag_msg = NULL; - guint32 source_local_ref=0; - guint8 more; - guint msg_offset = tvb_offset_from_real_beginning(tvb); + guint32 source_local_ref = 0; + guint8 more; + guint msg_offset = tvb_offset_from_real_beginning(tvb); /* Macro for getting pointer to mandatory variable parameters */ #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); \ + do { \ + if (ptr_size == POINTER_LENGTH) \ + var = tvb_get_guint8(tvb, offset); \ + else \ + var = tvb_get_letohs(tvb, offset); \ proto_tree_add_uint(sccp_tree, hf_var, tvb, \ - offset, ptr_size, var); \ - var += offset; \ - if (ptr_size == POINTER_LENGTH_LONG) \ - var += 1; \ - offset += ptr_size; + offset, ptr_size, var); \ + var += offset; \ + if (ptr_size == POINTER_LENGTH_LONG) \ + var += 1; \ + offset += ptr_size; \ + } while (0) /* Macro for getting pointer to optional parameters */ -#define OPTIONAL_POINTER(ptr_size) \ - if (ptr_size == POINTER_LENGTH) \ - orig_opt_ptr = optional_pointer = tvb_get_guint8(tvb, offset); \ - else \ - orig_opt_ptr = optional_pointer = tvb_get_letohs(tvb, offset); \ - proto_tree_add_uint(sccp_tree, hf_sccp_optional_pointer, tvb, \ - offset, ptr_size, optional_pointer); \ - optional_pointer += offset; \ - if (ptr_size == POINTER_LENGTH_LONG) \ - optional_pointer += 1; \ - offset += ptr_size; +#define OPTIONAL_POINTER(ptr_size) \ + do { \ + if (ptr_size == POINTER_LENGTH) \ + orig_opt_ptr = optional_pointer = tvb_get_guint8(tvb, offset); \ + else \ + orig_opt_ptr = optional_pointer = tvb_get_letohs(tvb, offset); \ + proto_tree_add_uint(sccp_tree, hf_sccp_optional_pointer, tvb, \ + offset, ptr_size, optional_pointer); \ + optional_pointer += offset; \ + if (ptr_size == POINTER_LENGTH_LONG) \ + optional_pointer += 1; \ + offset += ptr_size; \ + } while (0) /* Extract the message type; all other processing is based on this */ @@ -2702,51 +2720,51 @@ dissect_sccp_message(tvbuff_t *tvb, packet_info *pinfo, proto_tree *sccp_tree, * put that info there should call col_set_fence() to protect it. */ col_add_fstr(pinfo->cinfo, COL_INFO, "%s ", - val_to_str(message_type, sccp_message_type_acro_values, "Unknown: %d")); + val_to_str(message_type, sccp_message_type_acro_values, "Unknown: %d")); if (sccp_tree) { /* add the message type to the protocol tree */ proto_tree_add_uint(sccp_tree, hf_sccp_message_type, tvb, - SCCP_MSG_TYPE_OFFSET, SCCP_MSG_TYPE_LENGTH, message_type); + SCCP_MSG_TYPE_OFFSET, SCCP_MSG_TYPE_LENGTH, message_type); }; /* Starting a new message dissection; clear the global assoc, SLR, and DLR values */ - dlr = INVALID_LR; - slr = INVALID_LR; + dlr = INVALID_LR; + slr = INVALID_LR; assoc = NULL; - no_assoc.calling_dpc = 0; - no_assoc.called_dpc = 0; - no_assoc.calling_ssn = INVALID_SSN; - no_assoc.called_ssn = INVALID_SSN; - no_assoc.has_fw_key = FALSE; - no_assoc.has_bw_key = FALSE; - no_assoc.payload = SCCP_PLOAD_NONE; - no_assoc.called_party = NULL; + no_assoc.calling_dpc = 0; + no_assoc.called_dpc = 0; + no_assoc.calling_ssn = INVALID_SSN; + no_assoc.called_ssn = INVALID_SSN; + no_assoc.has_fw_key = FALSE; + no_assoc.has_bw_key = FALSE; + no_assoc.payload = SCCP_PLOAD_NONE; + no_assoc.called_party = NULL; no_assoc.calling_party = NULL; - no_assoc.extra_info = NULL; + no_assoc.extra_info = NULL; - switch(message_type) { + switch (message_type) { case SCCP_MSG_TYPE_CR: - /* 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... - */ + /* 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... + */ offset += dissect_sccp_parameter(tvb, pinfo, sccp_tree, tree, - PARAMETER_SOURCE_LOCAL_REFERENCE, - offset, SOURCE_LOCAL_REFERENCE_LENGTH); + PARAMETER_SOURCE_LOCAL_REFERENCE, + offset, SOURCE_LOCAL_REFERENCE_LENGTH); offset += dissect_sccp_parameter(tvb, pinfo, sccp_tree, tree, - PARAMETER_CLASS, offset, - PROTOCOL_CLASS_LENGTH); + PARAMETER_CLASS, offset, + PROTOCOL_CLASS_LENGTH); assoc = get_sccp_assoc(pinfo, msg_offset, slr, dlr, message_type); - VARIABLE_POINTER(variable_pointer1, hf_sccp_variable_pointer1, POINTER_LENGTH) - OPTIONAL_POINTER(POINTER_LENGTH) + VARIABLE_POINTER(variable_pointer1, hf_sccp_variable_pointer1, POINTER_LENGTH); + OPTIONAL_POINTER(POINTER_LENGTH); dissect_sccp_variable_parameter(tvb, pinfo, sccp_tree, tree, - PARAMETER_CALLED_PARTY_ADDRESS, - variable_pointer1); + PARAMETER_CALLED_PARTY_ADDRESS, + variable_pointer1); break; case SCCP_MSG_TYPE_CC: @@ -2757,49 +2775,49 @@ dissect_sccp_message(tvbuff_t *tvb, packet_info *pinfo, proto_tree *sccp_tree, * sub-dissected). */ offset += dissect_sccp_parameter(tvb, pinfo, sccp_tree, tree, - PARAMETER_DESTINATION_LOCAL_REFERENCE, - offset, - DESTINATION_LOCAL_REFERENCE_LENGTH); + 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); + PARAMETER_SOURCE_LOCAL_REFERENCE, + offset, SOURCE_LOCAL_REFERENCE_LENGTH); assoc = get_sccp_assoc(pinfo, msg_offset, slr, dlr, message_type); offset += dissect_sccp_parameter(tvb, pinfo, sccp_tree, tree, - PARAMETER_CLASS, offset, - PROTOCOL_CLASS_LENGTH); + PARAMETER_CLASS, offset, + PROTOCOL_CLASS_LENGTH); OPTIONAL_POINTER(POINTER_LENGTH); break; case SCCP_MSG_TYPE_CREF: offset += dissect_sccp_parameter(tvb, pinfo, sccp_tree, tree, - PARAMETER_DESTINATION_LOCAL_REFERENCE, - offset, - DESTINATION_LOCAL_REFERENCE_LENGTH); + PARAMETER_DESTINATION_LOCAL_REFERENCE, + offset, + DESTINATION_LOCAL_REFERENCE_LENGTH); assoc = get_sccp_assoc(pinfo, msg_offset, slr, dlr, message_type); offset += dissect_sccp_parameter(tvb, pinfo, sccp_tree, tree, - PARAMETER_REFUSAL_CAUSE, offset, - REFUSAL_CAUSE_LENGTH); + PARAMETER_REFUSAL_CAUSE, offset, + REFUSAL_CAUSE_LENGTH); OPTIONAL_POINTER(POINTER_LENGTH); break; case SCCP_MSG_TYPE_RLSD: offset += dissect_sccp_parameter(tvb, pinfo, sccp_tree, tree, - PARAMETER_DESTINATION_LOCAL_REFERENCE, - offset, - DESTINATION_LOCAL_REFERENCE_LENGTH); + 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); + PARAMETER_SOURCE_LOCAL_REFERENCE, + offset, SOURCE_LOCAL_REFERENCE_LENGTH); assoc = get_sccp_assoc(pinfo, msg_offset, slr, dlr, message_type); offset += dissect_sccp_parameter(tvb, pinfo, sccp_tree, tree, - PARAMETER_RELEASE_CAUSE, offset, - RELEASE_CAUSE_LENGTH); + PARAMETER_RELEASE_CAUSE, offset, + RELEASE_CAUSE_LENGTH); OPTIONAL_POINTER(POINTER_LENGTH); assoc = get_sccp_assoc(pinfo, msg_offset, slr, dlr, message_type); @@ -2807,12 +2825,12 @@ dissect_sccp_message(tvbuff_t *tvb, packet_info *pinfo, proto_tree *sccp_tree, case SCCP_MSG_TYPE_RLC: offset += dissect_sccp_parameter(tvb, pinfo, sccp_tree, tree, - PARAMETER_DESTINATION_LOCAL_REFERENCE, - offset, - DESTINATION_LOCAL_REFERENCE_LENGTH); + 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); + PARAMETER_SOURCE_LOCAL_REFERENCE, + offset, SOURCE_LOCAL_REFERENCE_LENGTH); assoc = get_sccp_assoc(pinfo, msg_offset, slr, dlr, message_type); break; @@ -2820,52 +2838,52 @@ dissect_sccp_message(tvbuff_t *tvb, packet_info *pinfo, proto_tree *sccp_tree, case SCCP_MSG_TYPE_DT1: source_local_ref = tvb_get_letoh24(tvb, offset); offset += dissect_sccp_parameter(tvb, pinfo, sccp_tree, tree, - PARAMETER_DESTINATION_LOCAL_REFERENCE, - offset, - DESTINATION_LOCAL_REFERENCE_LENGTH); + PARAMETER_DESTINATION_LOCAL_REFERENCE, + offset, + DESTINATION_LOCAL_REFERENCE_LENGTH); assoc = get_sccp_assoc(pinfo, msg_offset, slr, dlr, message_type); more = tvb_get_guint8(tvb, offset) & SEGMENTING_REASSEMBLING_MASK; offset += dissect_sccp_parameter(tvb, pinfo, sccp_tree, tree, - PARAMETER_SEGMENTING_REASSEMBLING, - offset, SEGMENTING_REASSEMBLING_LENGTH); - VARIABLE_POINTER(variable_pointer1, hf_sccp_variable_pointer1, POINTER_LENGTH) + PARAMETER_SEGMENTING_REASSEMBLING, + offset, SEGMENTING_REASSEMBLING_LENGTH); + VARIABLE_POINTER(variable_pointer1, hf_sccp_variable_pointer1, POINTER_LENGTH); /* Reassemble */ if (!sccp_xudt_desegment) { - 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); + 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); } else { - 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 SCCP", frag_msg, - &sccp_xudt_msg_frag_items, NULL, - tree); - - if (frag_msg && frag_msg->next) { /* Reassembled */ - col_append_str(pinfo->cinfo, COL_INFO, "(Message reassembled) "); - } else if (more) { /* Not last packet of reassembled message */ - col_append_str(pinfo->cinfo, COL_INFO, "(Message fragment) "); - } - - pinfo->fragmented = save_fragmented; - - if (new_tvb) - dissect_sccp_data_param(new_tvb, pinfo, tree); + 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 SCCP", frag_msg, + &sccp_xudt_msg_frag_items, NULL, + tree); + + if (frag_msg && frag_msg->next) { /* Reassembled */ + col_append_str(pinfo->cinfo, COL_INFO, "(Message reassembled) "); + } else if (more) { /* Not last packet of reassembled message */ + col_append_str(pinfo->cinfo, COL_INFO, "(Message fragment) "); + } + + pinfo->fragmented = save_fragmented; + + if (new_tvb) + dissect_sccp_data_param(new_tvb, pinfo, tree); } /* End reassemble */ @@ -2873,53 +2891,53 @@ dissect_sccp_message(tvbuff_t *tvb, packet_info *pinfo, proto_tree *sccp_tree, case SCCP_MSG_TYPE_DT2: offset += dissect_sccp_parameter(tvb, pinfo, sccp_tree, tree, - PARAMETER_DESTINATION_LOCAL_REFERENCE, - offset, - DESTINATION_LOCAL_REFERENCE_LENGTH); + PARAMETER_DESTINATION_LOCAL_REFERENCE, + offset, + DESTINATION_LOCAL_REFERENCE_LENGTH); assoc = get_sccp_assoc(pinfo, msg_offset, slr, dlr, message_type); offset += dissect_sccp_parameter(tvb, pinfo, sccp_tree, tree, - PARAMETER_SEQUENCING_SEGMENTING, offset, - SEQUENCING_SEGMENTING_LENGTH); + PARAMETER_SEQUENCING_SEGMENTING, offset, + SEQUENCING_SEGMENTING_LENGTH); break; case SCCP_MSG_TYPE_AK: offset += dissect_sccp_parameter(tvb, pinfo, sccp_tree, tree, - PARAMETER_DESTINATION_LOCAL_REFERENCE, - offset, - DESTINATION_LOCAL_REFERENCE_LENGTH); + PARAMETER_DESTINATION_LOCAL_REFERENCE, + offset, + DESTINATION_LOCAL_REFERENCE_LENGTH); assoc = get_sccp_assoc(pinfo, msg_offset, slr, dlr, message_type); offset += dissect_sccp_parameter(tvb, pinfo, sccp_tree, tree, - PARAMETER_RECEIVE_SEQUENCE_NUMBER, - offset, RECEIVE_SEQUENCE_NUMBER_LENGTH); + PARAMETER_RECEIVE_SEQUENCE_NUMBER, + offset, RECEIVE_SEQUENCE_NUMBER_LENGTH); offset += dissect_sccp_parameter(tvb, pinfo, sccp_tree, tree, - PARAMETER_CREDIT, offset, CREDIT_LENGTH); + PARAMETER_CREDIT, offset, CREDIT_LENGTH); break; case SCCP_MSG_TYPE_UDT: pinfo->sccp_info = sccp_msg = new_ud_msg(pinfo,message_type); offset += dissect_sccp_parameter(tvb, pinfo, sccp_tree, tree, - PARAMETER_CLASS, offset, - PROTOCOL_CLASS_LENGTH); - 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) + PARAMETER_CLASS, offset, + PROTOCOL_CLASS_LENGTH); + 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); assoc = get_sccp_assoc(pinfo, msg_offset, slr, dlr, message_type); dissect_sccp_variable_parameter(tvb, pinfo, sccp_tree, tree, - PARAMETER_CALLED_PARTY_ADDRESS, - variable_pointer1); + PARAMETER_CALLED_PARTY_ADDRESS, + variable_pointer1); dissect_sccp_variable_parameter(tvb, pinfo, sccp_tree, tree, - PARAMETER_CALLING_PARTY_ADDRESS, - variable_pointer2); + PARAMETER_CALLING_PARTY_ADDRESS, + variable_pointer2); dissect_sccp_variable_parameter(tvb, pinfo, sccp_tree, tree, PARAMETER_DATA, - variable_pointer3); + variable_pointer3); break; case SCCP_MSG_TYPE_UDTS: @@ -2930,189 +2948,189 @@ dissect_sccp_message(tvbuff_t *tvb, packet_info *pinfo, proto_tree *sccp_tree, pinfo->sccp_info = sccp_msg = new_ud_msg(pinfo,message_type); offset += dissect_sccp_parameter(tvb, pinfo, sccp_tree, tree, - PARAMETER_RETURN_CAUSE, offset, - RETURN_CAUSE_LENGTH); + PARAMETER_RETURN_CAUSE, offset, + RETURN_CAUSE_LENGTH); - 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) + 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); assoc = get_sccp_assoc(pinfo, msg_offset, slr, dlr, message_type); dissect_sccp_variable_parameter(tvb, pinfo, sccp_tree, tree, - PARAMETER_CALLED_PARTY_ADDRESS, - variable_pointer1); + PARAMETER_CALLED_PARTY_ADDRESS, + variable_pointer1); dissect_sccp_variable_parameter(tvb, pinfo, sccp_tree, tree, - PARAMETER_CALLING_PARTY_ADDRESS, - variable_pointer2); + PARAMETER_CALLING_PARTY_ADDRESS, + variable_pointer2); dissect_sccp_variable_parameter(tvb, pinfo, sccp_tree, tree, PARAMETER_DATA, - variable_pointer3); + variable_pointer3); pinfo->flags.in_error_pkt = save_in_error_pkt; break; } case SCCP_MSG_TYPE_ED: offset += dissect_sccp_parameter(tvb, pinfo, sccp_tree, tree, - PARAMETER_DESTINATION_LOCAL_REFERENCE, - offset, - DESTINATION_LOCAL_REFERENCE_LENGTH); + PARAMETER_DESTINATION_LOCAL_REFERENCE, + offset, + DESTINATION_LOCAL_REFERENCE_LENGTH); assoc = get_sccp_assoc(pinfo, msg_offset, slr, dlr, message_type); VARIABLE_POINTER(variable_pointer1, hf_sccp_variable_pointer1, POINTER_LENGTH); dissect_sccp_variable_parameter(tvb, pinfo, sccp_tree, tree, PARAMETER_DATA, - variable_pointer1); + variable_pointer1); break; case SCCP_MSG_TYPE_EA: offset += dissect_sccp_parameter(tvb, pinfo, sccp_tree, tree, - PARAMETER_DESTINATION_LOCAL_REFERENCE, - offset, - DESTINATION_LOCAL_REFERENCE_LENGTH); + PARAMETER_DESTINATION_LOCAL_REFERENCE, + offset, + DESTINATION_LOCAL_REFERENCE_LENGTH); assoc = get_sccp_assoc(pinfo, msg_offset, slr, dlr, message_type); break; case SCCP_MSG_TYPE_RSR: offset += dissect_sccp_parameter(tvb, pinfo, sccp_tree, tree, - PARAMETER_DESTINATION_LOCAL_REFERENCE, - offset, - DESTINATION_LOCAL_REFERENCE_LENGTH); + 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); + 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); + PARAMETER_RESET_CAUSE, offset, + RESET_CAUSE_LENGTH); assoc = get_sccp_assoc(pinfo, msg_offset, slr, dlr, message_type); break; case SCCP_MSG_TYPE_RSC: offset += dissect_sccp_parameter(tvb, pinfo, sccp_tree, tree, - PARAMETER_DESTINATION_LOCAL_REFERENCE, - offset, - DESTINATION_LOCAL_REFERENCE_LENGTH); + 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); + PARAMETER_SOURCE_LOCAL_REFERENCE, + offset, SOURCE_LOCAL_REFERENCE_LENGTH); assoc = get_sccp_assoc(pinfo, msg_offset, slr, dlr, message_type); break; case SCCP_MSG_TYPE_ERR: offset += dissect_sccp_parameter(tvb, pinfo, sccp_tree, tree, - PARAMETER_DESTINATION_LOCAL_REFERENCE, - offset, - DESTINATION_LOCAL_REFERENCE_LENGTH); + 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); + PARAMETER_ERROR_CAUSE, offset, + ERROR_CAUSE_LENGTH); assoc = get_sccp_assoc(pinfo, msg_offset, slr, dlr, message_type); break; case SCCP_MSG_TYPE_IT: offset += dissect_sccp_parameter(tvb, pinfo, sccp_tree, tree, - PARAMETER_DESTINATION_LOCAL_REFERENCE, - offset, - DESTINATION_LOCAL_REFERENCE_LENGTH); + 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); + PARAMETER_SOURCE_LOCAL_REFERENCE, + offset, SOURCE_LOCAL_REFERENCE_LENGTH); assoc = get_sccp_assoc(pinfo, msg_offset, slr, dlr, message_type); offset += dissect_sccp_parameter(tvb, pinfo, sccp_tree, tree, - PARAMETER_CLASS, offset, - PROTOCOL_CLASS_LENGTH); + PARAMETER_CLASS, offset, + PROTOCOL_CLASS_LENGTH); offset += dissect_sccp_parameter(tvb, pinfo, sccp_tree, tree, - PARAMETER_SEQUENCING_SEGMENTING, - offset, SEQUENCING_SEGMENTING_LENGTH); + PARAMETER_SEQUENCING_SEGMENTING, + offset, SEQUENCING_SEGMENTING_LENGTH); offset += dissect_sccp_parameter(tvb, pinfo, sccp_tree, tree, - PARAMETER_CREDIT, offset, CREDIT_LENGTH); + PARAMETER_CREDIT, offset, CREDIT_LENGTH); break; case SCCP_MSG_TYPE_XUDT: pinfo->sccp_info = sccp_msg = new_ud_msg(pinfo,message_type); offset += dissect_sccp_parameter(tvb, pinfo, sccp_tree, tree, - PARAMETER_CLASS, offset, - PROTOCOL_CLASS_LENGTH); + PARAMETER_CLASS, offset, + PROTOCOL_CLASS_LENGTH); offset += dissect_sccp_parameter(tvb, pinfo, sccp_tree, tree, - PARAMETER_HOP_COUNTER, offset, - HOP_COUNTER_LENGTH); + PARAMETER_HOP_COUNTER, offset, + HOP_COUNTER_LENGTH); - 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) + 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); - /* Optional parameters are Segmentation and Importance - * NOTE 2 - Segmentation Should not be present in case of a single XUDT - * message. - */ + /* Optional parameters are Segmentation and Importance + * NOTE 2 - Segmentation Should not be present in case of a single XUDT + * message. + */ assoc = get_sccp_assoc(pinfo, msg_offset, slr, dlr, message_type); dissect_sccp_variable_parameter(tvb, pinfo, sccp_tree, tree, - PARAMETER_CALLED_PARTY_ADDRESS, - variable_pointer1); + PARAMETER_CALLED_PARTY_ADDRESS, + variable_pointer1); dissect_sccp_variable_parameter(tvb, pinfo, sccp_tree, tree, - PARAMETER_CALLING_PARTY_ADDRESS, - variable_pointer2); + PARAMETER_CALLING_PARTY_ADDRESS, + variable_pointer2); if (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 SCCP", - frag_msg, - &sccp_xudt_msg_frag_items, - NULL, tree); - - if (frag_msg) { /* Reassembled */ - col_append_str(pinfo->cinfo, COL_INFO,"(Message reassembled) "); - } else { /* Not last packet of reassembled message */ - col_append_str(pinfo->cinfo, COL_INFO,"(Message fragment) "); - } - - pinfo->fragmented = save_fragmented; - - if (new_tvb) - dissect_sccp_data_param(new_tvb, pinfo, tree); - } + 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 SCCP", + frag_msg, + &sccp_xudt_msg_frag_items, + NULL, tree); + + if (frag_msg) { /* Reassembled */ + col_append_str(pinfo->cinfo, COL_INFO,"(Message reassembled) "); + } else { /* Not last packet of reassembled message */ + 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); + dissect_sccp_variable_parameter(tvb, pinfo, sccp_tree, tree, + PARAMETER_DATA, variable_pointer3); } break; @@ -3123,83 +3141,83 @@ dissect_sccp_message(tvbuff_t *tvb, packet_info *pinfo, proto_tree *sccp_tree, pinfo->sccp_info = sccp_msg = new_ud_msg(pinfo,message_type); offset += dissect_sccp_parameter(tvb, pinfo, sccp_tree, tree, - PARAMETER_RETURN_CAUSE, offset, - RETURN_CAUSE_LENGTH); + PARAMETER_RETURN_CAUSE, offset, + RETURN_CAUSE_LENGTH); offset += dissect_sccp_parameter(tvb, pinfo, sccp_tree, tree, - PARAMETER_HOP_COUNTER, offset, - HOP_COUNTER_LENGTH); + PARAMETER_HOP_COUNTER, offset, + HOP_COUNTER_LENGTH); - 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) + 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); assoc = get_sccp_assoc(pinfo, msg_offset, slr, dlr, message_type); dissect_sccp_variable_parameter(tvb, pinfo, sccp_tree, tree, - PARAMETER_CALLED_PARTY_ADDRESS, - variable_pointer1); + PARAMETER_CALLED_PARTY_ADDRESS, + variable_pointer1); dissect_sccp_variable_parameter(tvb, pinfo, sccp_tree, tree, - PARAMETER_CALLING_PARTY_ADDRESS, - variable_pointer2); + PARAMETER_CALLING_PARTY_ADDRESS, + variable_pointer2); if (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 SCCP", - frag_msg, - &sccp_xudt_msg_frag_items, - NULL, tree); - - if (frag_msg) { /* Reassembled */ - col_append_str(pinfo->cinfo, COL_INFO, "(Message reassembled) "); - } else { /* Not last packet of reassembled message */ - col_append_str(pinfo->cinfo, COL_INFO, "(Message fragment) "); - } - - pinfo->fragmented = save_fragmented; - - if (new_tvb) - dissect_sccp_data_param(new_tvb, pinfo, tree); - } + 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 SCCP", + frag_msg, + &sccp_xudt_msg_frag_items, + NULL, tree); + + if (frag_msg) { /* Reassembled */ + col_append_str(pinfo->cinfo, COL_INFO, "(Message reassembled) "); + } else { /* Not last packet of reassembled message */ + 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); + dissect_sccp_variable_parameter(tvb, pinfo, sccp_tree, tree, + PARAMETER_DATA, variable_pointer3); } pinfo->flags.in_error_pkt = save_in_error_pkt; break; @@ -3208,53 +3226,53 @@ dissect_sccp_message(tvbuff_t *tvb, packet_info *pinfo, proto_tree *sccp_tree, pinfo->sccp_info = sccp_msg = new_ud_msg(pinfo,message_type); offset += dissect_sccp_parameter(tvb, pinfo, sccp_tree, tree, - PARAMETER_CLASS, offset, - PROTOCOL_CLASS_LENGTH); + PARAMETER_CLASS, offset, + PROTOCOL_CLASS_LENGTH); offset += dissect_sccp_parameter(tvb, pinfo, sccp_tree, tree, - PARAMETER_HOP_COUNTER, offset, - HOP_COUNTER_LENGTH); + PARAMETER_HOP_COUNTER, offset, + HOP_COUNTER_LENGTH); - 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) + 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); assoc = get_sccp_assoc(pinfo, msg_offset, slr, dlr, message_type); dissect_sccp_variable_parameter(tvb, pinfo, sccp_tree, tree, - PARAMETER_CALLED_PARTY_ADDRESS, - variable_pointer1); + PARAMETER_CALLED_PARTY_ADDRESS, + variable_pointer1); dissect_sccp_variable_parameter(tvb, pinfo, sccp_tree, tree, - PARAMETER_CALLING_PARTY_ADDRESS, - variable_pointer2); + PARAMETER_CALLING_PARTY_ADDRESS, + variable_pointer2); dissect_sccp_variable_parameter(tvb, pinfo, sccp_tree, tree, - PARAMETER_LONG_DATA, variable_pointer3); + PARAMETER_LONG_DATA, variable_pointer3); break; case SCCP_MSG_TYPE_LUDTS: pinfo->sccp_info = sccp_msg = new_ud_msg(pinfo,message_type); offset += dissect_sccp_parameter(tvb, pinfo, sccp_tree, tree, - PARAMETER_RETURN_CAUSE, offset, - RETURN_CAUSE_LENGTH); + PARAMETER_RETURN_CAUSE, offset, + RETURN_CAUSE_LENGTH); offset += dissect_sccp_parameter(tvb, pinfo, sccp_tree, tree, - PARAMETER_HOP_COUNTER, offset, - HOP_COUNTER_LENGTH); + PARAMETER_HOP_COUNTER, offset, + HOP_COUNTER_LENGTH); - 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) + 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); assoc = get_sccp_assoc(pinfo, msg_offset, slr, dlr, message_type); dissect_sccp_variable_parameter(tvb, pinfo, sccp_tree, tree, - PARAMETER_CALLED_PARTY_ADDRESS, - variable_pointer1); + PARAMETER_CALLED_PARTY_ADDRESS, + variable_pointer1); dissect_sccp_variable_parameter(tvb, pinfo, sccp_tree, tree, - PARAMETER_CALLING_PARTY_ADDRESS, - variable_pointer2); + PARAMETER_CALLING_PARTY_ADDRESS, + variable_pointer2); dissect_sccp_variable_parameter(tvb, pinfo, sccp_tree, tree, - PARAMETER_LONG_DATA, variable_pointer3); + PARAMETER_LONG_DATA, variable_pointer3); break; default: @@ -3263,30 +3281,30 @@ dissect_sccp_message(tvbuff_t *tvb, packet_info *pinfo, proto_tree *sccp_tree, if (orig_opt_ptr) dissect_sccp_optional_parameters(tvb, pinfo, sccp_tree, tree, - optional_pointer); - - 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; - for(m = assoc->msgs; m ; m = m->data.co.next) { - pi = proto_tree_add_uint(pt, hf_sccp_assoc_msg, tvb, 0, 0, m->framenum); + optional_pointer); - if (assoc->payload != SCCP_PLOAD_NONE) - proto_item_append_text(pi," %s", val_to_str(assoc->payload, assoc_protos, "Unknown: %d")); - - if (m->data.co.label) - proto_item_append_text(pi," %s", m->data.co.label); - - if (m->framenum == PINFO_FD_NUM(pinfo) && m->offset == msg_offset ) { - tap_queue_packet(sccp_tap, pinfo, m); - proto_item_append_text(pi," (current)"); - } - PROTO_ITEM_SET_GENERATED(pi); - } - } + 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; + for(m = assoc->msgs; m ; m = m->data.co.next) { + pi = proto_tree_add_uint(pt, hf_sccp_assoc_msg, tvb, 0, 0, m->framenum); + + if (assoc->payload != SCCP_PLOAD_NONE) + proto_item_append_text(pi," %s", val_to_str(assoc->payload, assoc_protos, "Unknown: %d")); + + if (m->data.co.label) + proto_item_append_text(pi," %s", m->data.co.label); + + if ((m->framenum == PINFO_FD_NUM(pinfo)) && (m->offset == msg_offset) ) { + tap_queue_packet(sccp_tap, pinfo, m); + proto_item_append_text(pi," (current)"); + } + PROTO_ITEM_SET_GENERATED(pi); + } + } } } @@ -3315,19 +3333,19 @@ dissect_sccp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) } /* Make entry in the Protocol column on summary display */ - switch(decode_mtp3_standard) { - case ITU_STANDARD: - col_set_str(pinfo->cinfo, COL_PROTOCOL, "SCCP (Int. ITU)"); - break; - case ANSI_STANDARD: - col_set_str(pinfo->cinfo, COL_PROTOCOL, "SCCP (ANSI)"); - break; - case CHINESE_ITU_STANDARD: - col_set_str(pinfo->cinfo, COL_PROTOCOL, "SCCP (Chin. ITU)"); - break; - case JAPAN_STANDARD: - col_set_str(pinfo->cinfo, COL_PROTOCOL, "SCCP (Japan)"); - break; + switch (decode_mtp3_standard) { + case ITU_STANDARD: + col_set_str(pinfo->cinfo, COL_PROTOCOL, "SCCP (Int. ITU)"); + break; + case ANSI_STANDARD: + col_set_str(pinfo->cinfo, COL_PROTOCOL, "SCCP (ANSI)"); + break; + case CHINESE_ITU_STANDARD: + col_set_str(pinfo->cinfo, COL_PROTOCOL, "SCCP (Chin. ITU)"); + break; + case JAPAN_STANDARD: + col_set_str(pinfo->cinfo, COL_PROTOCOL, "SCCP (Japan)"); + break; }; /* In the interest of speed, if "tree" is NULL, don't do any work not @@ -3349,16 +3367,16 @@ dissect_sccp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) mtp3_addr_p = (const mtp3_addr_pc_t *)pinfo->src.data; if (sccp_source_pc_global == mtp3_addr_p->pc) { - pinfo->p2p_dir = P2P_DIR_SENT; + pinfo->p2p_dir = P2P_DIR_SENT; } else { /* assuming if src was SS7 PC then dst will be too */ mtp3_addr_p = (const mtp3_addr_pc_t *)pinfo->dst.data; if (sccp_source_pc_global == mtp3_addr_p->pc) { - pinfo->p2p_dir = P2P_DIR_RECV; + pinfo->p2p_dir = P2P_DIR_RECV; } else { - pinfo->p2p_dir = P2P_DIR_UNKNOWN; + pinfo->p2p_dir = P2P_DIR_UNKNOWN; } } } @@ -3371,60 +3389,64 @@ dissect_sccp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) /*** 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} + 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} }; static void -sccp_users_update_cb(void* r, const char** err _U_) +sccp_users_update_cb(void *r, const char **err _U_) { - sccp_user_t* u = r; - struct _sccp_ul* c; - - for (c=user_list; c->handlep; c++) { - if (c->id == u->user) { - u->uses_tcap = c->uses_tcap; - u->handlep = c->handlep; - return; - } - } - - u->uses_tcap = FALSE; - u->handlep = &data_handle; + sccp_user_t *u = r; + struct _sccp_ul *c; + + for (c=user_list; c->handlep; c++) { + if (c->id == u->user) { + u->uses_tcap = c->uses_tcap; + u->handlep = c->handlep; + return; + } + } + + u->uses_tcap = FALSE; + u->handlep = &data_handle; } static void * -sccp_users_copy_cb(void* n, const void* o, size_t siz _U_) +sccp_users_copy_cb(void *n, const void *o, size_t siz _U_) { - const sccp_user_t* u = o; - sccp_user_t* un = n; + const sccp_user_t *u = o; + sccp_user_t *un = n; + + un->ni = u->ni; + un->user = u->user; + un->uses_tcap = u->uses_tcap; + un->handlep = u->handlep; - 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); - if (u->called_ssn) un->called_ssn = range_copy(u->called_ssn); + if (u->called_pc) + un->called_pc = range_copy(u->called_pc); + if (u->called_ssn) + un->called_ssn = range_copy(u->called_ssn); - return n; + return n; } static void -sccp_users_free_cb(void*r) +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); + sccp_user_t *u = r; + if (u->called_pc) g_free(u->called_pc); + if (u->called_ssn) g_free(u->called_ssn); } @@ -3439,9 +3461,9 @@ UAT_VS_DEF(sccp_users, user, sccp_user_t, SCCP_USER_DATA, "Data") static void init_sccp(void) { - next_assoc_id = 1; - fragment_table_init (&sccp_xudt_msg_fragment_table); - reassembled_table_init(&sccp_xudt_msg_reassembled_table); + next_assoc_id = 1; + fragment_table_init (&sccp_xudt_msg_fragment_table); + reassembled_table_init(&sccp_xudt_msg_reassembled_table); } @@ -3453,404 +3475,480 @@ proto_register_sccp(void) static hf_register_info hf[] = { { &hf_sccp_message_type, { "Message Type", "sccp.message_type", - FT_UINT8, BASE_HEX, VALS(sccp_message_type_values), 0x0, - NULL, HFILL}}, + FT_UINT8, BASE_HEX, VALS(sccp_message_type_values), 0x0, + NULL, HFILL} + }, { &hf_sccp_variable_pointer1, { "Pointer to first Mandatory Variable parameter", "sccp.variable_pointer1", - FT_UINT16, BASE_DEC, NULL, 0x0, - NULL, HFILL}}, + FT_UINT16, BASE_DEC, NULL, 0x0, + NULL, HFILL} + }, { &hf_sccp_variable_pointer2, { "Pointer to second Mandatory Variable parameter", "sccp.variable_pointer2", - FT_UINT16, BASE_DEC, NULL, 0x0, - NULL, HFILL}}, + FT_UINT16, BASE_DEC, NULL, 0x0, + NULL, HFILL} + }, { &hf_sccp_variable_pointer3, { "Pointer to third Mandatory Variable parameter", "sccp.variable_pointer3", - FT_UINT16, BASE_DEC, NULL, 0x0, - NULL, HFILL}}, + FT_UINT16, BASE_DEC, NULL, 0x0, + NULL, HFILL} + }, { &hf_sccp_optional_pointer, { "Pointer to Optional parameter", "sccp.optional_pointer", - FT_UINT16, BASE_DEC, NULL, 0x0, - NULL, HFILL}}, + FT_UINT16, BASE_DEC, NULL, 0x0, + NULL, HFILL} + }, { &hf_sccp_param_length, { "Variable parameter length", "sccp.parameter_length", - FT_UINT16, BASE_DEC, NULL, 0x0, - NULL, HFILL}}, + FT_UINT16, BASE_DEC, NULL, 0x0, + NULL, HFILL} + }, { &hf_sccp_ssn, { "Called or Calling SubSystem Number", "sccp.ssn", - FT_UINT8, BASE_DEC, VALS(sccp_ssn_values), 0x0, - NULL, HFILL}}, + FT_UINT8, BASE_DEC, VALS(sccp_ssn_values), 0x0, + NULL, HFILL} + }, { &hf_sccp_gt_digits, - { "Called or Calling GT Digits", - "sccp.digits", - FT_STRING, BASE_NONE, NULL, 0x0, - NULL, HFILL }}, + { "Called or Calling GT Digits", "sccp.digits", + FT_STRING, BASE_NONE, NULL, 0x0, + NULL, HFILL } + }, { &hf_sccp_called_national_indicator, { "National Indicator", "sccp.called.ni", - FT_UINT8, BASE_HEX, VALS(sccp_national_indicator_values), ANSI_NATIONAL_MASK, - NULL, HFILL}}, + FT_UINT8, BASE_HEX, VALS(sccp_national_indicator_values), ANSI_NATIONAL_MASK, + NULL, HFILL} + }, { &hf_sccp_called_routing_indicator, { "Routing Indicator", "sccp.called.ri", - FT_UINT8, BASE_HEX, VALS(sccp_routing_indicator_values), ROUTING_INDICATOR_MASK, - NULL, HFILL}}, + FT_UINT8, BASE_HEX, VALS(sccp_routing_indicator_values), ROUTING_INDICATOR_MASK, + NULL, 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, - NULL, HFILL}}, + FT_UINT8, BASE_HEX, VALS(sccp_itu_global_title_indicator_values), GTI_MASK, + NULL, 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, - NULL, HFILL}}, + FT_UINT8, BASE_HEX, VALS(sccp_ansi_global_title_indicator_values), GTI_MASK, + NULL, 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, - NULL, HFILL}}, + FT_UINT8, BASE_HEX, VALS(sccp_ai_ssni_values), ITU_SSN_INDICATOR_MASK, + NULL, 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, - NULL, HFILL}}, + FT_UINT8, BASE_HEX, VALS(sccp_ai_pci_values), ITU_PC_INDICATOR_MASK, + NULL, 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, - NULL, HFILL}}, + FT_UINT8, BASE_HEX, VALS(sccp_ai_ssni_values), ANSI_SSN_INDICATOR_MASK, + NULL, 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, - NULL, HFILL}}, + FT_UINT8, BASE_HEX, VALS(sccp_ai_pci_values), ANSI_PC_INDICATOR_MASK, + NULL, HFILL} + }, { &hf_sccp_called_ssn, { "SubSystem Number", "sccp.called.ssn", - FT_UINT8, BASE_DEC, VALS(sccp_ssn_values), 0x0, - NULL, HFILL}}, + FT_UINT8, BASE_DEC, VALS(sccp_ssn_values), 0x0, + NULL, HFILL} + }, { &hf_sccp_called_itu_pc, { "PC", "sccp.called.pc", - FT_UINT16, BASE_DEC, NULL, ITU_PC_MASK, - NULL, HFILL}}, + FT_UINT16, BASE_DEC, NULL, ITU_PC_MASK, + NULL, HFILL} + }, { &hf_sccp_called_ansi_pc, { "PC", "sccp.called.ansi_pc", - FT_STRING, BASE_NONE, NULL, 0x0, - NULL, HFILL}}, + FT_STRING, BASE_NONE, NULL, 0x0, + NULL, HFILL} + }, { &hf_sccp_called_chinese_pc, { "PC", "sccp.called.chinese_pc", - FT_STRING, BASE_NONE, NULL, 0x0, - NULL, HFILL}}, + FT_STRING, BASE_NONE, NULL, 0x0, + NULL, HFILL} + }, { &hf_sccp_called_japan_pc, { "PC", "sccp.called.pc", - FT_UINT16, BASE_DEC, NULL, 0x0, - NULL, HFILL}}, + FT_UINT16, BASE_DEC, NULL, 0x0, + NULL, HFILL} + }, { &hf_sccp_called_pc_network, - { "PC Network", - "sccp.called.network", - FT_UINT24, BASE_DEC, NULL, ANSI_NETWORK_MASK, - NULL, HFILL }}, + { "PC Network", "sccp.called.network", + FT_UINT24, BASE_DEC, NULL, ANSI_NETWORK_MASK, + NULL, HFILL } + }, { &hf_sccp_called_pc_cluster, - { "PC Cluster", - "sccp.called.cluster", - FT_UINT24, BASE_DEC, NULL, ANSI_CLUSTER_MASK, - NULL, HFILL }}, + { "PC Cluster", "sccp.called.cluster", + FT_UINT24, BASE_DEC, NULL, ANSI_CLUSTER_MASK, + NULL, HFILL } + }, { &hf_sccp_called_pc_member, - { "PC Member", - "sccp.called.member", - FT_UINT24, BASE_DEC, NULL, ANSI_MEMBER_MASK, - NULL, HFILL }}, + { "PC Member", "sccp.called.member", + FT_UINT24, BASE_DEC, NULL, ANSI_MEMBER_MASK, + NULL, HFILL } + }, { &hf_sccp_called_gt_nai, - { "Nature of Address Indicator", - "sccp.called.nai", - FT_UINT8, BASE_HEX, VALS(sccp_nai_values), GT_NAI_MASK, - NULL, HFILL }}, + { "Nature of Address Indicator", "sccp.called.nai", + FT_UINT8, BASE_HEX, VALS(sccp_nai_values), GT_NAI_MASK, + NULL, HFILL } + }, { &hf_sccp_called_gt_oe, - { "Odd/Even Indicator", - "sccp.called.oe", - FT_UINT8, BASE_HEX, VALS(sccp_oe_values), GT_OE_MASK, - NULL, HFILL }}, + { "Odd/Even Indicator", "sccp.called.oe", + FT_UINT8, BASE_HEX, VALS(sccp_oe_values), GT_OE_MASK, + NULL, HFILL } + }, { &hf_sccp_called_gt_tt, - { "Translation Type", - "sccp.called.tt", - FT_UINT8, BASE_HEX, NULL, 0x0, - NULL, HFILL }}, + { "Translation Type", "sccp.called.tt", + FT_UINT8, BASE_HEX, NULL, 0x0, + NULL, HFILL } + }, { &hf_sccp_called_gt_np, - { "Numbering Plan", - "sccp.called.np", - FT_UINT8, BASE_HEX, VALS(sccp_np_values), GT_NP_MASK, - NULL, HFILL }}, + { "Numbering Plan", "sccp.called.np", + FT_UINT8, BASE_HEX, VALS(sccp_np_values), GT_NP_MASK, + NULL, HFILL } + }, { &hf_sccp_called_gt_es, - { "Encoding Scheme", - "sccp.called.es", - FT_UINT8, BASE_HEX, VALS(sccp_es_values), GT_ES_MASK, - NULL, HFILL }}, + { "Encoding Scheme", "sccp.called.es", + FT_UINT8, BASE_HEX, VALS(sccp_es_values), GT_ES_MASK, + NULL, HFILL } + }, { &hf_sccp_called_gt_digits, - { "Called Party Digits", - "sccp.called.digits", - FT_STRING, BASE_NONE, NULL, 0x0, - NULL, HFILL }}, + { "Called Party Digits", "sccp.called.digits", + FT_STRING, BASE_NONE, NULL, 0x0, + NULL, HFILL } + }, { &hf_sccp_called_gt_digits_length, - { "Number of Called Party Digits", - "sccp.called.digits.length", - FT_UINT8, BASE_DEC, NULL, 0x0, - NULL, HFILL }}, + { "Number of Called Party Digits", "sccp.called.digits.length", + FT_UINT8, BASE_DEC, NULL, 0x0, + NULL, HFILL } + }, { &hf_sccp_calling_national_indicator, { "National Indicator", "sccp.calling.ni", - FT_UINT8, BASE_HEX, VALS(sccp_national_indicator_values), ANSI_NATIONAL_MASK, - NULL, HFILL}}, + FT_UINT8, BASE_HEX, VALS(sccp_national_indicator_values), ANSI_NATIONAL_MASK, + NULL, HFILL} + }, { &hf_sccp_calling_routing_indicator, { "Routing Indicator", "sccp.calling.ri", - FT_UINT8, BASE_HEX, VALS(sccp_routing_indicator_values), ROUTING_INDICATOR_MASK, - NULL, HFILL}}, + FT_UINT8, BASE_HEX, VALS(sccp_routing_indicator_values), ROUTING_INDICATOR_MASK, + NULL, 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, - NULL, HFILL}}, + FT_UINT8, BASE_HEX, VALS(sccp_itu_global_title_indicator_values), GTI_MASK, + NULL, 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, - NULL, HFILL}}, + FT_UINT8, BASE_HEX, VALS(sccp_ansi_global_title_indicator_values), GTI_MASK, + NULL, 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, - NULL, HFILL}}, + FT_UINT8, BASE_HEX, VALS(sccp_ai_ssni_values), ITU_SSN_INDICATOR_MASK, + NULL, 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, - NULL, HFILL}}, + FT_UINT8, BASE_HEX, VALS(sccp_ai_pci_values), ITU_PC_INDICATOR_MASK, + NULL, 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, - NULL, HFILL}}, + FT_UINT8, BASE_HEX, VALS(sccp_ai_ssni_values), ANSI_SSN_INDICATOR_MASK, + NULL, 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, - NULL, HFILL}}, + FT_UINT8, BASE_HEX, VALS(sccp_ai_pci_values), ANSI_PC_INDICATOR_MASK, + NULL, HFILL} + }, { &hf_sccp_calling_ssn, { "SubSystem Number", "sccp.calling.ssn", - FT_UINT8, BASE_DEC, VALS(sccp_ssn_values), 0x0, - NULL, HFILL}}, + FT_UINT8, BASE_DEC, VALS(sccp_ssn_values), 0x0, + NULL, HFILL} + }, { &hf_sccp_calling_itu_pc, { "PC", "sccp.calling.pc", - FT_UINT16, BASE_DEC, NULL, ITU_PC_MASK, - NULL, HFILL}}, + FT_UINT16, BASE_DEC, NULL, ITU_PC_MASK, + NULL, HFILL} + }, { &hf_sccp_calling_ansi_pc, { "PC", "sccp.calling.ansi_pc", - FT_STRING, BASE_NONE, NULL, 0x0, - NULL, HFILL}}, + FT_STRING, BASE_NONE, NULL, 0x0, + NULL, HFILL} + }, { &hf_sccp_calling_chinese_pc, { "PC", "sccp.calling.chinese_pc", - FT_STRING, BASE_NONE, NULL, 0x0, - NULL, HFILL}}, + FT_STRING, BASE_NONE, NULL, 0x0, + NULL, HFILL} + }, { &hf_sccp_calling_japan_pc, { "PC", "sccp.calling.pc", - FT_UINT16, BASE_DEC, NULL, 0x0, - NULL, HFILL}}, + FT_UINT16, BASE_DEC, NULL, 0x0, + NULL, HFILL} + }, { &hf_sccp_calling_pc_network, - { "PC Network", - "sccp.calling.network", - FT_UINT24, BASE_DEC, NULL, ANSI_NETWORK_MASK, - NULL, HFILL }}, + { "PC Network", "sccp.calling.network", + FT_UINT24, BASE_DEC, NULL, ANSI_NETWORK_MASK, + NULL, HFILL } + }, { &hf_sccp_calling_pc_cluster, - { "PC Cluster", - "sccp.calling.cluster", - FT_UINT24, BASE_DEC, NULL, ANSI_CLUSTER_MASK, - NULL, HFILL }}, + { "PC Cluster", "sccp.calling.cluster", + FT_UINT24, BASE_DEC, NULL, ANSI_CLUSTER_MASK, + NULL, HFILL } + }, { &hf_sccp_calling_pc_member, - { "PC Member", - "sccp.calling.member", - FT_UINT24, BASE_DEC, NULL, ANSI_MEMBER_MASK, - NULL, HFILL }}, + { "PC Member", "sccp.calling.member", + FT_UINT24, BASE_DEC, NULL, ANSI_MEMBER_MASK, + NULL, HFILL } + }, { &hf_sccp_calling_gt_nai, - { "Nature of Address Indicator", - "sccp.calling.nai", - FT_UINT8, BASE_HEX, VALS(sccp_nai_values), GT_NAI_MASK, - NULL, HFILL }}, + { "Nature of Address Indicator", "sccp.calling.nai", + FT_UINT8, BASE_HEX, VALS(sccp_nai_values), GT_NAI_MASK, + NULL, HFILL } + }, { &hf_sccp_calling_gt_oe, - { "Odd/Even Indicator", - "sccp.calling.oe", - FT_UINT8, BASE_HEX, VALS(sccp_oe_values), GT_OE_MASK, - NULL, HFILL }}, + { "Odd/Even Indicator", "sccp.calling.oe", + FT_UINT8, BASE_HEX, VALS(sccp_oe_values), GT_OE_MASK, + NULL, HFILL } + }, { &hf_sccp_calling_gt_tt, - { "Translation Type", - "sccp.calling.tt", - FT_UINT8, BASE_HEX, NULL, 0x0, - NULL, HFILL }}, + { "Translation Type", "sccp.calling.tt", + FT_UINT8, BASE_HEX, NULL, 0x0, + NULL, HFILL } + }, { &hf_sccp_calling_gt_np, - { "Numbering Plan", - "sccp.calling.np", - FT_UINT8, BASE_HEX, VALS(sccp_np_values), GT_NP_MASK, - NULL, HFILL }}, + { "Numbering Plan", "sccp.calling.np", + FT_UINT8, BASE_HEX, VALS(sccp_np_values), GT_NP_MASK, + NULL, HFILL } + }, { &hf_sccp_calling_gt_es, - { "Encoding Scheme", - "sccp.calling.es", - FT_UINT8, BASE_HEX, VALS(sccp_es_values), GT_ES_MASK, - NULL, HFILL }}, + { "Encoding Scheme", "sccp.calling.es", + FT_UINT8, BASE_HEX, VALS(sccp_es_values), GT_ES_MASK, + NULL, HFILL } + }, { &hf_sccp_calling_gt_digits, - { "Calling Party Digits", - "sccp.calling.digits", - FT_STRING, BASE_NONE, NULL, 0x0, - NULL, HFILL }}, + { "Calling Party Digits", "sccp.calling.digits", + FT_STRING, BASE_NONE, NULL, 0x0, + NULL, HFILL } + }, { &hf_sccp_calling_gt_digits_length, - { "Number of Calling Party Digits", - "sccp.calling.digits.length", - FT_UINT8, BASE_DEC, NULL, 0x0, - NULL, HFILL }}, + { "Number of Calling Party Digits", "sccp.calling.digits.length", + FT_UINT8, BASE_DEC, NULL, 0x0, + NULL, HFILL } + }, { &hf_sccp_dlr, { "Destination Local Reference", "sccp.dlr", - FT_UINT24, BASE_HEX, NULL, 0x0, - NULL, HFILL}}, + FT_UINT24, BASE_HEX, NULL, 0x0, + NULL, HFILL} + }, { &hf_sccp_slr, { "Source Local Reference", "sccp.slr", - FT_UINT24, BASE_HEX, NULL, 0x0, - NULL, HFILL}}, + FT_UINT24, BASE_HEX, NULL, 0x0, + NULL, HFILL} + }, { &hf_sccp_lr, - { "Local Reference", "sccp.lr", - FT_UINT24, BASE_HEX, NULL, 0x0, - NULL, HFILL}}, + { "Local Reference", "sccp.lr", + FT_UINT24, BASE_HEX, NULL, 0x0, + NULL, HFILL} + }, { &hf_sccp_class, { "Class", "sccp.class", - FT_UINT8, BASE_HEX, NULL, CLASS_CLASS_MASK, - NULL, HFILL}}, + FT_UINT8, BASE_HEX, NULL, CLASS_CLASS_MASK, + NULL, HFILL} + }, { &hf_sccp_handling, { "Message handling", "sccp.handling", - FT_UINT8, BASE_HEX, VALS(sccp_class_handling_values), CLASS_SPARE_HANDLING_MASK, - NULL, HFILL}}, + FT_UINT8, BASE_HEX, VALS(sccp_class_handling_values), CLASS_SPARE_HANDLING_MASK, + NULL, HFILL} + }, { &hf_sccp_more, { "More data", "sccp.more", - FT_UINT8, BASE_HEX, VALS(sccp_segmenting_reassembling_values), SEGMENTING_REASSEMBLING_MASK, - NULL, HFILL}}, + FT_UINT8, BASE_HEX, VALS(sccp_segmenting_reassembling_values), SEGMENTING_REASSEMBLING_MASK, + NULL, HFILL} + }, { &hf_sccp_rsn, { "Receive Sequence Number", "sccp.rsn", - FT_UINT8, BASE_HEX, NULL, RSN_MASK, - NULL, HFILL}}, + FT_UINT8, BASE_HEX, NULL, RSN_MASK, + NULL, HFILL} + }, { &hf_sccp_sequencing_segmenting_ssn, { "Sequencing Segmenting: Send Sequence Number", "sccp.sequencing_segmenting.ssn", - FT_UINT8, BASE_HEX, NULL, SEND_SEQUENCE_NUMBER_MASK, - NULL, HFILL}}, + FT_UINT8, BASE_HEX, NULL, SEND_SEQUENCE_NUMBER_MASK, + NULL, HFILL} + }, { &hf_sccp_sequencing_segmenting_rsn, { "Sequencing Segmenting: Receive Sequence Number", "sccp.sequencing_segmenting.rsn", - FT_UINT8, BASE_HEX, NULL, RECEIVE_SEQUENCE_NUMBER_MASK, - NULL, HFILL}}, + FT_UINT8, BASE_HEX, NULL, RECEIVE_SEQUENCE_NUMBER_MASK, + NULL, 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, - NULL, HFILL}}, + FT_UINT8, BASE_HEX, VALS(sccp_segmenting_reassembling_values), SEQUENCING_SEGMENTING_MORE_MASK, + NULL, HFILL} + }, { &hf_sccp_credit, { "Credit", "sccp.credit", - FT_UINT8, BASE_HEX, NULL, 0x0, - NULL, HFILL}}, + FT_UINT8, BASE_HEX, NULL, 0x0, + NULL, HFILL} + }, { &hf_sccp_release_cause, { "Release Cause", "sccp.release_cause", - FT_UINT8, BASE_HEX, VALS(sccp_release_cause_values), 0x0, - NULL, HFILL}}, + FT_UINT8, BASE_HEX, VALS(sccp_release_cause_values), 0x0, + NULL, HFILL} + }, { &hf_sccp_return_cause, { "Return Cause", "sccp.return_cause", - FT_UINT8, BASE_HEX, VALS(sccp_return_cause_values), 0x0, - NULL, HFILL}}, + FT_UINT8, BASE_HEX, VALS(sccp_return_cause_values), 0x0, + NULL, HFILL} + }, { &hf_sccp_reset_cause, { "Reset Cause", "sccp.reset_cause", - FT_UINT8, BASE_HEX, VALS(sccp_reset_cause_values), 0x0, - NULL, HFILL}}, + FT_UINT8, BASE_HEX, VALS(sccp_reset_cause_values), 0x0, + NULL, HFILL} + }, { &hf_sccp_error_cause, { "Error Cause", "sccp.error_cause", - FT_UINT8, BASE_HEX, VALS(sccp_error_cause_values), 0x0, - NULL, HFILL}}, + FT_UINT8, BASE_HEX, VALS(sccp_error_cause_values), 0x0, + NULL, HFILL} + }, { &hf_sccp_refusal_cause, { "Refusal Cause", "sccp.refusal_cause", - FT_UINT8, BASE_HEX, VALS(sccp_refusal_cause_values), 0x0, - NULL, HFILL}}, + FT_UINT8, BASE_HEX, VALS(sccp_refusal_cause_values), 0x0, + NULL, HFILL} + }, { &hf_sccp_segmentation_first, { "Segmentation: First", "sccp.segmentation.first", - FT_UINT8, BASE_HEX, VALS(sccp_segmentation_first_segment_values), SEGMENTATION_FIRST_SEGMENT_MASK, - NULL, HFILL}}, + FT_UINT8, BASE_HEX, VALS(sccp_segmentation_first_segment_values), SEGMENTATION_FIRST_SEGMENT_MASK, + NULL, HFILL} + }, { &hf_sccp_segmentation_class, { "Segmentation: Class", "sccp.segmentation.class", - FT_UINT8, BASE_HEX, VALS(sccp_segmentation_class_values), SEGMENTATION_CLASS_MASK, - NULL, HFILL}}, + FT_UINT8, BASE_HEX, VALS(sccp_segmentation_class_values), SEGMENTATION_CLASS_MASK, + NULL, HFILL} + }, { &hf_sccp_segmentation_remaining, { "Segmentation: Remaining", "sccp.segmentation.remaining", - FT_UINT8, BASE_HEX, NULL, SEGMENTATION_REMAINING_MASK, - NULL, HFILL}}, + FT_UINT8, BASE_HEX, NULL, SEGMENTATION_REMAINING_MASK, + NULL, HFILL} + }, { &hf_sccp_segmentation_slr, { "Segmentation: Source Local Reference", "sccp.segmentation.slr", - FT_UINT24, BASE_HEX, NULL, 0x0, - NULL, HFILL}}, + FT_UINT24, BASE_HEX, NULL, 0x0, + NULL, HFILL} + }, { &hf_sccp_hop_counter, { "Hop Counter", "sccp.hops", - FT_UINT8, BASE_HEX, NULL, 0x0, - NULL, HFILL}}, + FT_UINT8, BASE_HEX, NULL, 0x0, + NULL, HFILL} + }, { &hf_sccp_importance, { "Importance", "sccp.importance", - FT_UINT8, BASE_HEX, NULL, IMPORTANCE_IMPORTANCE_MASK, - NULL, HFILL}}, + FT_UINT8, BASE_HEX, NULL, IMPORTANCE_IMPORTANCE_MASK, + NULL, HFILL} + }, /* ISNI is ANSI only */ { &hf_sccp_ansi_isni_mi, { "ISNI Mark for Identification Indicator", "sccp.isni.mi", - FT_UINT8, BASE_HEX, VALS(sccp_isni_mark_for_id_values), ANSI_ISNI_MI_MASK, - NULL, HFILL}}, + FT_UINT8, BASE_HEX, VALS(sccp_isni_mark_for_id_values), ANSI_ISNI_MI_MASK, + NULL, HFILL} + }, { &hf_sccp_ansi_isni_iri, { "ISNI Routing Indicator", "sccp.isni.iri", - FT_UINT8, BASE_HEX, VALS(sccp_isni_iri_values), ANSI_ISNI_IRI_MASK, - NULL, HFILL}}, + FT_UINT8, BASE_HEX, VALS(sccp_isni_iri_values), ANSI_ISNI_IRI_MASK, + NULL, HFILL} + }, { &hf_sccp_ansi_isni_ti, { "ISNI Type Indicator", "sccp.isni.ti", - FT_UINT8, BASE_HEX, VALS(sccp_isni_ti_values), ANSI_ISNI_TI_MASK, - NULL, HFILL}}, + FT_UINT8, BASE_HEX, VALS(sccp_isni_ti_values), ANSI_ISNI_TI_MASK, + NULL, HFILL} + }, { &hf_sccp_ansi_isni_netspec, { "ISNI Network Specific (Type 1)", "sccp.isni.netspec", - FT_UINT8, BASE_HEX, NULL, ANSI_ISNI_NETSPEC_MASK, - NULL, HFILL}}, + FT_UINT8, BASE_HEX, NULL, ANSI_ISNI_NETSPEC_MASK, + NULL, HFILL} + }, { &hf_sccp_ansi_isni_counter, { "ISNI Counter", "sccp.isni.counter", - FT_UINT8, BASE_DEC, NULL, ANSI_ISNI_COUNTER_MASK, - NULL, HFILL}}, + FT_UINT8, BASE_DEC, NULL, ANSI_ISNI_COUNTER_MASK, + NULL, HFILL} + }, { &hf_sccp_ansi_isni_network, { "Network ID network", "sccp.isni.network", - FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL}}, + FT_UINT8, BASE_DEC, NULL, 0x0, + NULL, HFILL} + }, { &hf_sccp_ansi_isni_cluster, { "Network ID cluster", "sccp.isni.cluster", - FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL}}, + FT_UINT8, BASE_DEC, NULL, 0x0, + NULL, HFILL} + }, {&hf_sccp_xudt_msg_fragments, - {"Message fragments", "sccp.msg.fragments", - FT_NONE, BASE_NONE, NULL, 0x00, NULL, HFILL } + { "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 } + { "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, 0x0, NULL, HFILL } + { "Message fragment overlap", "sccp.msg.fragment.overlap", + FT_BOOLEAN, BASE_NONE, NULL, 0x0, + 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, 0x0, NULL, HFILL } + { "Message fragment overlapping with conflicting data", "sccp.msg.fragment.overlap.conflicts", + FT_BOOLEAN, BASE_NONE, NULL, 0x0, + NULL, HFILL } }, {&hf_sccp_xudt_msg_fragment_multiple_tails, - {"Message has multiple tail fragments", "sccp.msg.fragment.multiple_tails", - FT_BOOLEAN, BASE_NONE, NULL, 0x0, NULL, HFILL } + { "Message has multiple tail fragments", "sccp.msg.fragment.multiple_tails", + FT_BOOLEAN, BASE_NONE, NULL, 0x0, + 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, 0x0, NULL, HFILL } + { "Message fragment too long", "sccp.msg.fragment.too_long_fragment", + FT_BOOLEAN, BASE_NONE, NULL, 0x0, + NULL, HFILL } }, {&hf_sccp_xudt_msg_fragment_error, - {"Message defragmentation error", "sccp.msg.fragment.error", - FT_FRAMENUM, BASE_NONE, NULL, 0x00, NULL, HFILL } + { "Message defragmentation error", "sccp.msg.fragment.error", + FT_FRAMENUM, BASE_NONE, NULL, 0x00, + NULL, HFILL } }, {&hf_sccp_xudt_msg_fragment_count, - {"Message fragment count", "sccp.msg.fragment.count", - FT_UINT32, BASE_DEC, NULL, 0x00, NULL, HFILL } + { "Message fragment count", "sccp.msg.fragment.count", + FT_UINT32, BASE_DEC, NULL, 0x00, + NULL, HFILL } }, {&hf_sccp_xudt_msg_reassembled_in, - {"Reassembled in", "sccp.msg.reassembled.in", - FT_FRAMENUM, BASE_NONE, NULL, 0x00, NULL, HFILL } + { "Reassembled in", "sccp.msg.reassembled.in", + FT_FRAMENUM, BASE_NONE, NULL, 0x00, + NULL, HFILL } }, {&hf_sccp_xudt_msg_reassembled_length, - {"Reassembled SCCP length", "sccp.msg.reassembled.length", - FT_UINT32, BASE_DEC, NULL, 0x00, NULL, HFILL } + { "Reassembled SCCP length", "sccp.msg.reassembled.length", + FT_UINT32, BASE_DEC, NULL, 0x00, + NULL, HFILL } }, { &hf_sccp_assoc_id, { "Association ID", "sccp.assoc.id", - FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL}}, + FT_UINT32, BASE_DEC, NULL, 0x0, + NULL, HFILL} + }, {&hf_sccp_assoc_msg, - {"Message in frame", "sccp.assoc.msg", - FT_FRAMENUM, BASE_NONE, NULL, 0x00, NULL, HFILL } + { "Message in frame", "sccp.assoc.msg", + FT_FRAMENUM, BASE_NONE, NULL, 0x00, + NULL, HFILL } }, - }; /* Setup protocol subtree array */ @@ -3876,23 +3974,23 @@ proto_register_sccp(void) static uat_field_t users_flds[] = { - UAT_FLD_DEC(sccp_users, ni, "Network Indicator", "Network Indicator"), - UAT_FLD_RANGE(sccp_users, called_pc, "Called DPCs", 0xFFFFFF, "DPCs for which this protocol is to be used"), - UAT_FLD_RANGE(sccp_users, called_ssn, "Called SSNs", 255, "Called SSNs for which this protocol is to be used"), - UAT_FLD_VS(sccp_users, user, "User protocol", sccp_users_vals, "The User Protocol"), - UAT_END_FIELDS + UAT_FLD_DEC(sccp_users, ni, "Network Indicator", "Network Indicator"), + UAT_FLD_RANGE(sccp_users, called_pc, "Called DPCs", 0xFFFFFF, "DPCs for which this protocol is to be used"), + UAT_FLD_RANGE(sccp_users, called_ssn, "Called SSNs", 255, "Called SSNs for which this protocol is to be used"), + UAT_FLD_VS(sccp_users, user, "User protocol", sccp_users_vals, "The User Protocol"), + UAT_END_FIELDS }; - uat_t* users_uat = uat_new("SCCP Users Table", sizeof(sccp_user_t), - "sccp_users", TRUE, (void*) &sccp_users, - &num_sccp_users, UAT_CAT_PORTS, "ChSccpUsers", - sccp_users_copy_cb, sccp_users_update_cb, - sccp_users_free_cb, NULL, users_flds ); + uat_t *users_uat = uat_new("SCCP Users Table", sizeof(sccp_user_t), + "sccp_users", TRUE, (void*) &sccp_users, + &num_sccp_users, UAT_CAT_PORTS, "ChSccpUsers", + sccp_users_copy_cb, sccp_users_update_cb, + sccp_users_free_cb, NULL, users_flds ); - /* Register the protocol name and description */ + /* Register the protocol name and description */ proto_sccp = proto_register_protocol("Signalling Connection Control Part", - "SCCP", "sccp"); + "SCCP", "sccp"); register_dissector("sccp", dissect_sccp, proto_sccp); @@ -3908,42 +4006,43 @@ proto_register_sccp(void) sccp_module = prefs_register_protocol(proto_sccp, proto_reg_handoff_sccp); prefs_register_uint_preference(sccp_module, "source_pc", - "Source PC (in hex)", - "The source point code (usually MSC) (to determine whether message is uplink or downlink)", - 16, &sccp_source_pc_global); + "Source PC (in hex)", + "The source point code (usually MSC) (to determine whether message is uplink or downlink)", + 16, &sccp_source_pc_global); prefs_register_bool_preference(sccp_module, "show_length", "Show length", - "Show parameter length in the protocol tree", - &sccp_show_length); + "Show parameter length in the protocol tree", + &sccp_show_length); prefs_register_bool_preference(sccp_module, "defragment_xudt", - "Reassemble XUDT messages", - "Whether XUDT messages should be reassembled", - &sccp_xudt_desegment); + "Reassemble XUDT messages", + "Whether XUDT messages should be reassembled", + &sccp_xudt_desegment); prefs_register_bool_preference(sccp_module, "trace_sccp", - "Trace Associations", - "Whether to keep information about messages and their associations", - &trace_sccp); + "Trace Associations", + "Whether to keep information about messages and their associations", + &trace_sccp); prefs_register_bool_preference(sccp_module, "show_more_info", - "Show key parameters in Info Column", - "Show SLR, DLR, and CAUSE Parameters in the Information Column of the Summary", - &show_key_params); + "Show key parameters in Info Column", + "Show SLR, DLR, and CAUSE Parameters in the Information Column of the Summary", + &show_key_params); prefs_register_uat_preference(sccp_module, "users_table", "Users Table", - "A table that enumerates user protocols to be used against specific PCs and SSNs", - users_uat); + "A table that enumerates user protocols to be used against specific PCs and SSNs", + users_uat); prefs_register_bool_preference(sccp_module, "set_addresses", "Set source and destination GT addresses", - "Set the source and destination addresses to the GT digits (if RI=GT)." - " This may affect TCAP's ability to recognize which messages belong to which TCAP session.", &set_addresses); + "Set the source and destination addresses to the GT digits (if RI=GT)." + " This may affect TCAP's ability to recognize which messages belong to which TCAP session.", + &set_addresses); prefs_register_string_preference(sccp_module, "default_payload", "Default Payload", - "The protocol which should be used to dissect the payload if nothing else has claimed it", - &default_payload); + "The protocol which should be used to dissect the payload if nothing else has claimed it", + &default_payload); register_init_routine(&init_sccp); @@ -3958,7 +4057,7 @@ proto_reg_handoff_sccp(void) { dissector_handle_t sccp_handle; - static gboolean initialised=FALSE; + static gboolean initialised = FALSE; if (!initialised) { sccp_handle = find_dissector("sccp"); @@ -3967,13 +4066,13 @@ proto_reg_handoff_sccp(void) dissector_add_uint("mtp3.service_indicator", MTP_SI_SCCP, sccp_handle); dissector_add_string("tali.opcode", "sccp", sccp_handle); - data_handle = find_dissector("data"); - tcap_handle = find_dissector("tcap"); - ranap_handle = find_dissector("ranap"); - bssap_handle = find_dissector("bssap"); + data_handle = find_dissector("data"); + 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"); + camel_handle = find_dissector("camel"); + inap_handle = find_dissector("inap"); initialised = TRUE; } |