/* packet-cast.c * * Dissector for the CAST Client Control Protocol * (The "D-Channel"-Protocol for Cisco Systems' IP-Phones) * * SPDX-License-Identifier: GPL-2.0-or-later */ /* This implementation is based on a draft version of the 3.0 * specification */ #include "config.h" #include #include #include #include "packet-tcp.h" #define TCP_PORT_CAST 4224 /* Not IANA registered */ void proto_register_cast(void); void proto_reg_handoff_cast(void); static dissector_handle_t cast_handle; /* I will probably need this again when I change things * to function pointers, but let me use the existing * infrastructure for now * * typedef struct { * uint32_t id; * char *name; * } message_id_t; */ static const value_string message_id[] = { {0x0000, "KeepAliveMessage"}, {0x0001, "KeepAliveVersionMessage"}, {0x0002, "KeepAliveVersionACKMessage"}, {0x0003, "UpdateCapabilitiesMessage"}, {0x0004, "EmptyCapabilitiesMessage"}, {0x0005, "OpenMultiMediaReceiveChannelMessage"}, {0x0006, "OpenMultiMediaReceiveChannelACKMessage"}, {0x0007, "CloseMultiMediaReceiveChannelMessage"}, {0x0008, "StartMultiMediaTransmissionMessage"}, {0x0009, "StopMultiMediaTransmissionMessage"}, {0x000A, "MiscellaneousCommandMessage"}, {0x000B, "FlowControlCommandMessage"}, {0x000C, "ClearConferenceMessage"}, {0x000D, "CallStateMessage"}, {0x000E, "RequestCallStateMessage"}, {0x000F, "RequestAllCallStatesMessage"}, {0x0010, "CallInfoMessage"}, {0x0011, "RequestCallInfoMessage"}, {0x0012, "CallFocusMessage"}, {0x0013, "MakeCallMessage"}, {0x0014, "HangUpMessage"}, {0x0015, "AnswerMessage"}, {0x0040, "KeepAliveACKMessage"}, {0x0041, "StreamStartMessage"}, {0x0042, "StreamStopMessage"}, {0x0043, "MuteStartMessage"}, {0x0044, "MuteStopMessage"}, {0x0045, "SpeakerStartMessage"}, {0x0046, "SpeakerStopMessage"}, {0x0047, "StreamStartMessageWithCodec"}, {0x0050, "VIEODiscoveryprotocol"}, {0x0051, "VIEOControlprotocol"}, {0x0060, "T120protocol"}, {0x0061, "T121protocol"}, {0x0062, "T122protocol"}, {0x0070, "IMSessionDiscoveryprotocol"}, {0x0071, "IMSessionControlprotocol"}, {0x0074, "SlidesDiscoveryprotocol"}, {0x0075, "SlidesControlprotocol"}, {0x0080, "CastTunnelMessage"}, {0x0090, "RemoteRequestMessage"}, {0x0091, "RemoteResponseMessage"}, {0x00A0, "CollabDiscoveryprotocol"}, {0x00A1, "CollabControlprotocol"}, {0x00A4, "FECCDiscoveryprotocol"}, {0x00A5, "FECCControlprotocol"}, {0x00B0, "ClockSyncprotocol"}, {0x00B1, "StreamSyncprotocol"}, {0x00B4, "MediaDiscoveryprotocol"}, {0x00B5, "MediaControlprotocol"}, {0x00C0, "SessionDiscoveryprotocol"}, {0x00C1, "SessionControlprotocol"}, {0x00C4, "ConferenceDiscoveryprotocol"}, {0x00C5, "Conferenceprotocol"}, {0x00CC, "SCCPCallControlProxyprotocol"}, {0x00D0, "CallDiscoveryprotocol"}, {0x00D1, "CallControlprotocol"}, {0 , NULL} /* terminator */ }; static const value_string audioCodecTypes[] = { {1 , "G711/G729"}, {2 , "GSM"}, {3 , "G723"}, {4 , "G722"}, {5 , "WideBand"}, { 0 , NULL} }; static const value_string orcStatus[] = { {0 , "orcOk"}, {1 , "orcError"}, {0 , NULL} }; static const value_string mediaPayloads[] = { { 1 , "Non-standard codec"}, { 2 , "G.711 A-law 64k"}, { 3 , "G.711 A-law 56k"}, { 4 , "G.711 u-law 64k"}, { 5 , "G.711 u-law 56k"}, { 6 , "G.722 64k"}, { 7 , "G.722 56k"}, { 8 , "G.722 48k"}, { 9 , "G.723.1"}, { 10 , "G.728"}, { 11 , "G.729"}, { 12 , "G.729 Annex A"}, { 13 , "IS11172 AudioCap"}, /* IS11172 is an ISO MPEG standard */ { 14 , "IS13818 AudioCap"}, /* IS13818 is an ISO MPEG standard */ { 15 , "G.729 Annex B"}, { 16 , "G.729 Annex A+Annex B"}, { 18 , "GSM Full Rate"}, { 19 , "GSM Half Rate"}, { 20 , "GSM Enhanced Full Rate"}, { 25 , "Wideband 256k"}, { 32 , "Data 64k"}, { 33 , "Data 56k"}, { 80 , "GSM"}, { 81 , "ActiveVoice"}, { 82 , "G.726 32K"}, { 83 , "G.726 24K"}, { 84 , "G.726 16K"}, { 85 , "G.729B"}, { 86 , "G.729B Low Complexity"}, {100 , "H261"}, {101 , "H263"}, {102 , "Vieo"}, {105 , "T120"}, {106 , "H224"}, {257 , "RFC2833_DynPayload"}, {0 , NULL} }; static const value_string cast_Layouts[] = { { 0 , "NoLayout"}, { 1 , "OneByOne"}, { 2 , "OneByTwo"}, { 3 , "TwoByTwo"}, { 4 , "TwoByTwo3Alt1"}, { 5 , "TwoByTwo3Alt2"}, { 6 , "ThreeByThree"}, { 7 , "ThreeByThree6Alt1"}, { 8 , "ThreeByThree6Alt2"}, { 9 , "ThreeByThree4Alt1"}, {10 , "ThreeByThree4Alt2"}, {0 , NULL} }; static const value_string cast_transmitOrReceive[] = { {1 , "Station_Receive_only"}, {2 , "Station_Transmit_only"}, {3 , "Station_Receive_Transmit"}, {0 , NULL} }; static const value_string cast_formatTypes[] = { {1 , "sqcif (128x96)"}, {2 , "qcif (176x144)"}, {3 , "cif (352x288)"}, {4 , "4cif (704x576)"}, {5 , "16cif (1408x1152)"}, {6 , "custom_base"}, {0 , NULL} }; static const value_string cast_echoCancelTypes[] = { {0 , "Media_EchoCancellation_Off"}, {1 , "Media_EchoCancellation_On"}, {0 , NULL} }; static const value_string cast_g723BitRates[] = { {1 , "Media_G723BRate_5_3"}, {2 , "Media_G723BRate_6_4"}, {0 , NULL} }; static const value_string cast_miscCommandType[] = { {0 , "videoFreezePicture"}, {1 , "videoFastUpdatePicture"}, {2 , "videoFastUpdateGOB"}, {3 , "videoFastUpdateMB"}, {4 , "lostPicture"}, {5 , "lostPartialPicture"}, {6 , "recoveryReferencePicture"}, {7 , "temporalSpatialTradeOff"}, {0 , NULL} }; static const value_string cast_callStateTypes[] = { { 0 , "TsIdle"}, { 1 , "TsOffHook"}, { 2 , "TsOnHook"}, { 3 , "TsRingOut"}, { 4 , "TsRingIn"}, { 5 , "TsConnected"}, { 6 , "TsBusy"}, { 7 , "TsCongestion"}, { 8 , "TsHold"}, { 9 , "TsCallWaiting"}, {10 , "TsCallTransfer"}, {11 , "TsCallPark"}, {12 , "TsProceed"}, {13 , "TsCallRemoteMultiline"}, {14 , "TsInvalidNumber"}, {15 , "TsMaxState"}, {0 , NULL} }; /* Defined Call Type */ static const value_string cast_callTypes[] = { {1 , "InBoundCall"}, {2 , "OutBoundCall"}, {3 , "ForwardCall"}, {0 , NULL} }; static const value_string cast_callSecurityStatusTypes[] = { {0 , "CallSecurityStatusUnknown"}, {1 , "CallSecurityStatusNotAuthenticated"}, {2 , "CallSecurityStatusAuthenticated"}, {0 , NULL} }; #define MAX_CUSTOM_PICTURES 6 #define MAX_SERVICE_TYPE 4 #define MAX_LAYOUT_WITH_SAME_SERVICE 5 #define MAX_PICTURE_FORMAT 5 #define MAX_REFERENCE_PICTURE 4 #define MAX_LEVEL_PREFERENCE 4 #define StationMaxVideoCapabilities 10 #define StationMaxDataCapabilities 5 #define StationMaxNameSize 40 /* max size of calling party's name */ #define StationMaxDirnumSize 24 /* max size of calling or called party dirnum */ /* Initialize the protocol and registered fields */ static int proto_cast; static int hf_cast_data_length; static int hf_cast_reserved; static int hf_cast_messageid; static int hf_cast_version; static int hf_cast_ORCStatus; static int hf_cast_ipAddress; static int hf_cast_portNumber; static int hf_cast_passThruPartyID; static int hf_cast_callIdentifier; static int hf_cast_conferenceID; static int hf_cast_payloadType; static int hf_cast_lineInstance; static int hf_cast_payloadCapability; static int hf_cast_isConferenceCreator; static int hf_cast_payload_rfc_number; static int hf_cast_videoCapCount; static int hf_cast_dataCapCount; static int hf_cast_RTPPayloadFormat; static int hf_cast_customPictureFormatCount; static int hf_cast_pictureWidth; static int hf_cast_pictureHeight; static int hf_cast_pixelAspectRatio; static int hf_cast_clockConversionCode; static int hf_cast_clockDivisor; static int hf_cast_activeStreamsOnRegistration; static int hf_cast_maxBW; static int hf_cast_serviceResourceCount; static int hf_cast_layoutCount; static int hf_cast_layout; static int hf_cast_maxConferences; static int hf_cast_activeConferenceOnRegistration; static int hf_cast_transmitOrReceive; static int hf_cast_levelPreferenceCount; static int hf_cast_transmitPreference; static int hf_cast_format; static int hf_cast_maxBitRate; static int hf_cast_minBitRate; static int hf_cast_MPI; static int hf_cast_serviceNumber; static int hf_cast_temporalSpatialTradeOffCapability; static int hf_cast_stillImageTransmission; static int hf_cast_h263_capability_bitfield; static int hf_cast_annexNandWFutureUse; static int hf_cast_modelNumber; static int hf_cast_bandwidth; static int hf_cast_protocolDependentData; static int hf_cast_DSCPValue; static int hf_cast_serviceNum; /* static int hf_cast_precedenceValue; */ static int hf_cast_maxStreams; static int hf_cast_millisecondPacketSize; static int hf_cast_echoCancelType; static int hf_cast_g723BitRate; static int hf_cast_bitRate; static int hf_cast_pictureFormatCount; static int hf_cast_confServiceNum; static int hf_cast_miscCommandType; static int hf_cast_temporalSpatialTradeOff; static int hf_cast_firstGOB; static int hf_cast_numberOfGOBs; static int hf_cast_firstMB; static int hf_cast_numberOfMBs; static int hf_cast_pictureNumber; static int hf_cast_longTermPictureIndex; static int hf_cast_recoveryReferencePictureCount; static int hf_cast_calledParty; static int hf_cast_privacy; static int hf_cast_precedenceLv; static int hf_cast_precedenceDm; static int hf_cast_callState; static int hf_cast_callingPartyName; static int hf_cast_callingParty; static int hf_cast_calledPartyName; static int hf_cast_callType; static int hf_cast_originalCalledPartyName; static int hf_cast_originalCalledParty; static int hf_cast_lastRedirectingPartyName; static int hf_cast_lastRedirectingParty; static int hf_cast_cgpnVoiceMailbox; static int hf_cast_cdpnVoiceMailbox; static int hf_cast_originalCdpnVoiceMailbox; static int hf_cast_lastRedirectingVoiceMailbox; static int hf_cast_originalCdpnRedirectReason; static int hf_cast_lastRedirectingReason; static int hf_cast_callInstance; static int hf_cast_callSecurityStatus; static int hf_cast_partyPIRestrictionBits_CallingPartyName; static int hf_cast_partyPIRestrictionBits_CallingPartyNumber; static int hf_cast_partyPIRestrictionBits_CalledPartyName; static int hf_cast_partyPIRestrictionBits_CalledPartyNumber; static int hf_cast_partyPIRestrictionBits_OriginalCalledPartyName; static int hf_cast_partyPIRestrictionBits_OriginalCalledPartyNumber; static int hf_cast_partyPIRestrictionBits_LastRedirectPartyName; static int hf_cast_partyPIRestrictionBits_LastRedirectPartyNumber; static int hf_cast_directoryNumber; static int hf_cast_requestorIpAddress; static int hf_cast_stationIpAddress; static int hf_cast_stationFriendlyName; static int hf_cast_stationGUID; static int hf_cast_audio; /* Initialize the subtree pointers */ static int ett_cast; static int ett_cast_tree; /* desegmentation of SCCP */ static bool cast_desegment = true; /* Dissect a single CAST PDU */ static int dissect_cast_pdu(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_) { int offset = 0; /* Header fields */ uint32_t hdr_data_length; uint32_t hdr_marker; uint32_t data_messageid; const char *messageid_str; /* uint32_t data_size; */ unsigned i = 0; unsigned t = 0; int count; int val; /* Set up structures we will need to add the protocol subtree and manage it */ proto_item *ti; proto_tree *cast_tree = NULL; proto_tree *cast_sub_tree; proto_tree *cast_sub_tree_sav; proto_tree *cast_sub_tree_sav_sav; hdr_data_length = tvb_get_letohl(tvb, offset); hdr_marker = tvb_get_letohl(tvb, offset+4); data_messageid = tvb_get_letohl(tvb, offset+8); /* In the interest of speed, if "tree" is NULL, don't do any work not * necessary to generate protocol tree items. */ if (tree) { ti = proto_tree_add_item(tree, proto_cast, tvb, offset, hdr_data_length+8, ENC_NA); cast_tree = proto_item_add_subtree(ti, ett_cast); proto_tree_add_uint(cast_tree, hf_cast_data_length, tvb, offset, 4, hdr_data_length); proto_tree_add_uint(cast_tree, hf_cast_reserved, tvb, offset+4, 4, hdr_marker); } messageid_str = val_to_str(data_messageid, message_id, "0x%08X (Unknown)"); col_add_str(pinfo->cinfo, COL_INFO, messageid_str); if (tree) { proto_tree_add_uint(cast_tree, hf_cast_messageid, tvb,offset+8, 4, data_messageid ); } if (tree) { switch(data_messageid) { case 0x0 : /* keepAlive */ /* no data in message */ break; case 0x1 : /* KeepAliveVersion */ proto_tree_add_item(cast_tree, hf_cast_version, tvb, offset+12, 4, ENC_LITTLE_ENDIAN); break; case 0x2 : /* KeepAliveVersionAck */ proto_tree_add_item(cast_tree, hf_cast_version, tvb, offset+12, 4, ENC_LITTLE_ENDIAN); break; case 0x3 : /* UpdateCapabilities */ /* to do - this message is very large and will span multiple packets, it would be nice to someday */ /* find out a way to join the next packet and get the complete message to decode */ proto_tree_add_item(cast_tree, hf_cast_videoCapCount, tvb, offset+12, 4, ENC_LITTLE_ENDIAN); proto_tree_add_item(cast_tree, hf_cast_dataCapCount, tvb, offset+16, 4, ENC_LITTLE_ENDIAN); proto_tree_add_item(cast_tree, hf_cast_RTPPayloadFormat, tvb, offset+20, 4, ENC_LITTLE_ENDIAN); proto_tree_add_item(cast_tree, hf_cast_customPictureFormatCount, tvb, offset+24, 4, ENC_LITTLE_ENDIAN); count = offset+28; /* total of 120 bytes */ for ( i = 0; i < MAX_CUSTOM_PICTURES; i++ ) { cast_sub_tree = proto_tree_add_subtree_format(cast_tree, tvb, offset, 20, ett_cast_tree, NULL, "customPictureFormat[%d]", i); proto_tree_add_item(cast_sub_tree, hf_cast_pictureWidth, tvb, count, 4, ENC_LITTLE_ENDIAN); count+= 4; proto_tree_add_item(cast_sub_tree, hf_cast_pictureHeight, tvb, count, 4, ENC_LITTLE_ENDIAN); count+= 4; proto_tree_add_item(cast_sub_tree, hf_cast_pixelAspectRatio, tvb, count, 4, ENC_LITTLE_ENDIAN); count+= 4; proto_tree_add_item(cast_sub_tree, hf_cast_clockConversionCode, tvb, count, 4, ENC_LITTLE_ENDIAN); count+= 4; proto_tree_add_item(cast_sub_tree, hf_cast_clockDivisor, tvb, count, 4, ENC_LITTLE_ENDIAN); count+= 4; } cast_sub_tree = proto_tree_add_subtree(cast_tree, tvb, offset, 8, ett_cast_tree, NULL, "confResources"); proto_tree_add_item(cast_sub_tree, hf_cast_activeStreamsOnRegistration, tvb, count, 4, ENC_LITTLE_ENDIAN); count+= 4; proto_tree_add_item(cast_sub_tree, hf_cast_maxBW, tvb, count, 4, ENC_LITTLE_ENDIAN); count+= 4; proto_tree_add_item(cast_sub_tree, hf_cast_serviceResourceCount, tvb, count, 4, ENC_LITTLE_ENDIAN); count+= 4; cast_sub_tree_sav = cast_sub_tree; /* total of 160 bytes */ for ( i = 0; i < MAX_SERVICE_TYPE; i++ ) { cast_sub_tree = proto_tree_add_subtree_format(cast_sub_tree_sav, tvb, offset, 20, ett_cast_tree, NULL, "serviceResource[%d]", i); proto_tree_add_item(cast_sub_tree, hf_cast_layoutCount, tvb, count, 4, ENC_LITTLE_ENDIAN); count+= 4; cast_sub_tree_sav_sav = cast_sub_tree_sav; for ( t = 0; t < MAX_LAYOUT_WITH_SAME_SERVICE; t++ ) { cast_sub_tree = proto_tree_add_subtree_format(cast_sub_tree_sav, tvb, offset, 20, ett_cast_tree, NULL, "layouts[%d]", t); proto_tree_add_item(cast_sub_tree, hf_cast_layout, tvb, count, 4, ENC_LITTLE_ENDIAN); count+= 4; } cast_sub_tree = cast_sub_tree_sav_sav; proto_tree_add_item(cast_sub_tree, hf_cast_serviceNum, tvb, count, 4, ENC_LITTLE_ENDIAN); count+= 4; proto_tree_add_item(cast_sub_tree, hf_cast_maxStreams, tvb, count, 4, ENC_LITTLE_ENDIAN); count+= 4; proto_tree_add_item(cast_sub_tree, hf_cast_maxConferences, tvb, count, 4, ENC_LITTLE_ENDIAN); count+= 4; proto_tree_add_item(cast_sub_tree, hf_cast_activeConferenceOnRegistration, tvb, count, 4, ENC_LITTLE_ENDIAN); count+= 4; } /* total of 176 bytes */ for ( i = 0; i < StationMaxVideoCapabilities; i++ ) { cast_sub_tree = proto_tree_add_subtree_format(cast_tree, tvb, offset, 20, ett_cast_tree, NULL, "vidCaps[%d]", i); proto_tree_add_item(cast_sub_tree, hf_cast_payloadCapability, tvb, count, 4, ENC_LITTLE_ENDIAN); count+= 4; proto_tree_add_item(cast_sub_tree, hf_cast_transmitOrReceive, tvb, count, 4, ENC_LITTLE_ENDIAN); count+= 4; proto_tree_add_item(cast_sub_tree, hf_cast_levelPreferenceCount, tvb, count, 4, ENC_LITTLE_ENDIAN); count+= 4; cast_sub_tree_sav = cast_sub_tree; for ( t = 0; t < MAX_LEVEL_PREFERENCE; t++ ) { cast_sub_tree = proto_tree_add_subtree_format(cast_sub_tree_sav, tvb, offset, 20, ett_cast_tree, NULL, "levelPreference[%d]", t); proto_tree_add_item(cast_sub_tree, hf_cast_transmitPreference, tvb, count, 4, ENC_LITTLE_ENDIAN); count+= 4; proto_tree_add_item(cast_sub_tree, hf_cast_format, tvb, count, 4, ENC_LITTLE_ENDIAN); count+= 4; proto_tree_add_item(cast_sub_tree, hf_cast_maxBitRate, tvb, count, 4, ENC_LITTLE_ENDIAN); count+= 4; proto_tree_add_item(cast_sub_tree, hf_cast_minBitRate, tvb, count, 4, ENC_LITTLE_ENDIAN); count+= 4; proto_tree_add_item(cast_sub_tree, hf_cast_MPI, tvb, count, 4, ENC_LITTLE_ENDIAN); count+= 4; proto_tree_add_item(cast_sub_tree, hf_cast_serviceNumber, tvb, count, 4, ENC_LITTLE_ENDIAN); count+= 4; } /* H.261 */ cast_sub_tree = proto_tree_add_subtree(cast_sub_tree_sav, tvb, offset, 8, ett_cast_tree, NULL, "h261VideoCapability"); proto_tree_add_item(cast_sub_tree, hf_cast_temporalSpatialTradeOffCapability, tvb, count, 4, ENC_LITTLE_ENDIAN); proto_tree_add_item(cast_sub_tree, hf_cast_stillImageTransmission, tvb, count+4, 4, ENC_LITTLE_ENDIAN); /* H.263 */ cast_sub_tree = proto_tree_add_subtree(cast_sub_tree_sav, tvb, offset, 8, ett_cast_tree, NULL, "h263VideoCapability"); proto_tree_add_item(cast_sub_tree, hf_cast_h263_capability_bitfield, tvb, count, 4, ENC_LITTLE_ENDIAN); proto_tree_add_item(cast_sub_tree, hf_cast_annexNandWFutureUse, tvb, count+4, 4, ENC_LITTLE_ENDIAN); /* Vieo */ cast_sub_tree = proto_tree_add_subtree(cast_sub_tree_sav, tvb, offset, 8, ett_cast_tree, NULL, "vieoVideoCapability"); proto_tree_add_item(cast_sub_tree, hf_cast_modelNumber, tvb, count, 4, ENC_LITTLE_ENDIAN); count+= 4; proto_tree_add_item(cast_sub_tree, hf_cast_bandwidth, tvb, count, 4, ENC_LITTLE_ENDIAN); count+= 4; } /* total 80 bytes */ for ( i = 0; i < StationMaxDataCapabilities; i++ ) { cast_sub_tree = proto_tree_add_subtree_format(cast_tree, tvb, offset, 20, ett_cast_tree, NULL, "dataCaps[%d]", i); proto_tree_add_item(cast_sub_tree, hf_cast_payloadCapability, tvb, count, 4, ENC_LITTLE_ENDIAN); count+= 4; proto_tree_add_item(cast_sub_tree, hf_cast_transmitOrReceive, tvb, count, 4, ENC_LITTLE_ENDIAN); count+= 4; proto_tree_add_item(cast_sub_tree, hf_cast_protocolDependentData, tvb, count, 4, ENC_LITTLE_ENDIAN); count+= 4; proto_tree_add_item(cast_sub_tree, hf_cast_maxBitRate, tvb, count, 4, ENC_LITTLE_ENDIAN); count+= 4; } break; case 0x4 : /* */ break; case 0x5 : /* OpenMultiMediaReceiveChannel */ proto_tree_add_item(cast_tree, hf_cast_conferenceID, tvb, offset+12, 4, ENC_LITTLE_ENDIAN); proto_tree_add_item(cast_tree, hf_cast_passThruPartyID, tvb, offset+16, 4, ENC_LITTLE_ENDIAN); proto_tree_add_item(cast_tree, hf_cast_payloadCapability, tvb, offset+20, 4, ENC_LITTLE_ENDIAN); proto_tree_add_item(cast_tree, hf_cast_lineInstance, tvb, offset+24, 4, ENC_LITTLE_ENDIAN); proto_tree_add_item(cast_tree, hf_cast_callIdentifier, tvb, offset+28, 4, ENC_LITTLE_ENDIAN); proto_tree_add_item(cast_tree, hf_cast_payload_rfc_number, tvb, offset+32, 4, ENC_LITTLE_ENDIAN); proto_tree_add_item(cast_tree, hf_cast_payloadType, tvb, offset+36, 4, ENC_LITTLE_ENDIAN); proto_tree_add_item(cast_tree, hf_cast_isConferenceCreator, tvb, offset+40, 4, ENC_LITTLE_ENDIAN); /* add audio part of union */ cast_sub_tree = proto_tree_add_subtree(cast_tree, tvb, offset, 12, ett_cast_tree, NULL, "audioParameters"); proto_tree_add_item(cast_sub_tree, hf_cast_millisecondPacketSize, tvb, offset+44, 4, ENC_LITTLE_ENDIAN); proto_tree_add_item(cast_sub_tree, hf_cast_echoCancelType, tvb, offset+48, 4, ENC_LITTLE_ENDIAN); proto_tree_add_item(cast_sub_tree, hf_cast_g723BitRate, tvb, offset+52, 4, ENC_LITTLE_ENDIAN); /* add video part of union */ cast_sub_tree = proto_tree_add_subtree(cast_tree, tvb, offset, 30, ett_cast_tree, NULL, "videoParameters"); proto_tree_add_item(cast_sub_tree, hf_cast_bitRate, tvb, offset+44, 4, ENC_LITTLE_ENDIAN); proto_tree_add_item(cast_sub_tree, hf_cast_pictureFormatCount, tvb, offset+48, 4, ENC_LITTLE_ENDIAN); cast_sub_tree_sav = cast_sub_tree; count = offset+52; for ( i = 0; i < MAX_PICTURE_FORMAT; i++ ) { cast_sub_tree = proto_tree_add_subtree_format(cast_sub_tree_sav, tvb, offset, 8 * MAX_PICTURE_FORMAT, ett_cast_tree, NULL, "pictureFormat[%d]", i); proto_tree_add_item(cast_sub_tree, hf_cast_format, tvb, count, 4, ENC_LITTLE_ENDIAN); count += 4; proto_tree_add_item(cast_sub_tree, hf_cast_MPI, tvb, count, 4, ENC_LITTLE_ENDIAN); count += 4; } cast_sub_tree = cast_sub_tree_sav; proto_tree_add_item(cast_sub_tree, hf_cast_confServiceNum, tvb, count, 4, ENC_LITTLE_ENDIAN); count += 4; /* add H261 part of union */ cast_sub_tree = proto_tree_add_subtree(cast_sub_tree_sav, tvb, offset, 8, ett_cast_tree, NULL, "h261VideoCapability"); proto_tree_add_item(cast_sub_tree, hf_cast_temporalSpatialTradeOffCapability, tvb, count, 4, ENC_LITTLE_ENDIAN); proto_tree_add_item(cast_sub_tree, hf_cast_stillImageTransmission, tvb, count+4, 4, ENC_LITTLE_ENDIAN); /* add H263 part of union */ cast_sub_tree = proto_tree_add_subtree(cast_sub_tree_sav, tvb, offset, 8, ett_cast_tree, NULL, "h263VideoCapability"); proto_tree_add_item(cast_sub_tree, hf_cast_h263_capability_bitfield, tvb, count, 4, ENC_LITTLE_ENDIAN); proto_tree_add_item(cast_sub_tree, hf_cast_annexNandWFutureUse, tvb, count+4, 4, ENC_LITTLE_ENDIAN); /* add Vieo part of union */ cast_sub_tree = proto_tree_add_subtree(cast_sub_tree_sav, tvb, offset, 8, ett_cast_tree, NULL, "vieoVideoCapability"); proto_tree_add_item(cast_sub_tree, hf_cast_modelNumber, tvb, count, 4, ENC_LITTLE_ENDIAN); count += 4; proto_tree_add_item(cast_sub_tree, hf_cast_bandwidth, tvb, count, 4, ENC_LITTLE_ENDIAN); /* add data part of union */ cast_sub_tree = proto_tree_add_subtree(cast_tree, tvb, offset, 8, ett_cast_tree, NULL, "dataParameters"); proto_tree_add_item(cast_sub_tree, hf_cast_protocolDependentData, tvb, offset+44, 4, ENC_LITTLE_ENDIAN); proto_tree_add_item(cast_sub_tree, hf_cast_maxBitRate, tvb, offset+48, 4, ENC_LITTLE_ENDIAN); break; case 0x6 : /* OpenMultiMediaReceiveChannelACK */ proto_tree_add_item(cast_tree, hf_cast_ORCStatus, tvb, offset+12, 4, ENC_LITTLE_ENDIAN); proto_tree_add_item(cast_tree, hf_cast_ipAddress, tvb, offset+16, 4, ENC_LITTLE_ENDIAN); proto_tree_add_item(cast_tree, hf_cast_portNumber, tvb, offset+20, 4, ENC_LITTLE_ENDIAN); proto_tree_add_item(cast_tree, hf_cast_passThruPartyID, tvb, offset+24, 4, ENC_LITTLE_ENDIAN); proto_tree_add_item(cast_tree, hf_cast_callIdentifier, tvb, offset+28, 4, ENC_LITTLE_ENDIAN); break; case 0x7 : /* CloseMultiMediaReceiveChannel */ proto_tree_add_item(cast_tree, hf_cast_conferenceID, tvb, offset+12, 4, ENC_LITTLE_ENDIAN); proto_tree_add_item(cast_tree, hf_cast_passThruPartyID, tvb, offset+16, 4, ENC_LITTLE_ENDIAN); proto_tree_add_item(cast_tree, hf_cast_callIdentifier, tvb, offset+20, 4, ENC_LITTLE_ENDIAN); break; case 0x8 : /* StartMultiMediaTransmission */ proto_tree_add_item(cast_tree, hf_cast_conferenceID, tvb, offset+12, 4, ENC_LITTLE_ENDIAN); proto_tree_add_item(cast_tree, hf_cast_passThruPartyID, tvb, offset+16, 4, ENC_LITTLE_ENDIAN); proto_tree_add_item(cast_tree, hf_cast_payloadCapability, tvb, offset+20, 4, ENC_LITTLE_ENDIAN); proto_tree_add_item(cast_tree, hf_cast_ipAddress, tvb, offset+24, 4, ENC_LITTLE_ENDIAN); proto_tree_add_item(cast_tree, hf_cast_portNumber, tvb, offset+28, 4, ENC_LITTLE_ENDIAN); proto_tree_add_item(cast_tree, hf_cast_callIdentifier, tvb, offset+32, 4, ENC_LITTLE_ENDIAN); proto_tree_add_item(cast_tree, hf_cast_payload_rfc_number, tvb, offset+36, 4, ENC_LITTLE_ENDIAN); proto_tree_add_item(cast_tree, hf_cast_payloadType, tvb, offset+40, 4, ENC_LITTLE_ENDIAN); proto_tree_add_item(cast_tree, hf_cast_DSCPValue, tvb, offset+44, 4, ENC_LITTLE_ENDIAN); /* add video part of union */ cast_sub_tree = proto_tree_add_subtree(cast_tree, tvb, offset, 30, ett_cast_tree, NULL, "videoParameters"); proto_tree_add_item(cast_sub_tree, hf_cast_bitRate, tvb, offset+48, 4, ENC_LITTLE_ENDIAN); proto_tree_add_item(cast_sub_tree, hf_cast_pictureFormatCount, tvb, offset+52, 4, ENC_LITTLE_ENDIAN); cast_sub_tree_sav = cast_sub_tree; count = offset+56; for ( i = 0; i < MAX_PICTURE_FORMAT; i++ ) { cast_sub_tree = proto_tree_add_subtree_format(cast_sub_tree_sav, tvb, offset, 8 * MAX_PICTURE_FORMAT, ett_cast_tree, NULL, "pictureFormat[%d]", i); proto_tree_add_item(cast_sub_tree, hf_cast_format, tvb, count, 4, ENC_LITTLE_ENDIAN); count += 4; proto_tree_add_item(cast_sub_tree, hf_cast_MPI, tvb, count, 4, ENC_LITTLE_ENDIAN); count += 4; } cast_sub_tree = cast_sub_tree_sav; proto_tree_add_item(cast_sub_tree, hf_cast_confServiceNum, tvb, count, 4, ENC_LITTLE_ENDIAN); count += 4; val = count; /* add H261 part of union */ cast_sub_tree = proto_tree_add_subtree(cast_sub_tree_sav, tvb, offset, 8, ett_cast_tree, NULL, "h261VideoCapability"); proto_tree_add_item(cast_sub_tree, hf_cast_temporalSpatialTradeOffCapability, tvb, count, 4, ENC_LITTLE_ENDIAN); count += 4; proto_tree_add_item(cast_sub_tree, hf_cast_stillImageTransmission, tvb, count, 4, ENC_LITTLE_ENDIAN); /* add H263 part of union */ count = val; cast_sub_tree = proto_tree_add_subtree(cast_sub_tree_sav, tvb, offset, 8, ett_cast_tree, NULL, "h263VideoCapability"); proto_tree_add_item(cast_sub_tree, hf_cast_h263_capability_bitfield, tvb, count, 4, ENC_LITTLE_ENDIAN); count += 4; proto_tree_add_item(cast_sub_tree, hf_cast_annexNandWFutureUse, tvb, count, 4, ENC_LITTLE_ENDIAN); /* add Vieo part of union */ count = val; cast_sub_tree = proto_tree_add_subtree(cast_sub_tree_sav, tvb, offset, 8, ett_cast_tree, NULL, "vieoVideoCapability"); proto_tree_add_item(cast_sub_tree, hf_cast_modelNumber, tvb, count, 4, ENC_LITTLE_ENDIAN); count += 4; proto_tree_add_item(cast_sub_tree, hf_cast_bandwidth, tvb, count, 4, ENC_LITTLE_ENDIAN); /* add data part of union */ cast_sub_tree = proto_tree_add_subtree(cast_tree, tvb, offset, 8, ett_cast_tree, NULL, "dataParameters"); proto_tree_add_item(cast_sub_tree, hf_cast_protocolDependentData, tvb, offset+48, 4, ENC_LITTLE_ENDIAN); proto_tree_add_item(cast_sub_tree, hf_cast_maxBitRate, tvb, offset+52, 4, ENC_LITTLE_ENDIAN); break; case 0x9 : /* StopMultiMediaTransmission */ proto_tree_add_item(cast_tree, hf_cast_conferenceID, tvb, offset+12, 4, ENC_LITTLE_ENDIAN); proto_tree_add_item(cast_tree, hf_cast_passThruPartyID, tvb, offset+16, 4, ENC_LITTLE_ENDIAN); proto_tree_add_item(cast_tree, hf_cast_callIdentifier, tvb, offset+20, 4, ENC_LITTLE_ENDIAN); break; case 0xA : /* MiscellaneousCommand */ proto_tree_add_item(cast_tree, hf_cast_conferenceID, tvb, offset+12, 4, ENC_LITTLE_ENDIAN); proto_tree_add_item(cast_tree, hf_cast_passThruPartyID, tvb, offset+16, 4, ENC_LITTLE_ENDIAN); proto_tree_add_item(cast_tree, hf_cast_callIdentifier, tvb, offset+20, 4, ENC_LITTLE_ENDIAN); proto_tree_add_item(cast_tree, hf_cast_miscCommandType, tvb, offset+24, 4, ENC_LITTLE_ENDIAN); /* show videoFreezePicture */ /* not sure of format */ /* show videoFastUpdatePicture */ /* not sure of format */ /* show videoFastUpdateGOB */ cast_sub_tree = proto_tree_add_subtree(cast_tree, tvb, offset, 8, ett_cast_tree, NULL, "videoFastUpdateGOB"); proto_tree_add_item(cast_sub_tree, hf_cast_firstGOB, tvb, offset+28, 4, ENC_LITTLE_ENDIAN); proto_tree_add_item(cast_sub_tree, hf_cast_numberOfGOBs, tvb, offset+32, 4, ENC_LITTLE_ENDIAN); /* show videoFastUpdateMB */ cast_sub_tree = proto_tree_add_subtree(cast_tree, tvb, offset, 8, ett_cast_tree, NULL, "videoFastUpdateGOB"); proto_tree_add_item(cast_sub_tree, hf_cast_firstGOB, tvb, offset+28, 4, ENC_LITTLE_ENDIAN); proto_tree_add_item(cast_sub_tree, hf_cast_firstMB, tvb, offset+32, 4, ENC_LITTLE_ENDIAN); proto_tree_add_item(cast_sub_tree, hf_cast_numberOfMBs, tvb, offset+36, 4, ENC_LITTLE_ENDIAN); /* show lostPicture */ cast_sub_tree = proto_tree_add_subtree(cast_tree, tvb, offset, 8, ett_cast_tree, NULL, "lostPicture"); proto_tree_add_item(cast_sub_tree, hf_cast_pictureNumber, tvb, offset+28, 4, ENC_LITTLE_ENDIAN); proto_tree_add_item(cast_sub_tree, hf_cast_longTermPictureIndex, tvb, offset+32, 4, ENC_LITTLE_ENDIAN); /* show lostPartialPicture */ cast_sub_tree = proto_tree_add_subtree(cast_tree, tvb, offset, 8, ett_cast_tree, NULL, "lostPartialPicture"); proto_tree_add_item(cast_sub_tree, hf_cast_pictureNumber, tvb, offset+28, 4, ENC_LITTLE_ENDIAN); proto_tree_add_item(cast_sub_tree, hf_cast_longTermPictureIndex, tvb, offset+32, 4, ENC_LITTLE_ENDIAN); proto_tree_add_item(cast_sub_tree, hf_cast_firstMB, tvb, offset+36, 4, ENC_LITTLE_ENDIAN); proto_tree_add_item(cast_sub_tree, hf_cast_numberOfMBs, tvb, offset+40, 4, ENC_LITTLE_ENDIAN); /* show recoveryReferencePicture */ cast_sub_tree = proto_tree_add_subtree(cast_tree, tvb, offset, 8, ett_cast_tree, NULL, "recoveryReferencePicture"); proto_tree_add_item(cast_sub_tree, hf_cast_recoveryReferencePictureCount, tvb, offset+28, 4, ENC_LITTLE_ENDIAN); cast_sub_tree_sav = cast_sub_tree; for ( i = 0; i < MAX_REFERENCE_PICTURE; i++ ) { cast_sub_tree = proto_tree_add_subtree_format(cast_sub_tree_sav, tvb, offset, 8, ett_cast_tree, NULL, "recoveryReferencePicture[%d]", i); proto_tree_add_item(cast_sub_tree, hf_cast_pictureNumber, tvb, offset+32+(i*8), 4, ENC_LITTLE_ENDIAN); proto_tree_add_item(cast_sub_tree, hf_cast_longTermPictureIndex, tvb, offset+36+(i*8), 4, ENC_LITTLE_ENDIAN); } /* show temporalSpatialTradeOff */ cast_sub_tree = proto_tree_add_subtree(cast_tree, tvb, offset, 4, ett_cast_tree, NULL, "temporalSpatialTradeOff"); proto_tree_add_item(cast_sub_tree, hf_cast_temporalSpatialTradeOff, tvb, offset+28, 4, ENC_LITTLE_ENDIAN); break; case 0xB : /* FlowControlCommand */ proto_tree_add_item(cast_tree, hf_cast_conferenceID, tvb, offset+12, 4, ENC_LITTLE_ENDIAN); proto_tree_add_item(cast_tree, hf_cast_passThruPartyID, tvb, offset+16, 4, ENC_LITTLE_ENDIAN); proto_tree_add_item(cast_tree, hf_cast_callIdentifier, tvb, offset+20, 4, ENC_LITTLE_ENDIAN); proto_tree_add_item(cast_tree, hf_cast_maxBitRate, tvb, offset+24, 4, ENC_LITTLE_ENDIAN); break; case 0xC : /* ClearConference */ proto_tree_add_item(cast_tree, hf_cast_conferenceID, tvb, offset+12, 4, ENC_LITTLE_ENDIAN); proto_tree_add_item(cast_tree, hf_cast_serviceNum, tvb, offset+16, 4, ENC_LITTLE_ENDIAN); break; case 0xD : /* CallState */ proto_tree_add_item(cast_tree, hf_cast_callState, tvb, offset+12, 4, ENC_LITTLE_ENDIAN); proto_tree_add_item(cast_tree, hf_cast_lineInstance, tvb, offset+16, 4, ENC_LITTLE_ENDIAN); proto_tree_add_item(cast_tree, hf_cast_callIdentifier, tvb, offset+20, 4, ENC_LITTLE_ENDIAN); proto_tree_add_item(cast_tree, hf_cast_privacy, tvb, offset+24, 4, ENC_LITTLE_ENDIAN); proto_tree_add_item(cast_tree, hf_cast_precedenceLv, tvb, offset+28, 4, ENC_LITTLE_ENDIAN); proto_tree_add_item(cast_tree, hf_cast_precedenceDm, tvb, offset+32, 4, ENC_LITTLE_ENDIAN); break; case 0xE : /* RequestCallState */ proto_tree_add_item(cast_tree, hf_cast_callIdentifier, tvb, offset+12, 4, ENC_LITTLE_ENDIAN); break; case 0xF : /* RequestAllCallStates */ /* no data in message */ break; case 0x10 : /* CallInfo */ i = offset+12; proto_tree_add_item(cast_tree, hf_cast_callingPartyName, tvb, i, StationMaxNameSize, ENC_ASCII); i += StationMaxNameSize; proto_tree_add_item(cast_tree, hf_cast_callingParty, tvb, i, StationMaxDirnumSize, ENC_ASCII); i += StationMaxDirnumSize; proto_tree_add_item(cast_tree, hf_cast_calledPartyName, tvb, i, StationMaxNameSize, ENC_ASCII); i += StationMaxNameSize; proto_tree_add_item(cast_tree, hf_cast_calledParty, tvb, i, StationMaxDirnumSize, ENC_ASCII); i += StationMaxDirnumSize; proto_tree_add_item(cast_tree, hf_cast_lineInstance, tvb, i, 4, ENC_LITTLE_ENDIAN); i += 4; proto_tree_add_item(cast_tree, hf_cast_callIdentifier, tvb, i, 4, ENC_LITTLE_ENDIAN); i += 4; proto_tree_add_item(cast_tree, hf_cast_callType, tvb, i, 4, ENC_LITTLE_ENDIAN); i += 4; proto_tree_add_item(cast_tree, hf_cast_originalCalledPartyName, tvb, i, StationMaxNameSize, ENC_ASCII); i += StationMaxNameSize; proto_tree_add_item(cast_tree, hf_cast_originalCalledParty, tvb, i, StationMaxDirnumSize, ENC_ASCII); i += StationMaxDirnumSize; proto_tree_add_item(cast_tree, hf_cast_lastRedirectingPartyName, tvb, i, StationMaxNameSize, ENC_ASCII); i += StationMaxNameSize; proto_tree_add_item(cast_tree, hf_cast_lastRedirectingParty, tvb, i, StationMaxDirnumSize, ENC_ASCII); i += StationMaxDirnumSize; proto_tree_add_item(cast_tree, hf_cast_originalCdpnRedirectReason, tvb, i, 4, ENC_LITTLE_ENDIAN); i += 4; proto_tree_add_item(cast_tree, hf_cast_lastRedirectingReason, tvb, i, 4, ENC_LITTLE_ENDIAN); i += 4; proto_tree_add_item(cast_tree, hf_cast_cgpnVoiceMailbox, tvb, i, StationMaxDirnumSize, ENC_ASCII); i += StationMaxDirnumSize; proto_tree_add_item(cast_tree, hf_cast_cdpnVoiceMailbox, tvb, i, StationMaxDirnumSize, ENC_ASCII); i += StationMaxDirnumSize; proto_tree_add_item(cast_tree, hf_cast_originalCdpnVoiceMailbox, tvb, i, StationMaxDirnumSize, ENC_ASCII); i += StationMaxDirnumSize; proto_tree_add_item(cast_tree, hf_cast_lastRedirectingVoiceMailbox, tvb, i, StationMaxDirnumSize, ENC_ASCII); i += StationMaxDirnumSize; proto_tree_add_item(cast_tree, hf_cast_callInstance, tvb, i, 4, ENC_LITTLE_ENDIAN); i += 4; proto_tree_add_item(cast_tree, hf_cast_callSecurityStatus, tvb, i, 4, ENC_LITTLE_ENDIAN); i += 4; cast_sub_tree = proto_tree_add_subtree(cast_tree, tvb, offset, 8, ett_cast_tree, NULL, "partyPIRestrictionBits"); proto_tree_add_item(cast_sub_tree, hf_cast_partyPIRestrictionBits_CallingPartyName, tvb, i, 4, ENC_LITTLE_ENDIAN); proto_tree_add_item(cast_sub_tree, hf_cast_partyPIRestrictionBits_CallingPartyNumber, tvb, i, 4, ENC_LITTLE_ENDIAN); proto_tree_add_item(cast_sub_tree, hf_cast_partyPIRestrictionBits_CalledPartyName, tvb, i, 4, ENC_LITTLE_ENDIAN); proto_tree_add_item(cast_sub_tree, hf_cast_partyPIRestrictionBits_CalledPartyNumber, tvb, i, 4, ENC_LITTLE_ENDIAN); proto_tree_add_item(cast_sub_tree, hf_cast_partyPIRestrictionBits_OriginalCalledPartyName, tvb, i, 4, ENC_LITTLE_ENDIAN); proto_tree_add_item(cast_sub_tree, hf_cast_partyPIRestrictionBits_OriginalCalledPartyNumber, tvb, i, 4, ENC_LITTLE_ENDIAN); proto_tree_add_item(cast_sub_tree, hf_cast_partyPIRestrictionBits_LastRedirectPartyName, tvb, i, 4, ENC_LITTLE_ENDIAN); proto_tree_add_item(cast_sub_tree, hf_cast_partyPIRestrictionBits_LastRedirectPartyNumber, tvb, i, 4, ENC_LITTLE_ENDIAN); break; case 0x11 : /* RequestCallInfo */ proto_tree_add_item(cast_tree, hf_cast_lineInstance, tvb, offset+12, 4, ENC_LITTLE_ENDIAN); break; case 0x12 : /* CallFocus */ proto_tree_add_item(cast_tree, hf_cast_lineInstance, tvb, offset+12, 4, ENC_LITTLE_ENDIAN); proto_tree_add_item(cast_tree, hf_cast_callIdentifier, tvb, offset+16, 4, ENC_LITTLE_ENDIAN); break; case 0x13 : /* MakeCall */ proto_tree_add_item(cast_tree, hf_cast_calledParty, tvb, offset+12, StationMaxDirnumSize, ENC_ASCII); proto_tree_add_item(cast_tree, hf_cast_lineInstance, tvb, offset+16, 4, ENC_LITTLE_ENDIAN); break; case 0x14 : /* HangUp */ proto_tree_add_item(cast_tree, hf_cast_lineInstance, tvb, offset+12, 4, ENC_LITTLE_ENDIAN); break; case 0x15 : /* Answer */ proto_tree_add_item(cast_tree, hf_cast_lineInstance, tvb, offset+12, 4, ENC_LITTLE_ENDIAN); break; case 0x40 : /* keepAliveAck */ /* no data in message */ break; case 0x41 : /* StreamStart */ /* no data in message */ break; case 0x42 : /* StreamStop */ /* no data in message */ break; case 0x43 : /* MuteStart */ /* no data in message */ break; case 0x44 : /* MuteStop */ /* no data in message */ break; case 0x45 : /* SpeakerStart */ /* no data in message */ break; case 0x46 : /* SpeakerStop */ /* no data in message */ break; case 0x47 : /* StreamStartMessageWithCodec */ proto_tree_add_item(cast_tree, hf_cast_audio, tvb, offset+12, 4, ENC_LITTLE_ENDIAN); break; case 0x50 : /* VIEODiscoveryprotocol */ break; case 0x51 : /* VIEOControlprotocol */ break; case 0x60 : /* VeT120protocol */ break; case 0x61 : /* VeT121protocol */ break; case 0x62 : /* VeT122protocol */ break; case 0x70 : /* IMSessionDiscoveryprotocol */ break; case 0x71 : /* IMSessionControlprotocol */ break; case 0x74 : /* SlidesDiscoveryprotocol */ break; case 0x75 : /* SlidesControlprotocol */ break; case 0x80 : /* Tunnel */ break; case 0x90 : /* RemoteInfoRequest */ i = offset+12; proto_tree_add_item(cast_tree, hf_cast_stationFriendlyName, tvb, i, StationMaxNameSize, ENC_ASCII); i += StationMaxNameSize; proto_tree_add_item(cast_tree, hf_cast_stationGUID, tvb, i, StationMaxNameSize, ENC_ASCII); i += StationMaxNameSize; proto_tree_add_item(cast_tree, hf_cast_requestorIpAddress, tvb, i, 4, ENC_LITTLE_ENDIAN); break; case 0x91 : /* RemoteInfoResponse */ i = offset+12; proto_tree_add_item(cast_tree, hf_cast_stationFriendlyName, tvb, i, StationMaxNameSize, ENC_ASCII); i += StationMaxNameSize; proto_tree_add_item(cast_tree, hf_cast_stationGUID, tvb, i, StationMaxNameSize, ENC_ASCII); i += StationMaxNameSize; proto_tree_add_item(cast_tree, hf_cast_stationIpAddress, tvb, i, 4, ENC_LITTLE_ENDIAN); i += 4; proto_tree_add_item(cast_tree, hf_cast_directoryNumber, tvb, i, StationMaxNameSize, ENC_ASCII); break; case 0xA0 : /* CollabDiscoveryprotocol */ break; case 0xA1 : /* CollabControlprotocol */ break; case 0xA4 : /* FECCDiscoveryprotocol */ break; case 0xA5 : /* FECCControlprotocol */ break; case 0xB0 : /* ClockSyncprotocol */ break; case 0xB1 : /* StreamSyncprotocol */ break; case 0xB4 : /* MediaDiscoveryprotocol */ break; case 0xB5 : /* MediaControlprotocol */ break; case 0xC0 : /* SessionDiscoveryprotocol */ break; case 0xC1 : /* SessionControlprotocol */ break; case 0xC4 : /* ConferenceDiscoveryprotocol */ break; case 0xC5 : /* Conferenceprotocol */ break; case 0xCC : /* SCCPCallControlProxyprotocol */ break; case 0xD0 : /* CallDiscoveryprotocol */ break; case 0xD1 : /* CallControlprotocol */ break; default: break; } } return tvb_reported_length(tvb); } /* Get the length of a single CAST PDU */ static unsigned get_cast_pdu_len(packet_info *pinfo _U_, tvbuff_t *tvb, int offset, void *data _U_) { uint32_t hdr_data_length; /* * Get the length of the CAST packet. */ hdr_data_length = tvb_get_letohl(tvb, offset); /* * That length doesn't include the length of the header itself; * add that in. */ return hdr_data_length + 8; } /* Code to actually dissect the packets */ static int dissect_cast(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data) { /* The general structure of a packet: {IP-Header|TCP-Header|n*CAST} * CAST-Packet: {Header(Size, Reserved)|Data(MessageID, Message-Data)} */ /* Header fields */ uint32_t hdr_data_length; uint32_t hdr_marker; /* check, if this is really an SKINNY packet, they start with a length + 0 */ /* get relevant header information */ hdr_data_length = tvb_get_letohl(tvb, 0); hdr_marker = tvb_get_letohl(tvb, 4); /* data_size = MIN(8+hdr_data_length, tvb_reported_length(tvb)) - 0xC; */ if (hdr_data_length < 4 || hdr_marker != 0) { return 0; } /* Make entries in Protocol column and Info column on summary display */ col_set_str(pinfo->cinfo, COL_PROTOCOL, "CAST"); col_set_str(pinfo->cinfo, COL_INFO, "Cast Client Control Protocol"); tcp_dissect_pdus(tvb, pinfo, tree, cast_desegment, 4, get_cast_pdu_len, dissect_cast_pdu, data); return tvb_reported_length(tvb); } /* Register the protocol with Wireshark */ void proto_register_cast(void) { /* Setup list of header fields */ static hf_register_info hf[] = { { &hf_cast_data_length, { "Data Length", "cast.data_length", FT_UINT32, BASE_DEC, NULL, 0x0, "Number of bytes in the data portion.", HFILL } }, { &hf_cast_reserved, { "Marker", "cast.marker", FT_UINT32, BASE_HEX, NULL, 0x0, "Marker value should ne zero.", HFILL } }, /* FIXME: Enable use of message name ??? */ { &hf_cast_messageid, { "Message ID", "cast.messageid", FT_UINT32, BASE_HEX, VALS(message_id), 0x0, "The function requested/done with this message.", HFILL } }, { &hf_cast_version, { "Version", "cast.version", FT_UINT32, BASE_DEC, NULL, 0x0, "The version in the keepalive version messages.", HFILL } }, { &hf_cast_ORCStatus, { "ORCStatus", "cast.ORCStatus", FT_UINT32, BASE_DEC, VALS(orcStatus), 0x0, "The status of the opened receive channel.", HFILL } }, { &hf_cast_ipAddress, { "IP Address", "cast.ipAddress", FT_IPv4, BASE_NONE, NULL, 0x0, NULL, HFILL } }, { &hf_cast_portNumber, { "Port Number", "cast.portNumber", FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL } }, { &hf_cast_passThruPartyID, { "PassThruPartyID", "cast.passThruPartyID", FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL } }, { &hf_cast_callIdentifier, { "Call Identifier", "cast.callIdentifier", FT_UINT32, BASE_DEC, NULL, 0x0, "Call identifier for this call.", HFILL } }, { &hf_cast_conferenceID, { "Conference ID", "cast.conferenceID", FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL } }, { &hf_cast_payloadType, { "PayloadType", "cast.payloadType", FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL } }, { &hf_cast_lineInstance, { "Line Instance", "cast.lineInstance", FT_UINT32, BASE_DEC, NULL, 0x0, "The display call plane associated with this call.", HFILL } }, { &hf_cast_payloadCapability, { "PayloadCapability", "cast.payloadCapability", FT_UINT32, BASE_DEC, VALS(mediaPayloads), 0x0, "The payload capability for this media capability structure.", HFILL } }, { &hf_cast_isConferenceCreator, { "IsConferenceCreator", "cast.isConferenceCreator", FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL } }, { &hf_cast_payload_rfc_number, { "Payload_rfc_number", "cast.payload_rfc_number", FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL } }, { &hf_cast_videoCapCount, { "VideoCapCount", "cast.videoCapCount", FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL } }, { &hf_cast_dataCapCount, { "DataCapCount", "cast.dataCapCount", FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL } }, { &hf_cast_RTPPayloadFormat, { "RTPPayloadFormat", "cast.RTPPayloadFormat", FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL } }, { &hf_cast_customPictureFormatCount, { "CustomPictureFormatCount", "cast.customPictureFormatCount", FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL } }, { &hf_cast_pictureWidth, { "PictureWidth", "cast.pictureWidth", FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL } }, { &hf_cast_pictureHeight, { "PictureHeight", "cast.pictureHeight", FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL } }, { &hf_cast_pixelAspectRatio, { "PixelAspectRatio", "cast.pixelAspectRatio", FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL } }, { &hf_cast_clockConversionCode, { "ClockConversionCode", "cast.clockConversionCode", FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL } }, { &hf_cast_clockDivisor, { "ClockDivisor", "cast.clockDivisor", FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL } }, { &hf_cast_activeStreamsOnRegistration, { "ActiveStreamsOnRegistration", "cast.activeStreamsOnRegistration", FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL } }, { &hf_cast_maxBW, { "MaxBW", "cast.maxBW", FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL } }, { &hf_cast_serviceResourceCount, { "ServiceResourceCount", "cast.serviceResourceCount", FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL } }, { &hf_cast_layoutCount, { "LayoutCount", "cast.layoutCount", FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL } }, { &hf_cast_layout, { "Layout", "cast.layout", FT_UINT32, BASE_DEC, VALS(cast_Layouts), 0x0, NULL, HFILL } }, { &hf_cast_maxConferences, { "MaxConferences", "cast.maxConferences", FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL } }, { &hf_cast_activeConferenceOnRegistration, { "ActiveConferenceOnRegistration", "cast.activeConferenceOnRegistration", FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL } }, { &hf_cast_transmitOrReceive, { "TransmitOrReceive", "cast.transmitOrReceive", FT_UINT32, BASE_DEC, VALS(cast_transmitOrReceive), 0x0, NULL, HFILL } }, { &hf_cast_levelPreferenceCount, { "LevelPreferenceCount", "cast.levelPreferenceCount", FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL } }, { &hf_cast_transmitPreference, { "TransmitPreference", "cast.transmitPreference", FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL } }, { &hf_cast_format, { "Format", "cast.format", FT_UINT32, BASE_DEC, VALS(cast_formatTypes), 0x0, NULL, HFILL } }, { &hf_cast_maxBitRate, { "MaxBitRate", "cast.maxBitRate", FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL } }, { &hf_cast_minBitRate, { "MinBitRate", "cast.minBitRate", FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL } }, { &hf_cast_MPI, { "MPI", "cast.MPI", FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL } }, { &hf_cast_serviceNumber, { "ServiceNumber", "cast.serviceNumber", FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL } }, { &hf_cast_temporalSpatialTradeOffCapability, { "TemporalSpatialTradeOffCapability", "cast.temporalSpatialTradeOffCapability", FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL } }, { &hf_cast_stillImageTransmission, { "StillImageTransmission", "cast.stillImageTransmission", FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL } }, { &hf_cast_h263_capability_bitfield, { "H263_capability_bitfield", "cast.h263_capability_bitfield", FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL } }, { &hf_cast_annexNandWFutureUse, { "AnnexNandWFutureUse", "cast.annexNandWFutureUse", FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL } }, { &hf_cast_modelNumber, { "ModelNumber", "cast.modelNumber", FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL } }, { &hf_cast_bandwidth, { "Bandwidth", "cast.bandwidth", FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL } }, { &hf_cast_protocolDependentData, { "ProtocolDependentData", "cast.protocolDependentData", FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL } }, { &hf_cast_DSCPValue, { "DSCPValue", "cast.DSCPValue", FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL } }, { &hf_cast_serviceNum, { "ServiceNum", "cast.serviceNum", FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL } }, #if 0 { &hf_cast_precedenceValue, { "Precedence", "cast.precedenceValue", FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL } }, #endif { &hf_cast_maxStreams, { "MaxStreams", "cast.maxStreams", FT_UINT32, BASE_DEC, NULL, 0x0, "32 bit unsigned integer indicating the maximum number of simultaneous RTP duplex streams that the client can handle.", HFILL } }, { &hf_cast_millisecondPacketSize, { "MS/Packet", "cast.millisecondPacketSize", FT_UINT32, BASE_DEC, NULL, 0x0, "The number of milliseconds of conversation in each packet", HFILL } }, { &hf_cast_echoCancelType, { "Echo Cancel Type", "cast.echoCancelType", FT_UINT32, BASE_DEC, VALS(cast_echoCancelTypes), 0x0, "Is echo cancelling enabled or not", HFILL } }, { &hf_cast_g723BitRate, { "G723 BitRate", "cast.g723BitRate", FT_UINT32, BASE_DEC, VALS(cast_g723BitRates), 0x0, "The G723 bit rate for this stream/JUNK if not g723 stream", HFILL } }, { &hf_cast_pictureFormatCount, { "PictureFormatCount", "cast.pictureFormatCount", FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL } }, { &hf_cast_confServiceNum, { "ConfServiceNum", "cast.confServiceNum", FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL } }, { &hf_cast_miscCommandType, { "MiscCommandType", "cast.miscCommandType", FT_UINT32, BASE_DEC, VALS(cast_miscCommandType), 0x0, NULL, HFILL } }, { &hf_cast_temporalSpatialTradeOff, { "TemporalSpatialTradeOff", "cast.temporalSpatialTradeOff", FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL } }, { &hf_cast_firstGOB, { "FirstGOB", "cast.firstGOB", FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL } }, { &hf_cast_numberOfGOBs, { "NumberOfGOBs", "cast.numberOfGOBs", FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL } }, { &hf_cast_firstMB, { "FirstMB", "cast.firstMB", FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL } }, { &hf_cast_numberOfMBs, { "NumberOfMBs", "cast.numberOfMBs", FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL } }, { &hf_cast_pictureNumber, { "PictureNumber", "cast.pictureNumber", FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL } }, { &hf_cast_longTermPictureIndex, { "LongTermPictureIndex", "cast.longTermPictureIndex", FT_UINT32, BASE_DEC, NULL, 0x0, "LongTermPictureIndex.", HFILL } }, { &hf_cast_recoveryReferencePictureCount, { "RecoveryReferencePictureCount", "cast.recoveryReferencePictureCount", FT_UINT32, BASE_DEC, NULL, 0x0, "RecoveryReferencePictureCount.", HFILL } }, { &hf_cast_calledParty, { "CalledParty", "cast.calledParty", FT_STRING, BASE_NONE, NULL, 0x0, "The number called.", HFILL } }, { &hf_cast_privacy, { "Privacy", "cast.privacy", FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL } }, { &hf_cast_precedenceLv, { "PrecedenceLv", "cast.precedenceLv", FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL } }, { &hf_cast_precedenceDm, { "PrecedenceDm", "cast.precedenceDm", FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL } }, { &hf_cast_callState, { "CallState", "cast.callState", FT_UINT32, BASE_DEC, VALS(cast_callStateTypes), 0x0, NULL, HFILL } }, { &hf_cast_callingPartyName, { "Calling Party Name", "cast.callingPartyName", FT_STRING, BASE_NONE, NULL, 0x0, "The passed name of the calling party.", HFILL } }, { &hf_cast_callingParty, { "Calling Party", "cast.callingParty", FT_STRING, BASE_NONE, NULL, 0x0, "The passed number of the calling party.", HFILL } }, { &hf_cast_calledPartyName, { "Called Party Name", "cast.calledPartyName", FT_STRING, BASE_NONE, NULL, 0x0, "The name of the party we are calling.", HFILL } }, { &hf_cast_callType, { "Call Type", "cast.callType", FT_UINT32, BASE_DEC, VALS(cast_callTypes), 0x0, "What type of call, in/out/etc", HFILL } }, { &hf_cast_originalCalledPartyName, { "Original Called Party Name", "cast.originalCalledPartyName", FT_STRING, BASE_NONE, NULL, 0x0, "name of the original person who placed the call.", HFILL } }, { &hf_cast_originalCalledParty, { "Original Called Party", "cast.originalCalledParty", FT_STRING, BASE_NONE, NULL, 0x0, "The number of the original calling party.", HFILL } }, { &hf_cast_lastRedirectingPartyName, { "LastRedirectingPartyName", "cast.lastRedirectingPartyName", FT_STRING, BASE_NONE, NULL, 0x0, NULL, HFILL } }, { &hf_cast_lastRedirectingParty, { "LastRedirectingParty", "cast.lastRedirectingParty", FT_STRING, BASE_NONE, NULL, 0x0, NULL, HFILL } }, { &hf_cast_cgpnVoiceMailbox, { "CgpnVoiceMailbox", "cast.cgpnVoiceMailbox", FT_STRING, BASE_NONE, NULL, 0x0, NULL, HFILL } }, { &hf_cast_cdpnVoiceMailbox, { "CdpnVoiceMailbox", "cast.cdpnVoiceMailbox", FT_STRING, BASE_NONE, NULL, 0x0, NULL, HFILL } }, { &hf_cast_originalCdpnVoiceMailbox, { "OriginalCdpnVoiceMailbox", "cast.originalCdpnVoiceMailbox", FT_STRING, BASE_NONE, NULL, 0x0, NULL, HFILL } }, { &hf_cast_lastRedirectingVoiceMailbox, { "LastRedirectingVoiceMailbox", "cast.lastRedirectingVoiceMailbox", FT_STRING, BASE_NONE, NULL, 0x0, NULL, HFILL } }, { &hf_cast_originalCdpnRedirectReason, { "OriginalCdpnRedirectReason", "cast.originalCdpnRedirectReason", FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL } }, { &hf_cast_lastRedirectingReason, { "LastRedirectingReason", "cast.lastRedirectingReason", FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL } }, { &hf_cast_callInstance, { "CallInstance", "cast.callInstance", FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL } }, { &hf_cast_callSecurityStatus, { "CallSecurityStatus", "cast.callSecurityStatus", FT_UINT32, BASE_DEC, VALS(cast_callSecurityStatusTypes), 0x0, NULL, HFILL } }, { &hf_cast_partyPIRestrictionBits_CallingPartyName, { "RestrictCallingPartyName", "cast.partyPIRestrictionBits.CallingPartyName", FT_BOOLEAN, 32, TFS(&tfs_yes_no), 0x00000001, NULL, HFILL } }, { &hf_cast_partyPIRestrictionBits_CallingPartyNumber, { "RestrictCallingPartyNumber", "cast.partyPIRestrictionBits.CallingPartyNumber", FT_BOOLEAN, 32, TFS(&tfs_yes_no), 0x00000002, NULL, HFILL } }, { &hf_cast_partyPIRestrictionBits_CalledPartyName, { "RestrictCalledPartyName", "cast.partyPIRestrictionBits.CalledPartyName", FT_BOOLEAN, 32, TFS(&tfs_yes_no), 0x00000004, NULL, HFILL } }, { &hf_cast_partyPIRestrictionBits_CalledPartyNumber, { "RestrictCalledPartyNumber", "cast.partyPIRestrictionBits.CalledPartyNumber", FT_BOOLEAN, 32, TFS(&tfs_yes_no), 0x00000008, NULL, HFILL } }, { &hf_cast_partyPIRestrictionBits_OriginalCalledPartyName, { "RestrictOriginalCalledPartyName", "cast.partyPIRestrictionBits.OriginalCalledPartyName", FT_BOOLEAN, 32, TFS(&tfs_yes_no), 0x00000010, NULL, HFILL } }, { &hf_cast_partyPIRestrictionBits_OriginalCalledPartyNumber, { "RestrictOriginalCalledPartyNumber", "cast.partyPIRestrictionBits.OriginalCalledPartyNumber", FT_BOOLEAN, 32, TFS(&tfs_yes_no), 0x00000020, NULL, HFILL } }, { &hf_cast_partyPIRestrictionBits_LastRedirectPartyName, { "RestrictLastRedirectPartyName", "cast.partyPIRestrictionBits.LastRedirectPartyName", FT_BOOLEAN, 32, TFS(&tfs_yes_no), 0x00000040, NULL, HFILL } }, { &hf_cast_partyPIRestrictionBits_LastRedirectPartyNumber, { "RestrictLastRedirectPartyNumber", "cast.partyPIRestrictionBits.LastRedirectPartyNumber", FT_BOOLEAN, 32, TFS(&tfs_yes_no), 0x00000080, NULL, HFILL } }, { &hf_cast_directoryNumber, { "Directory Number", "cast.directoryNumber", FT_STRING, BASE_NONE, NULL, 0x0, "The number we are reporting statistics for.", HFILL } }, { &hf_cast_requestorIpAddress, { "RequestorIpAddress", "cast.requestorIpAddress", FT_IPv4, BASE_NONE, NULL, 0x0, NULL, HFILL } }, { &hf_cast_stationIpAddress, { "StationIpAddress", "cast.stationIpAddress", FT_IPv4, BASE_NONE, NULL, 0x0, NULL, HFILL } }, { &hf_cast_stationFriendlyName, { "StationFriendlyName", "cast.stationFriendlyName", FT_STRING, BASE_NONE, NULL, 0x0, NULL, HFILL } }, { &hf_cast_stationGUID, { "stationGUID", "cast.stationGUID", FT_STRING, BASE_NONE, NULL, 0x0, NULL, HFILL } }, { &hf_cast_audio, { "AudioCodec", "cast.audio", FT_UINT32, BASE_DEC, VALS(audioCodecTypes), 0x0, "The audio codec that is in use.", HFILL } }, { &hf_cast_bitRate, { "BitRate", "cast.bitRate", FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL } }, }; /* Setup protocol subtree array */ static int *ett[] = { &ett_cast, &ett_cast_tree, }; module_t *cast_module; /* Register the protocol name and description */ proto_cast = proto_register_protocol("Cast Client Control Protocol", "CAST", "cast"); proto_register_field_array(proto_cast, hf, array_length(hf)); proto_register_subtree_array(ett, array_length(ett)); cast_module = prefs_register_protocol(proto_cast, NULL); prefs_register_bool_preference(cast_module, "reassembly", /*"desegment",*/ "Reassemble CAST messages spanning multiple TCP segments", "Whether the CAST dissector should reassemble messages spanning multiple TCP segments." " To use this option, you must also enable \"Allow subdissectors to reassemble TCP streams\" in the TCP protocol settings.", &cast_desegment); cast_handle = register_dissector("cast", dissect_cast, proto_cast); } void proto_reg_handoff_cast(void) { dissector_add_uint_with_preference("tcp.port", TCP_PORT_CAST, cast_handle); } /* * Editor modelines - https://www.wireshark.org/tools/modelines.html * * Local Variables: * c-basic-offset: 2 * tab-width: 8 * indent-tabs-mode: nil * End: * * ex: set shiftwidth=2 tabstop=8 expandtab: * :indentSize=2:tabSize=8:noTabs=true: */