diff options
Diffstat (limited to 'epan/dissectors/packet-ranap.c')
-rw-r--r-- | epan/dissectors/packet-ranap.c | 4872 |
1 files changed, 4872 insertions, 0 deletions
diff --git a/epan/dissectors/packet-ranap.c b/epan/dissectors/packet-ranap.c new file mode 100644 index 0000000000..2ec6df5edc --- /dev/null +++ b/epan/dissectors/packet-ranap.c @@ -0,0 +1,4872 @@ +/* packet-ranap.c + * Routines for Radio Access Network Application Part Protocol dissection + * Based on 3GPP TS 25.413 V3.4.0 + * Copyright 2001, Martin Held <Martin.Held@icn.siemens.de> + * + * $Id$ + * + * Ethereal - Network traffic analyzer + * By Gerald Combs <gerald@ethereal.com> + * Copyright 1998 Gerald Combs + * + * Copied from README.developer + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +#include <stdio.h> +#include <stdlib.h> + + +#include <string.h> +#include <glib.h> + +#include <epan/packet.h> + + +#define SCCP_SSN_RANAP 0x8E + +/* description of PDU header */ +#define PDU_NUMBER_OF_OCTETS_OFFSET 3 + +/* PDU Index Values */ +#define InitiatingMessage 0 +#define SuccessfulOutcome 1 +#define UnsuccessfulOutcome 2 +#define Outcome 3 + +static const value_string ranap_pdu_index_values[] = { + {InitiatingMessage, "InitiatingMessage"}, + {SuccessfulOutcome, "SuccessfulOutcome"}, + {UnsuccessfulOutcome, "UnsuccessfulOutcome"}, + {Outcome, "Outcome"}, + { 0, NULL} +}; + + +/* Procedure Code Values */ +#define PC_RAB_Assignment 0 +#define PC_Iu_Release 1 +#define PC_RelocationPreparation 2 +#define PC_RelocationResourceAllocation 3 +#define PC_RelocationCancel 4 +#define PC_SRNS_ContextTransfer 5 +#define PC_SecurityModeControl 6 +#define PC_DataVolumeReport 7 +#define PC_CN_InformationBroadcast 8 +#define PC_Reset 9 +#define PC_RAB_ReleaseRequest 10 +#define PC_Iu_ReleaseRequest 11 +#define PC_RelocationDetect 12 +#define PC_RelocationComplete 13 +#define PC_Paging 14 +#define PC_CommonID 15 +#define PC_CN_InvokeTrace 16 +#define PC_LocationReportingControl 17 +#define PC_LocationReport 18 +#define PC_InitialUE_Message 19 +#define PC_DirectTransfer 20 +#define PC_OverloadControl 21 +#define PC_ErrorIndication 22 +#define PC_SRNS_DataForward 23 +#define PC_ForwardSRNS_Context 24 +#define PC_privateMessage 25 +#define PC_CN_DeactivateTrace 26 +#define PC_ResetResource 27 +#define PC_RANAP_Relocation 28 +#define PC_max 28 + +static const value_string ranap_procedure_code_values[] = { + {PC_RAB_Assignment, "RAB-Assignment"}, + {PC_Iu_Release, "IU-Release"}, + {PC_RelocationPreparation, "RelocationPreparation"}, + {PC_RelocationResourceAllocation, "RelocationResourceAllocation"}, + {PC_RelocationCancel, "RelocationCancel"}, + {PC_SRNS_ContextTransfer, "SRNS-ContextTransfer"}, + {PC_SecurityModeControl, "SecurityModeControl"}, + {PC_DataVolumeReport, "DataVolumeReport"}, + {PC_CN_InformationBroadcast, "CN-InformationBroadcast"}, + {PC_Reset, "Reset"}, + {PC_RAB_ReleaseRequest, "RAB-ReleaseRequest"}, + {PC_Iu_ReleaseRequest, "Iu-ReleaseRequest"}, + {PC_RelocationDetect, "RelocationDetect"}, + {PC_RelocationComplete, "RelocationComplete"}, + {PC_Paging, "Paging"}, + {PC_CommonID, "CommonID"}, + {PC_CN_InvokeTrace, "CN-InvokeTrace"}, + {PC_LocationReportingControl, "LocationReportingControl"}, + {PC_LocationReport, "LocationReport"}, + {PC_InitialUE_Message, "InitialUE_Message"}, + {PC_DirectTransfer, "DirectTransfer"}, + {PC_OverloadControl, "OverloadControl"}, + {PC_ErrorIndication, "ErrorIndication"}, + {PC_SRNS_DataForward, "SRNS-DataForward"}, + {PC_ForwardSRNS_Context, "ForwardSRNS-Context"}, + {PC_privateMessage, "privateMessage"}, + {PC_CN_DeactivateTrace, "CN-DeactivateTrace"}, + {PC_ResetResource, "ResetResource"}, + {PC_RANAP_Relocation, "RANAP-Relocation"}, + {0, NULL} +}; + + +static const value_string ranap_message_names[][5] = { + {/* PC_RAB_Assignment */ + { InitiatingMessage, "RAB-AssignmentRequest"}, + { SuccessfulOutcome, "undefined message"}, + { UnsuccessfulOutcome, "undefined message"}, + { Outcome, "RAB-AssignmentResponse"}, + { 0, NULL}, }, + { /* PC_Iu_Release */ + { InitiatingMessage, "Iu-ReleaseCommand"}, + { SuccessfulOutcome, "Iu-ReleaseComplete"}, + { UnsuccessfulOutcome, NULL}, + { Outcome, NULL}, + { 0, NULL}, }, + { /* PC_RelocationPreparation */ + { InitiatingMessage, "RelocationRequired"}, + { SuccessfulOutcome, "RelocationCommand"}, + { UnsuccessfulOutcome, "RelocationPreparationFailure"}, + { Outcome, NULL}, + { 0, NULL}, }, + { /* PC_RelocationResourceAllocation */ + { InitiatingMessage, "RelocationRequest"}, + { SuccessfulOutcome, "RelocationRequestAcknowledge"}, + { UnsuccessfulOutcome, "RelocationFailure"}, + { Outcome, NULL}, + { 0, NULL}, }, + { /* PC_RelocationCancel */ + { InitiatingMessage, "RelocationCancel"}, + { SuccessfulOutcome, "RelocationCancelAcknowledge"}, + { UnsuccessfulOutcome, NULL}, + { Outcome, NULL}, + { 0, NULL}, }, + { /* PC_SRNS_ContextTransfer */ + { InitiatingMessage, "SRNS-ContextRequest"}, + { SuccessfulOutcome, "SRNS-ContextResponse"}, + { UnsuccessfulOutcome, NULL}, + { Outcome, NULL}, + { 0, NULL}, }, + { /* PC_SecurityModeControl */ + { InitiatingMessage, "SecurityModeCommand"}, + { SuccessfulOutcome, "SecurityModeComplete"}, + { UnsuccessfulOutcome, "SecurityModeReject"}, + { Outcome, NULL}, + { 0, NULL}, }, + { /* PC_DataVolumeReport */ + { InitiatingMessage, "DataVolumeReportRequest"}, + { SuccessfulOutcome, "DataVolumeReport"}, + { UnsuccessfulOutcome, NULL}, + { Outcome, NULL}, + { 0, NULL}, }, + { /* PC_CN_InformationBroadcast */ + { InitiatingMessage, "CN-InformationBroadcastRequest"}, + { SuccessfulOutcome, "CN-InformationBroadcastConfirm"}, + { UnsuccessfulOutcome, "CN-InformationBroadcastReject"}, + { Outcome, NULL}, + { 0, NULL}, }, + { /* PC_Reset */ + { InitiatingMessage, "Reset"}, + { SuccessfulOutcome, "ResetAcknowledge"}, + { UnsuccessfulOutcome, NULL}, + { Outcome, NULL}, + { 0, NULL}, }, + { /* PC_RAB_ReleaseRequest */ + { InitiatingMessage, "RAB-ReleaseRequest"}, + { SuccessfulOutcome, NULL}, + { UnsuccessfulOutcome, NULL}, + { Outcome, NULL}, + { 0, NULL}, }, + { /* PC_Iu_ReleaseRequest */ + { InitiatingMessage, "Iu-ReleaseRequest"}, + { SuccessfulOutcome, NULL}, + { UnsuccessfulOutcome, NULL}, + { Outcome, NULL}, + { 0, NULL}, }, + { /* PC_RelocationDetect */ + { InitiatingMessage, "RelocationDetect"}, + { SuccessfulOutcome, NULL}, + { UnsuccessfulOutcome, NULL}, + { Outcome, NULL}, + { 0, NULL}, }, + { /* PC_RelocationComplete */ + { InitiatingMessage, "RelocationComplete"}, + { SuccessfulOutcome, NULL}, + { UnsuccessfulOutcome, NULL}, + { Outcome, NULL}, + { 0, NULL}, }, + { /* PC_Paging */ + { InitiatingMessage, "Paging"}, + { SuccessfulOutcome, NULL}, + { UnsuccessfulOutcome, NULL}, + { Outcome, NULL}, + { 0, NULL}, }, + { /* PC_CommonID */ + { InitiatingMessage, "CommonID"}, + { SuccessfulOutcome, NULL}, + { UnsuccessfulOutcome, NULL}, + { Outcome, NULL}, + { 0, NULL}, }, + { /* PC_CN_InvokeTrace */ + { InitiatingMessage, "CN-InvokeTrace"}, + { SuccessfulOutcome, NULL}, + { UnsuccessfulOutcome, NULL}, + { Outcome, NULL}, + { 0, NULL}, }, + {/* PC_LocationReportingControl */ + { InitiatingMessage, "LocationReportingControl"}, + { SuccessfulOutcome, NULL}, + { UnsuccessfulOutcome, NULL}, + { Outcome, NULL}, + { 0, NULL}, }, + { /* PC_LocationReport */ + { InitiatingMessage, "LocationReport"}, + { SuccessfulOutcome, NULL}, + { UnsuccessfulOutcome, NULL}, + { Outcome, NULL}, + { 0, NULL}, }, + { /* PC_InitialUE_Message */ + { InitiatingMessage, "InitialUE-Message"}, + { SuccessfulOutcome, NULL}, + { UnsuccessfulOutcome, NULL}, + { Outcome, NULL}, + { 0, NULL}, }, + { /* PC_DirectTransfer */ + { InitiatingMessage, "DirectTransfer"}, + { SuccessfulOutcome, NULL}, + { UnsuccessfulOutcome, NULL}, + { Outcome, NULL}, + { 0, NULL}, }, + { /* PC_OverloadControl */ + { InitiatingMessage, "Overload"}, + { SuccessfulOutcome, NULL}, + { UnsuccessfulOutcome, NULL}, + { Outcome, NULL}, + { 0, NULL}, }, + { /* PC_ErrorIndication */ + { InitiatingMessage, "ErrorIndication"}, + { SuccessfulOutcome, NULL}, + { UnsuccessfulOutcome, NULL}, + { Outcome, NULL}, + { 0, NULL}, }, + { /* PC_SRNS_DataForward */ + { InitiatingMessage, "SRNS-DataForwardCommand"}, + { SuccessfulOutcome, NULL}, + { UnsuccessfulOutcome, NULL}, + { Outcome, NULL}, + { 0, NULL}, }, + { /* PC_ForwardSRNS_Context */ + { InitiatingMessage, "ForwardSRNS-Context"}, + { SuccessfulOutcome, NULL}, + { UnsuccessfulOutcome, NULL}, + { Outcome, NULL}, + { 0, NULL}, }, + { /* PC_privateMessage */ + { InitiatingMessage, "PrivateMessage"}, + { SuccessfulOutcome, NULL}, + { UnsuccessfulOutcome, NULL}, + { Outcome, NULL}, + { 0, NULL}, }, + { /* PC_CN_DeactivateTrace */ + { InitiatingMessage, "CN-DeactivateTrace"}, + { SuccessfulOutcome, NULL}, + { UnsuccessfulOutcome, NULL}, + { Outcome, NULL}, + { 0, NULL}, }, + { /* PC_ResetResource */ + { InitiatingMessage, "ResetResource"}, + { SuccessfulOutcome, "ResetResourceAcknowledge"}, + { UnsuccessfulOutcome, NULL}, + { Outcome, NULL}, + { 0, NULL}, }, + { /* PC_RANAP_Relocation */ + { InitiatingMessage, "RANAP-RelocationInformation"}, + { SuccessfulOutcome, NULL}, + { UnsuccessfulOutcome, NULL}, + { Outcome, NULL}, + { 0, NULL}, } +}; + + +/* Criticality Values */ +#define CR_reject 0 +#define CR_ignore 1 +#define CR_notify 2 + +static const value_string ranap_criticality_values[] = { + {CR_reject, "reject"}, + {CR_ignore, "ignore"}, + {CR_notify, "notify"}, + {0, NULL}}; + + +/* presence values for optional components */ +#define PR_not_present 0 +#define PR_present 1 + +static const value_string ranap_presence_values[] = { + {PR_not_present, "not present"}, + {PR_present, "present"}, + {0, NULL}}; + + +/* description of IE Header */ +#define IE_ID_LENGTH 2 +#define IE_CRITICALITY_LENGTH 1 + + +/* description of IE-ID values */ +#define IE_AreaIdentity 0 +#define IE_CN_BroadcastInformationPiece 1 +#define IE_CN_BroadcastInformationPieceList 2 +#define IE_CN_DomainIndicator 3 +#define IE_Cause 4 +#define IE_ChosenEncryptionAlgorithm 5 +#define IE_ChosenIntegrityProtectionAlgorithm 6 +#define IE_ClassmarkInformation2 7 +#define IE_ClassmarkInformation3 8 +#define IE_CriticalityDiagnostics 9 +#define IE_DL_GTP_PDU_SequenceNumber 10 +#define IE_EncryptionInformation 11 +#define IE_IntegrityProtectionInformation 12 +#define IE_IuTransportAssociation 13 +#define IE_L3_Information 14 +#define IE_LAI 15 +#define IE_NAS_PDU 16 +#define IE_NonSearchingIndication 17 +#define IE_NumberOfSteps 18 +#define IE_OMC_ID 19 +#define IE_OldBSS_ToNewBSS_Information 20 +#define IE_PagingAreaID 21 +#define IE_PagingCause 22 +#define IE_PermanentNAS_UE_ID 23 +#define IE_RAB_ContextItem 24 +#define IE_RAB_ContextList 25 +#define IE_RAB_DataForwardingItem 26 +#define IE_RAB_DataForwardingItem_SRNS_CtxReq 27 +#define IE_RAB_DataForwardingList 28 +#define IE_RAB_DataForwardingList_SRNS_CtxReq 29 +#define IE_RAB_DataVolumeReportItem 30 +#define IE_RAB_DataVolumeReportList 31 +#define IE_RAB_DataVolumeReportRequestItem 32 +#define IE_RAB_DataVolumeReportRequestList 33 +#define IE_RAB_FailedItem 34 +#define IE_RAB_FailedList 35 +#define IE_RAB_ID 36 +#define IE_RAB_QueuedItem 37 +#define IE_RAB_QueuedList 38 +#define IE_RAB_ReleaseFailedList 39 +#define IE_RAB_ReleaseItem 40 +#define IE_RAB_ReleaseList 41 +#define IE_RAB_ReleasedItem 42 +#define IE_RAB_ReleasedList 43 +#define IE_RAB_ReleasedList_IuRelComp 44 +#define IE_RAB_RelocationReleaseItem 45 +#define IE_RAB_RelocationReleaseList 46 +#define IE_RAB_SetupItem_RelocReq 47 +#define IE_RAB_SetupItem_RelocReqAck 48 +#define IE_RAB_SetupList_RelocReq 49 +#define IE_RAB_SetupList_RelocReqAck 50 +#define IE_RAB_SetupOrModifiedItem 51 +#define IE_RAB_SetupOrModifiedList 52 +#define IE_RAB_SetupOrModifyItem 53 +#define IE_RAB_SetupOrModifyList 54 +#define IE_RAC 55 +#define IE_RelocationType 56 +#define IE_RequestType 57 +#define IE_SAI 58 +#define IE_SAPI 59 +#define IE_SourceID 60 +#define IE_SourceRNC_ToTargetRNC_TransparentContainer 61 +#define IE_TargetID 62 +#define IE_TargetRNC_ToSourceRNC_TransparentContainer 63 +#define IE_TemporaryUE_ID 64 +#define IE_TraceReference 65 +#define IE_TraceType 66 +#define IE_TransportLayerAddress 67 +#define IE_TriggerID 68 +#define IE_UE_ID 69 +#define IE_UL_GTP_PDU_SequenceNumber 70 +#define IE_RAB_FailedtoReportItem 71 +#define IE_RAB_FailedtoReportList 72 +#define IE_KeyStatus 75 +#define IE_DRX_CycleLengthCoefficient 76 +#define IE_IuSigConIdList 77 +#define IE_IuSigConIdItem 78 +#define IE_IuSigConId 79 +#define IE_DirectTransferInformationItem_RANAP_RelocInf 80 +#define IE_DirectTransferInformationList_RANAP_RelocInf 81 +#define IE_RAB_ContextItem_RANAP_RelocInf 82 +#define IE_RAB_ContextList_RANAP_RelocInf 83 +#define IE_RAB_ContextFailedtoTransferItem 84 +#define IE_RAB_ContextFailedtoTransferList 85 +#define IE_GlobalRNC_ID 86 +#define IE_RAB_ReleasedItem_IuRelComp 87 + +static const value_string ranap_ie_id_values[] = { + {IE_AreaIdentity, "AreaIdentity"}, + {IE_CN_BroadcastInformationPiece, "CN_BroadcastInformationPiece"}, + {IE_CN_BroadcastInformationPieceList, "CN_BroadcastInformationPieceList"}, + {IE_CN_DomainIndicator, "CN_DomainIndicator"}, + {IE_Cause, "Cause"}, + {IE_ChosenEncryptionAlgorithm, "ChosenEncryptionAlgorithm"}, + {IE_ChosenIntegrityProtectionAlgorithm, "ChosenIntegrityProtectionAlgorithm"}, + {IE_ClassmarkInformation2, "ClassmarkInformation2"}, + {IE_ClassmarkInformation3, "ClassmarkInformation3"}, + {IE_CriticalityDiagnostics, "CriticalityDiagnostics"}, + {IE_DL_GTP_PDU_SequenceNumber, "DL_GTP_PDU_SequenceNumber"}, + {IE_EncryptionInformation, "EncryptionInformation"}, + {IE_IntegrityProtectionInformation, "IntegrityProtectionInformation"}, + {IE_IuTransportAssociation, "IuTransportAssociation"}, + {IE_L3_Information, "L3_Information"}, + {IE_LAI, "LAI"}, + {IE_NAS_PDU, "NAS_PDU"}, + {IE_NonSearchingIndication, "NonSearchingIndication"}, + {IE_NumberOfSteps, "NumberOfSteps"}, + {IE_OMC_ID, "OMC_ID"}, + {IE_OldBSS_ToNewBSS_Information, "OldBSS_ToNewBSS_Information"}, + {IE_PagingAreaID, "PagingAreaID"}, + {IE_PagingCause, "PagingCause"}, + {IE_PermanentNAS_UE_ID, "PermanentNAS_UE_ID"}, + {IE_RAB_ContextItem, "RAB_ContextItem"}, + {IE_RAB_ContextList, "RAB_ContextList"}, + {IE_RAB_DataForwardingItem, "RAB_DataForwardingItem"}, + {IE_RAB_DataForwardingItem_SRNS_CtxReq, "RAB_DataForwardingItem_SRNS_CtxReq"}, + {IE_RAB_DataForwardingList, "RAB_DataForwardingList"}, + {IE_RAB_DataForwardingList_SRNS_CtxReq, "RAB_DataForwardingList_SRNS_CtxReq"}, + {IE_RAB_DataVolumeReportItem, "RAB_DataVolumeReportItem"}, + {IE_RAB_DataVolumeReportList, "RAB_DataVolumeReportList"}, + {IE_RAB_DataVolumeReportRequestItem, "RAB_DataVolumeReportRequestItem"}, + {IE_RAB_DataVolumeReportRequestList, "RAB_DataVolumeReportRequestList"}, + {IE_RAB_FailedItem, "RAB_FailedItem"}, + {IE_RAB_FailedList, "RAB_FailedList"}, + {IE_RAB_ID, "RAB_ID"}, + {IE_RAB_QueuedItem, "RAB_QueuedItem"}, + {IE_RAB_QueuedList, "RAB_QueuedList"}, + {IE_RAB_ReleaseFailedList, "RAB_ReleaseFailedList"}, + {IE_RAB_ReleaseItem, "RAB_ReleaseItem"}, + {IE_RAB_ReleaseList, "RAB_ReleaseList"}, + {IE_RAB_ReleasedItem, "RAB_ReleasedItem"}, + {IE_RAB_ReleasedList, "RAB_ReleasedList"}, + {IE_RAB_ReleasedList_IuRelComp, "RAB_ReleasedList_IuRelComp"}, + {IE_RAB_RelocationReleaseItem, "RAB_RelocationReleaseItem"}, + {IE_RAB_RelocationReleaseList, "RAB_RelocationReleaseList"}, + {IE_RAB_SetupItem_RelocReq, "RAB_SetupItem_RelocReq"}, + {IE_RAB_SetupItem_RelocReqAck, "RAB_SetupItem_RelocReqAck"}, + {IE_RAB_SetupList_RelocReq, "RAB_SetupList_RelocReq"}, + {IE_RAB_SetupList_RelocReqAck, "RAB_SetupList_RelocReqAck"}, + {IE_RAB_SetupOrModifiedItem, "RAB_SetupOrModifiedItem"}, + {IE_RAB_SetupOrModifiedList, "RAB_SetupOrModifiedList"}, + {IE_RAB_SetupOrModifyItem, "RAB_SetupOrModifyItem"}, + {IE_RAB_SetupOrModifyList, "RAB_SetupOrModifyList"}, + {IE_RAC, "RAC"}, + {IE_RelocationType, "RelocationType"}, + {IE_RequestType, "RequestType"}, + {IE_SAI, "SAI"}, + {IE_SAPI, "SAPI"}, + {IE_SourceID, "SourceID"}, + {IE_SourceRNC_ToTargetRNC_TransparentContainer, + "SourceRNC_ToTargetRNC_TransparentContainer"}, + {IE_TargetID, "TargetID"}, + {IE_TargetRNC_ToSourceRNC_TransparentContainer, + "TargetRNC_ToSourceRNC_TransparentContainer"}, + {IE_TemporaryUE_ID, "TemporaryUE_ID"}, + {IE_TraceReference, "TraceReference"}, + {IE_TraceType, "TraceType"}, + {IE_TransportLayerAddress, "TransportLayerAddress"}, + {IE_TriggerID, "TriggerID"}, + {IE_UE_ID, "UE_ID"}, + {IE_UL_GTP_PDU_SequenceNumber, "UL_GTP_PDU_SequenceNumber"}, + {IE_RAB_FailedtoReportItem, "RAB_FailedtoReportItem"}, + {IE_RAB_FailedtoReportList, "RAB_FailedtoReportList"}, + {IE_KeyStatus, "KeyStatus"}, + {IE_DRX_CycleLengthCoefficient, "DRX_CycleLengthCoefficient"}, + {IE_IuSigConIdList, "IuSigConIdList"}, + {IE_IuSigConIdItem, "IuSigConIdItem"}, + {IE_IuSigConId, "IuSigConId"}, + {IE_DirectTransferInformationItem_RANAP_RelocInf, + "DirectTransferInformationItem_RANAP_RelocInf"}, + {IE_DirectTransferInformationList_RANAP_RelocInf, + "DirectTransferInformationList_RANAP_RelocInf"}, + {IE_RAB_ContextItem_RANAP_RelocInf, "RAB_ContextItem_RANAP_RelocInf"}, + {IE_RAB_ContextList_RANAP_RelocInf, "RAB_ContextList_RANAP_RelocInf"}, + {IE_RAB_ContextFailedtoTransferItem, "RAB_ContextFailedtoTransferItem"}, + {IE_RAB_ContextFailedtoTransferList, "RAB_ContextFailedtoTransferList"}, + {IE_GlobalRNC_ID, "GlobalRNC_ID"}, + {IE_RAB_ReleasedItem_IuRelComp, "RAB_ReleasedItem_IuRelComp"}, + {0, NULL} +}; + + +/* Description of IE-Contents */ + +/* Length of fields within IEs */ +#define RAB_ID_LENGTH 1 +#define PLMN_ID_LENGTH 3 +#define LAC_LENGTH 2 +#define IE_PROTOCOL_EXTENSION_LENGTH 1 +#define RAC_LENGTH 1 +#define SAC_LENGTH 2 +#define NUM_RABS_LENGTH 1 + + +/* Traffic Class values */ +#define TC_conversational 0 +#define TC_streaming 1 +#define TC_interactive 2 +#define TC_background 3 + +static const value_string ranap_trafficClass_values[] = { + {TC_conversational, "conversational"}, + {TC_streaming, "streaming"}, + {TC_interactive, "interactive"}, + {TC_background, "background"}, + {0, NULL}}; + + +/* rAB-AsymmetryIndicator values */ +#define AI_symmetric_bidirectional 0 +#define AI_asymmetric_unidirectional_downlink 1 +#define AI_asymmetric_unidirectional_uplink 2 +#define AI_asymmetric_bidirectional 3 + +static const value_string ranap_rAB_AsymmetryIndicator_values[] = { + {AI_symmetric_bidirectional, "symmetric-bidirectional"}, + {AI_asymmetric_unidirectional_downlink, "asymmetric-unidirectional-downlink"}, + {AI_asymmetric_unidirectional_uplink, "asymmetric-unidirectional-uplink"}, + {AI_asymmetric_bidirectional, "asymmetric-bidirectional"}, + {0, NULL}}; + + +/* DeliveryOrder values */ +#define DO_delivery_order_requested 0 +#define DO_delivery_order_not_requested 1 + +static const value_string ranap_DeliveryOrder_values[] = { + {DO_delivery_order_requested, "delivery-order-requested"}, + {DO_delivery_order_not_requested, "delivery-order-not-requested"}, + {0, NULL}}; + +#define maxSDU_Size_LENGTH 2 + +/* deliveryOfErroneousSDU values */ +#define DOES_yes 0 +#define DOES_no 1 +#define DOES_no_error_detection_consideration 2 + +static const value_string ranap_deliveryOfErroneousSDU_values[] = { + {DOES_yes, "yes"}, + {DOES_no, "no"}, + {DOES_no_error_detection_consideration, "no-error-detection-consideration"}, + {0, NULL}}; + + +#define subflowSDU_Size_LENGTH 2 +#define transferDelay_LENGTH 2 + + +/* trafficHandlingPriority values */ +static const value_string ranap_priority_values[] = { + { 0, "spare"}, + { 1, "highest"}, + { 2, ""}, + { 3, ""}, + { 4, ""}, + { 5, ""}, + { 6, ""}, + { 7, ""}, + { 8, ""}, + { 9, ""}, + { 10, ""}, + { 11, ""}, + { 12, ""}, + { 13, ""}, + { 14, "lowest"}, + { 15, "no-priority-used"}, + { 0, NULL}}; + + +/* pre-emptionCapability values */ +static const value_string ranap_pre_emptionCapability_values[] = { + { 0, "shall-not-trigger-pre-emption"}, + { 1, "may-trigger-pre-emption"}, + { 0, NULL}}; + +/* pre-emptionVulnerability values */ +static const value_string ranap_pre_emptionVulnerability_values[] = { + { 0, "not-pre-emptable"}, + { 1, "pre-emptable"}, + { 0, NULL}}; + + +/* queuingAllowed values */ +static const value_string ranap_queuingAllowed_values[] = { + { 0, "queueing-not-allowed"}, + { 1, "queueing-allowed"}, + { 0, NULL}}; + + +/* sourceStatisticsDescriptor values */ +static const value_string ranap_sourceStatisticsDescriptor_values[] = { + { 0, "speech"}, + { 1, "unknown"}, + { 0, NULL}}; + +/* relocationRequirement values */ +static const value_string ranap_relocationRequirement_values[] = { + { 0, "lossless"}, + { 1, "none"}, + { 0, NULL}}; + +/* userPlaneMode values */ +static const value_string ranap_userPlaneMode_values[] = { + { 0, "transparent-mode"}, + { 1, "support-mode-for-predefined-SDU-sizes"}, + { 0, NULL}}; + +/* PDP_Type values */ +static const value_string ranap_PDP_Type_values[] = { + { 0, "empty"}, + { 1, "ppp"}, + { 2, "osp-ihoss"}, + { 3, "ipv4"}, + { 4, "ipv6"}, + { 0, NULL}}; + +/* dataVolumeReportingIndication values */ +static const value_string ranap_dataVolumeReportingIndication_values[] = { + { 0, "do-report"}, + { 1, "do-not-report"}, + { 0, NULL}}; + + +/* cause_choice values */ +#define CC_CauseRadioNetwork 0 +#define CC_CauseTransmissionNetwork 1 +#define CC_CauseNAS 2 +#define CC_CauseProtocol 3 +#define CC_CauseMisc 4 +#define CC_CauseNon_Standard 5 + +static const value_string ranap_cause_choice_values[] = { + { CC_CauseRadioNetwork, "CauseRadioNetwork"}, + { CC_CauseTransmissionNetwork, "CauseTransmissionNetwork"}, + { CC_CauseNAS, "CauseNAS"}, + { CC_CauseProtocol, "CauseProtocol"}, + { CC_CauseMisc, "CauseMisc"}, + { CC_CauseNon_Standard, "CauseNon-Standard"}, + { 0, NULL}}; + + +/* cause values */ +static const value_string ranap_cause_value_str[] = { +/* CauseRadioNetwork (1..64) */ + { 1, "rab-pre-empted"}, + { 2, "trelocoverall-expiry"}, + { 3, "trelocprep-expiry"}, + { 4, "treloccomplete-expiry"}, + { 5, "tqueing-expiry"}, + { 6, "relocation-triggered"}, + { 7, "trellocalloc-expiry"}, + { 8, "unable-to-establish-during-relocation"}, + { 9, "unknown-target-rnc"}, + { 10, "relocation-cancelled"}, + { 11, "successful-relocation"}, + { 12, "requested-ciphering-and-or-integrity-protection-algorithms-not-supported"}, + { 13, "change-of-ciphering-and-or-integrity-protection-is-not-supported"}, + { 14, "failure-in-the-radio-interface-procedure"}, + { 15, "release-due-to-utran-generated-reason"}, + { 16, "user-inactivity"}, + { 17, "time-critical-relocation"}, + { 18, "requested-traffic-class-not-available"}, + { 19, "invalid-rab-parameters-value"}, + { 20, "requested-maximum-bit-rate-not-available"}, + { 21, "requested-guaranteed-bit-rate-not-available"}, + { 22, "requested-transfer-delay-not-achievable"}, + { 23, "invalid-rab-parameters-combination"}, + { 24, "condition-violation-for-sdu-parameters"}, + { 25, "condition-violation-for-traffic-handling-priority"}, + { 26, "condition-violation-for-guaranteed-bit-rate"}, + { 27, "user-plane-versions-not-supported"}, + { 28, "iu-up-failure"}, + { 29, "relocation-failure-in-target-CN-RNC-or-target-system"}, + { 30, "invalid-RAB-ID"}, + { 31, "no-remaining-rab"}, + { 32, "interaction-with-other-procedure"}, + { 33, "requested-maximum-bit-rate-for-dl-not-available"}, + { 34, "requested-maximum-bit-rate-for-ul-not-available"}, + { 35, "requested-guaranteed-bit-rate-for-dl-not-available"}, + { 36, "requested-guaranteed-bit-rate-for-ul-not-available"}, + { 37, "repeated-integrity-checking-failure"}, + { 38, "requested-report-type-not-supported"}, + { 39, "request-superseded"}, + { 40, "release-due-to-UE-generated-signalling-connection-release"}, + { 41, "resource-optimisation-relocation"}, + { 42, "requested-information-not-available"}, + { 43, "relocation-desirable-for-radio-reasons"}, + { 44, "relocation-not-supported-in-target-RNC-or-target-system"}, + { 45, "directed-retry"}, + { 46, "radio-connection-with-UE-Lost"}, + +/* CauseTransmissionNetwork (65..80) */ + { 65, "logical-error-unknown-iu-transport-association"}, + { 66, "iu-transport-connection-failed-to-establish"}, + +/* CauseNAS (81..96) */ + { 81, "user-restriction-start-indication"}, + { 82, "user-restriction-end-indication"}, + { 83, "normal-release"}, + +/* CauseProtocol (97..112) */ + { 97, "transfer-syntax-error"}, + { 98, "semantic-error"}, + { 99, "message-not-compatible-with-receiver-state"}, + {100, "abstract-syntax-error-reject"}, + {101, "abstract-syntax-error-ignore-and-notify"}, + {102, "abstract-syntax-error-falsely-constructed-message"}, + +/* CauseMisc (113..128) */ + {113, "om-intervention"}, + {114, "no-resource-available"}, + {115, "unspecified-failure"}, + {116, "network-optimisation"}, + { 0, NULL}}; + + +/* CN_DomainIndicator_values */ +static const value_string ranap_CN_DomainIndicator_values[] = { + { 0, "cs-domain"}, + { 1, "ps-domain"}, + { 0, NULL}}; + + +/* SAPI_values */ +static const value_string ranap_SAPI_values[] = { + { 0, "sapi-0"}, + { 1, "sapi-3"}, + { 0, NULL}}; + +/* service_Handover_values */ +static const value_string ranap_service_Handover_values[] = { + { 0, "handover-to-GSM-should-be-performed"}, + { 1, "handover-to-GSM-should-not-be-performed"}, + { 2, "handover-to-GSM-shall-not-be-performed"}, + { 0, NULL}}; + +/* Initialize the protocol and registered fields */ +/* protocol */ +static int proto_ranap = -1; + +static dissector_table_t nas_pdu_dissector_table; + +packet_info *g_pinfo = NULL; +proto_tree *g_tree = NULL; + +/* pdu header fields */ +static int hf_ranap_pdu_number_of_octets = -1; +static int hf_ranap_pdu_index = -1; +static int hf_ranap_procedure_code = -1; +static int hf_ranap_pdu_criticality = -1; +static int hf_ranap_number_of_ies = -1; + +/* ie header fields */ +static int hf_ranap_ie_ie_id = -1; +static int hf_ranap_ie_criticality = -1; +static int hf_ranap_ie_number_of_octets = -1; +static int hf_ranap_ie_protocol_extension = -1; + +/*ie contents fields */ +static int hf_ranap_number_of_ies_in_list = -1; +static int hf_ranap_ie_pair_first_criticality = -1; +static int hf_ranap_ie_pair_second_criticality = -1; +static int hf_ranap_first_value_number_of_octets = -1; +static int hf_ranap_second_value_number_of_octets = -1; +static int hf_ranap_rab_id = -1; +static int hf_ranap_nas_pdu = -1; +static int hf_ranap_plmn_id = -1; +static int hf_ranap_lac = -1; +static int hf_ranap_sac = -1; +static int hf_ranap_rac = -1; +static int hf_ranap_nAS_SynchronisationIndicator = -1; +static int hf_ranap_trafficClass = -1; +static int hf_ranap_deliveryOrder = -1; +static int hf_ranap_iE_Extensions_present = -1; +static int hf_ranap_num_rabs = -1; +static int hf_ranap_nAS_SynchronisationIndicator_present = -1; +static int hf_ranap_rAB_Parameters_present = -1; +static int hf_ranap_userPlaneInformation_present = -1; +static int hf_ranap_transportLayerInformation_present = -1; +static int hf_ranap_service_Handover_present = -1; +static int hf_ranap_guaranteedBitRate_present = -1; +static int hf_ranap_transferDelay_present = -1; +static int hf_ranap_trafficHandlingPriority_present = -1; +static int hf_ranap_allocationOrRetentionPriority_present = -1; +static int hf_ranap_sourceStatisticsDescriptor_present = -1; +static int hf_ranap_relocationRequirement_present = -1; +static int hf_ranap_rAB_AsymmetryIndicator = -1; +static int hf_ranap_maxBitrate = -1; +static int hf_ranap_guaranteedBitrate = -1; +static int hf_ranap_maxSDU_Size = -1; +static int hf_ranap_sDU_ErrorRatio_mantissa = -1; +static int hf_ranap_sDU_ErrorRatio_exponent = -1; +static int hf_ranap_residualBitErrorRatio_mantissa = -1; +static int hf_ranap_residualBitErrorRatio_exponent = -1; +static int hf_ranap_deliveryOfErroneousSDU = -1; +static int hf_ranap_subflowSDU_Size = -1; +static int hf_ranap_rAB_SubflowCombinationBitRate = -1; +static int hf_ranap_sDU_ErrorRatio_present = -1; +static int hf_ranap_sDU_FormatInformationParameters_present = -1; +static int hf_ranap_subflowSDU_Size_present = -1; +static int hf_ranap_rAB_SubflowCombinationBitRate_present = -1; +static int hf_ranap_transferDelay = -1; +static int hf_ranap_trafficHandlingPriority = -1; +static int hf_ranap_priorityLevel = -1; +static int hf_ranap_pre_emptionCapability = -1; +static int hf_ranap_pre_emptionVulnerability = -1; +static int hf_ranap_queuingAllowed = -1; +static int hf_ranap_sourceStatisticsDescriptor = -1; +static int hf_ranap_userPlaneMode = -1; +static int hf_ranap_uP_ModeVersions = -1; +static int hf_ranap_number_of_ProtocolExtensionFields = -1; +static int hf_ranap_ext_field_id = -1; +static int hf_ranap_ext_field_criticality = -1; +static int hf_ranap_ext_field_number_of_octets = -1; +static int hf_ranap_transportLayerAddress = -1; +static int hf_ranap_transportLayerAddress_length = -1; +static int hf_ranap_gTP_TEI = -1; +static int hf_ranap_bindingID = -1; +static int hf_ranap_pDP_TypeInformation_present = -1; +static int hf_ranap_dataVolumeReportingIndication_present = -1; +static int hf_ranap_dl_GTP_PDU_SequenceNumber_present = -1; +static int hf_ranap_ul_GTP_PDU_SequenceNumber_present = -1; +static int hf_ranap_dl_N_PDU_SequenceNumber_present = -1; +static int hf_ranap_ul_N_PDU_SequenceNumber_present = -1; +static int hf_ranap_PDP_Type = -1; +static int hf_ranap_dataVolumeReportingIndication = -1; +static int hf_ranap_dl_GTP_PDU_SequenceNumber = -1; +static int hf_ranap_ul_GTP_PDU_SequenceNumber = -1; +static int hf_ranap_dl_N_PDU_SequenceNumber = -1; +static int hf_ranap_ul_N_PDU_SequenceNumber = -1; +static int hf_ranap_cause_choice = -1; +static int hf_ranap_cause_value = -1; +static int hf_ranap_transportLayerAddress_present = -1; +static int hf_ranap_iuTransportAssociation_present = -1; +static int hf_ranap_dl_dataVolumes_present = -1; +static int hf_ranap_dataVolumeReference_present = -1; +static int hf_ranap_dl_UnsuccessfullyTransmittedDataVolume = -1; +static int hf_ranap_dataVolumeReference = -1; +static int hf_ranap_procedureCode_present = -1; +static int hf_ranap_triggeringMessage_present = -1; +static int hf_ranap_procedureCriticality_present = -1; +static int hf_ranap_iEsCriticalityDiagnostics_present = -1; +static int hf_ranap_triggeringMessage = -1; +static int hf_ranap_iECriticality = -1; +static int hf_ranap_procedureCriticality = -1; +static int hf_ranap_repetitionNumber = -1; +static int hf_ranap_num_of_CriticalityDiagnostics_IEs = -1; +static int hf_ranap_repetitionNumber_present = -1; +static int hf_ranap_dl_UnsuccessfullyTransmittedDataVolume_present = -1; +static int hf_ranap_CN_DomainIndicator = -1; +static int hf_ranap_IuSigConId = -1; +static int hf_ranap_SAPI = -1; +static int hf_ranap_msg_extension_present = -1; +static int hf_ranap_ProtocolExtensionContainer_present = -1; +static int hf_ranap_nas_pdu_length = -1; +static int hf_ranap_relocationRequirement = -1; +static int hf_ranap_service_Handover = -1; +static int hf_ranap_extension_field = -1; +static int hf_ranap_RNC_ID = -1; + + +/* subtrees */ +static gint ett_ranap = -1; +static gint ett_ranap_optionals = -1; +static gint ett_ranap_iE_Extension = -1; +static gint ett_ranap_ie = -1; +static gint ett_ranap_ie_pair = -1; +static gint ett_ranap_rab = -1; +static gint ett_ranap_ie_pair_first_value = -1; +static gint ett_ranap_ie_pair_second_value = -1; +static gint ett_ranap_rAB_Parameters = -1; +static gint ett_ranap_sDU = -1; +static gint ett_ranap_allocationOrRetentionPriority = -1; +static gint ett_ranap_CriticalityDiagnostics_IE = -1; + + + +/*****************************************************************************/ +/* */ +/* Utility Functions */ +/* */ +/*****************************************************************************/ + +/* sets *offset and *bitoffset n bits further */ +static void +proceed_nbits(gint *offset, gint *bitoffset, gint n) +{ + *bitoffset += n; + *offset += *bitoffset / 8; + *bitoffset %= 8; +} + +/* sets *offset and *bitoffset to the next byte boundary */ +static void allign(gint *offset, gint *bitoffset) +{ + if ( *bitoffset != 0 ) + { + (*offset)++; + *bitoffset=0; + } +} + +/* sets *offset and *bitoffset behind the following integer */ +static void +proceed_perint32(gint *offset, gint *bitoffset, gint length) +{ + proceed_nbits(offset, bitoffset, 2); + allign(offset, bitoffset); + *offset += length; +} + + +/* extract length field found at offset */ +/* if length field spans more than two bytes -1 is returned and the field is not decoded */ +static guint8 +extract_length(tvbuff_t *tvb, gint offset, gint *length, gint *length_size) +{ + guint8 tmp_length8; + guint16 tmp_length16; + + tmp_length8 = tvb_get_guint8(tvb, offset); + if ((tmp_length8 & 0x80) == 0) + { + /* length coded in one byte */ + *length = tmp_length8; + *length_size = 1; + } + else + { + tmp_length16 = tvb_get_ntohs(tvb, offset); + if ( ((tmp_length16 & 0x8000) == 0x8000) && ((tmp_length16 & 0x4000) == 0) ) + { + /* length coded in two bytes */ + *length = tmp_length16 & 0x3FFF; + *length_size = 2; + } + else + { /* length is coded in more than 2 bytes */ + return (-1); + } + } + return(0); +} + +/* extract the next n bits and return them alligned to the LSB */ +static guint8 +extract_nbits(tvbuff_t *tvb, gint offset, gint bitoffset, gint n) +{ + guint8 uint_bits; + guint16 tmp_2bytes; + + /* extract value */ + if (bitoffset + n <= 8) + { + /* all bits contained in one byte */ + uint_bits = tvb_get_guint8(tvb, offset); + uint_bits <<= bitoffset; /* remove bitoffset */ + uint_bits >>= 8-n; /* allign to LSB */ + } + else + { + /* bits contained within 2 bytes */ + tmp_2bytes = tvb_get_ntohs(tvb, offset); + tmp_2bytes <<= bitoffset; /* remove bitoffset */ + uint_bits = tmp_2bytes >> ( 8 + (8-n)); /* allign to LSB */ + } + + return(uint_bits); +} + + +/* extract an integer with 2bit length field and return the int value*/ +static guint32 +extract_int32(tvbuff_t *tvb, gint offset, gint bitoffset, gint *length) +{ + guint16 tmp_2byte; + guint32 result = 0; + + tmp_2byte = tvb_get_ntohs(tvb, offset); + + tmp_2byte <<= bitoffset; /* remove bitoffset */ + *length = tmp_2byte >> (6 + 8); /* allign 2bit length field to LSB */ + (*length)++; /* now we have the length of the int value */ + + proceed_nbits(&offset, &bitoffset, 2); + allign(&offset, &bitoffset); + + switch (*length) + { + case 1: + result = tvb_get_guint8(tvb, offset); + break; + case 2: + result = tvb_get_ntohs(tvb, offset); + break; + case 3: + result = tvb_get_ntoh24(tvb, offset); + break; + case 4: + result = tvb_get_ntohl(tvb, offset); + break; + } + + return(result); +} + + +/* return bitmask string looking like "..01 0..." */ +static char * +bitmaskstr(guint bitoffset, guint bitlength, guint16 value, guint *length) +{ + static char maskstr[20]; + guint i; + + + strcpy(maskstr, " "); + + for (i=0; i<16; i++) + { + if ( i < bitoffset || i > bitoffset+bitlength-1 ) + { + /* i is outside extracted bitfield */ + maskstr[i + i/4] = '.'; + } + else + { /* i is inside extracted bitfield */ + if ( ((0x8000 >> i) & value) != 0x0000 ) + { + /* bit is set */ + maskstr[i + i/4] = '1'; + } + else + { + /* bit is not set */ + maskstr[i + i/4] = '0'; + } + } + } + if (bitoffset + bitlength <= 8) + { + /* bitfield is located within first byte only */ + maskstr[9] = '\0'; + *length = 1; + } + else + { + /* bitfield is located within first & second byte */ + maskstr[19] = '\0'; + *length = 2; + } + + return(maskstr); +} + +/* add bitstring */ +static proto_item * +proto_tree_add_bitstring(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint offset, + gint bitoffset, gint bitlength) +{ + guint16 read_2bytes; + guint16 alligned_2bytes; + guint8 one_byte; + char *maskstr; + char maskstr_buf[56] = "\0"; + guint length; + int i; + guint8 bitstr[128]; + char buf[256] = "\0"; + header_field_info *hf_info_p; + gint byte_span; + gint initial_offset = offset; + + memset(bitstr, 0, 128); + + /* create bitmask string for first byte */ + read_2bytes = tvb_get_ntohs(tvb, offset); + maskstr = bitmaskstr(bitoffset, (bitoffset+bitlength >8) ? 8-bitoffset : bitlength, read_2bytes, &length); + if (bitoffset+bitlength > 8) + { + sprintf(maskstr_buf, "%s + %d Bits = ", maskstr, bitlength - (8-bitoffset)); + } + else + { + sprintf(maskstr_buf, "%s = ", maskstr); + } + + + /* print all but the last byte to buf */ + byte_span = (bitoffset + bitlength + 7) / 8; + for (i=0; i < byte_span - 1; i++, offset++) + { + read_2bytes = tvb_get_ntohs(tvb, offset); + alligned_2bytes = read_2bytes << bitoffset; /* remove bitoffset */ + one_byte = alligned_2bytes >> 8; /* move to low byte */ + + bitstr[i]=one_byte; + sprintf(&(buf[2*i]), "%02X", one_byte); + } + + /* add last byte if it contains bits which have not yet been shifted in */ + if ( ((bitlength + 7) / 8 ) == byte_span ) + { + read_2bytes = tvb_get_ntohs(tvb, offset); + alligned_2bytes = read_2bytes << bitoffset; /* remove bitoffset */ + one_byte = alligned_2bytes >> 8; /* move to low byte */ + one_byte >>= (8 - (bitlength%8)); /*cut off surplus bits */ + one_byte <<= (8 - (bitlength%8)); /* allign to MSB in low byte*/ + + bitstr[i]=one_byte; + sprintf(&(buf[2*i]), "%02X", one_byte); + } + + /* get header field info */ + hf_info_p = proto_registrar_get_nth(hfindex); + + + return ( proto_tree_add_bytes_format(tree, hfindex, tvb, initial_offset, + byte_span , bitstr, "%s %s: %s", maskstr_buf, hf_info_p->name, buf) ); + +} + + +/* add unsigned int, 1-8 bits long */ +static proto_item * +proto_tree_add_uint_bits(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint offset, + gint bitoffset, gint bitlength, gint min) +{ + guint8 uint_bits; + guint16 read_2bytes, alligned_2bytes; + char *maskstr; + guint length; + header_field_info *hf_info_p; + + + /* extract value */ + if (bitoffset + bitlength <= 8) + { + /* all bits contained in one byte */ + uint_bits = tvb_get_guint8(tvb, offset); + read_2bytes = uint_bits; + read_2bytes <<= 8; + } + else + { + /* bits contained within 2 bytes */ + read_2bytes = tvb_get_ntohs(tvb, offset); + } + alligned_2bytes = read_2bytes << bitoffset; /* remove bitoffset */ + uint_bits = alligned_2bytes >> ( 8 + (8-bitlength)); /* allign to LSB */ + + uint_bits += min; + + /* create bitmask string */ + maskstr = bitmaskstr(bitoffset, bitlength, read_2bytes, &length); + + /* get header field info */ + hf_info_p = proto_registrar_get_nth(hfindex); + + if (hf_info_p->strings != NULL) + { + /* string representation for decoded header field present */ + return ( proto_tree_add_uint_format(tree, hfindex, tvb, offset, + length, uint_bits, "%s = %s: %s (%d)", maskstr, hf_info_p->name, + val_to_str(uint_bits, hf_info_p->strings, "%d"), uint_bits) ); + } + else + { + /* no string representation */ + return ( proto_tree_add_uint_format(tree, hfindex, tvb, offset, + length, uint_bits, "%s = %s: %d", maskstr, hf_info_p->name, uint_bits) ); + } +} + +/* add PER encoded integer (maximum length of value: 4 bytes) */ +static proto_item * +proto_tree_add_PERint32(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint offset, + gint bitoffset, gint *length, gint min) +{ + guint32 value; + guint16 tmp_2bytes; + char *maskstr; + guint length_size; + header_field_info *hf_info_p; + + /* get value */ + value = extract_int32(tvb, offset, bitoffset, length); + value += min; + + /* create bitmask string for 2 bit length field */ + tmp_2bytes = tvb_get_ntohs(tvb, offset); + maskstr = bitmaskstr(bitoffset, 2, tmp_2bytes, &length_size); + + /* get header field info */ + hf_info_p = proto_registrar_get_nth(hfindex); + + return ( proto_tree_add_uint_format(tree, hfindex, tvb, offset, + (*length) + length_size, value, + "%s + %d Bytes = %s: %d", maskstr, *length, hf_info_p->name, value) ); +} + + + +/*****************************************************************************/ +/* */ +/* Dissecting Functions for single parameters */ +/* */ +/*****************************************************************************/ +static int +dissect_iE_Extension(tvbuff_t *tvb, proto_tree *tree, gint *offset, gint *bitoffset, char *description) +{ + proto_item *ext_item = NULL; + proto_tree *ext_tree = NULL; + guint16 number_of_extFields; + gint number_of_octets = 0; + gint number_of_octets_size = 0; + int i; + + allign(offset, bitoffset); + + /* create subtree for iE_Extension */ + if (tree) + { + ext_item = proto_tree_add_text(tree, tvb, *offset, 0, "%s iE-Extensions", description); + ext_tree = proto_item_add_subtree(ext_item, ett_ranap_iE_Extension); + } + + /* number of extension fields */ + number_of_extFields = tvb_get_ntohs(tvb, *offset) + 1; + if (ext_tree) + { + proto_tree_add_uint(ext_tree, hf_ranap_number_of_ProtocolExtensionFields, + tvb, *offset, 2, number_of_extFields); + } + + *offset += 2; + + /* for each extension field */ + for (i=1; i <= number_of_extFields; i++) + { + /* add fields to ie subtee */ + /* Extension Field ID */ + if (ext_tree) + { + proto_tree_add_item(ext_tree, hf_ranap_ext_field_id, tvb, + *offset, IE_ID_LENGTH, FALSE); + } + *offset += IE_ID_LENGTH; + + /* criticality */ + if (ext_tree) + { + proto_tree_add_uint_bits(ext_tree, hf_ranap_ext_field_criticality, tvb, + *offset, *bitoffset, 2, 0); + } + proceed_nbits(offset, bitoffset, 2); + + /* number of octets in the IE */ + allign(offset, bitoffset); + if (0 == extract_length(tvb, *offset, &number_of_octets, &number_of_octets_size)) + { + if (ext_tree) + { + proto_tree_add_uint(ext_tree, hf_ranap_ext_field_number_of_octets, tvb, + *offset, number_of_octets_size, number_of_octets); + } + } + else + { + /* decoding is not supported */ + if (ext_tree) + { + proto_tree_add_text(ext_tree, tvb, *offset, 0, + "Number of Octets greater than 0x3FFF, dissection not supported"); + } + return(-1); + } + + *offset += number_of_octets_size; + if (ext_tree) + { + proto_tree_add_item(ext_tree, hf_ranap_extension_field, tvb, + *offset, number_of_octets, FALSE); + + } + + *offset += number_of_octets; + } + + return(0); +} + + +static int +dissect_userPlaneInformation(tvbuff_t *tvb, proto_tree *tree, gint *offset, gint *bitoffset) +{ + int extension_present; + int iE_Extensions_present; + int tmp_extension_present; + + /* protocol_extension present ? */ + extension_present = extract_nbits(tvb, *offset, *bitoffset, 1); + proceed_nbits(offset, bitoffset, 1); + + /* iE_Extensions present ? */ + iE_Extensions_present = extract_nbits(tvb, *offset, *bitoffset, 1); + proceed_nbits(offset, bitoffset, 1); + + /* userPlaneMode */ + tmp_extension_present = extract_nbits(tvb, *offset, *bitoffset, 1); + proceed_nbits(offset, bitoffset, 1); + + proto_tree_add_uint_bits(tree, hf_ranap_userPlaneMode, tvb, *offset, + *bitoffset, 1, 0); + proceed_nbits(offset, bitoffset, 1); + + /* uP-ModeVersions */ + proto_tree_add_bitstring(tree, hf_ranap_uP_ModeVersions, tvb, *offset, + *bitoffset, 16); + proceed_nbits(offset, bitoffset, 16); + + /* iE-Extensions */ + if (iE_Extensions_present) + { + return(dissect_iE_Extension(tvb, tree, offset, bitoffset, "UserPlaneInformation")); + } + return(0); +} + + + +static int +dissect_sDU_Parameters(tvbuff_t *tvb, proto_tree *ie_tree, gint *offset, gint *bitoffset) +{ + proto_item *sDU_item = NULL; + proto_tree *sDU_tree = NULL; + proto_item *optionals_item = NULL; + proto_tree *optionals_tree = NULL; + int ret; + int extension_present; + int sDU_ErrorRatio_present; + int sDU_FormatInformationParameters_present; + int iE_Extensions_present; + int sDU_ErrorRatio_iE_Extensions_present; + int residualBitErrorRatio_iE_Extensions_present; + gint length; + gint number_of_sDU_FormatInformationParameters; + int sDU_FormatInformationParameters_extension_present; + int subflowSDU_Size_present; + int rAB_SubflowCombinationBitRate_present; + int sDU_FormatInformationParameters_iE_Extensions_present; + gint i; + + /* create subtree for sDU_Parameters */ + sDU_item = proto_tree_add_text(ie_tree, tvb, *offset, 0, + "sDU Parameters"); + sDU_tree = proto_item_add_subtree(sDU_item, ett_ranap_sDU); + + /* create subtree for extension/optional/default bitmap */ + optionals_item = proto_tree_add_text(sDU_tree, tvb, *offset, 1, + "sDU_Parameters Extension/Optional/Default bitmap"); + optionals_tree = proto_item_add_subtree(optionals_item, ett_ranap_optionals); + + /* protocol_extension present ? */ + extension_present = extract_nbits(tvb, *offset, *bitoffset, 1); + proto_tree_add_uint_bits(optionals_tree, hf_ranap_ie_protocol_extension, tvb, + *offset, *bitoffset, 1, 0); + proceed_nbits(offset, bitoffset, 1); + + /* sDU_ErrorRatio present ? */ + sDU_ErrorRatio_present = extract_nbits(tvb, *offset, *bitoffset, 1); + proto_tree_add_uint_bits(optionals_tree, hf_ranap_sDU_ErrorRatio_present, tvb, + *offset, *bitoffset, 1, 0); + proceed_nbits(offset, bitoffset, 1); + + /* sDU_FormatInformationParameters present ? */ + sDU_FormatInformationParameters_present = extract_nbits(tvb, *offset, *bitoffset, 1); + proto_tree_add_uint_bits(optionals_tree, hf_ranap_sDU_FormatInformationParameters_present, tvb, + *offset, *bitoffset, 1, 0); + proceed_nbits(offset, bitoffset, 1); + + /* iE_Extensions present ? */ + iE_Extensions_present = extract_nbits(tvb, *offset, *bitoffset, 1); + proto_tree_add_uint_bits(optionals_tree, hf_ranap_iE_Extensions_present, tvb, + *offset, *bitoffset, 1, 0); + proceed_nbits(offset, bitoffset, 1); + + + /* sDU_ErrorRatio */ + if (sDU_ErrorRatio_present) + { + sDU_ErrorRatio_iE_Extensions_present = extract_nbits(tvb, *offset, *bitoffset, 1); + proceed_nbits(offset, bitoffset, 1); + + proto_tree_add_uint_bits(sDU_tree, hf_ranap_sDU_ErrorRatio_mantissa, tvb, *offset, + *bitoffset, 4, 1); + proceed_nbits(offset, bitoffset, 4); + + proto_tree_add_uint_bits(sDU_tree, hf_ranap_sDU_ErrorRatio_exponent, tvb, *offset, + *bitoffset, 3, 1); + proceed_nbits(offset, bitoffset, 3); + + if (sDU_ErrorRatio_iE_Extensions_present) + { + if ((ret=dissect_iE_Extension(tvb, sDU_tree, offset, bitoffset, "sDU_ErrorRatio")) != 0) + return (ret); + } + } + + /* residualBitErrorRatio */ + residualBitErrorRatio_iE_Extensions_present = extract_nbits(tvb, *offset, *bitoffset, 1); + proceed_nbits(offset, bitoffset, 1); + + proto_tree_add_uint_bits(sDU_tree, hf_ranap_residualBitErrorRatio_mantissa, tvb, *offset, + *bitoffset, 4, 1); + proceed_nbits(offset, bitoffset, 4); + + proto_tree_add_uint_bits(sDU_tree, hf_ranap_sDU_ErrorRatio_exponent, tvb, *offset, + *bitoffset, 3, 1); + proceed_nbits(offset, bitoffset, 3); + + + if (residualBitErrorRatio_iE_Extensions_present) + { + if ((ret=dissect_iE_Extension(tvb, sDU_tree, offset, bitoffset, "residualBitErrorRatio")) != 0) + return(ret); + } + + + /* deliveryOfErroneousSDU */ + proto_tree_add_uint_bits(sDU_tree, hf_ranap_deliveryOfErroneousSDU, tvb, *offset, + *bitoffset, 2, 0); + proceed_nbits(offset, bitoffset, 2); + + + /* sDU_FormatInformationParameters */ + if (sDU_FormatInformationParameters_present) + { + number_of_sDU_FormatInformationParameters = extract_nbits(tvb, *offset, *bitoffset, 6) + 1; + proceed_nbits(offset, bitoffset, 6); + + for (i=1; i<= number_of_sDU_FormatInformationParameters; i++) + { + /* create subtree for extension/optional/default bitmap */ + optionals_item = proto_tree_add_text(sDU_tree, tvb, *offset, 1, + "sDU_FormatInformationParameters Extension/Optional/Default bitmap"); + optionals_tree = proto_item_add_subtree(optionals_item, ett_ranap_optionals); + + /* protocol extension present ? */ + sDU_FormatInformationParameters_extension_present = + extract_nbits(tvb, *offset, *bitoffset, 1); + proto_tree_add_uint_bits(optionals_tree, hf_ranap_ie_protocol_extension, tvb, + *offset, *bitoffset, 1, 0); + proceed_nbits(offset, bitoffset, 1); + + /* subflowSDU_Size present ? */ + subflowSDU_Size_present = extract_nbits(tvb, *offset, *bitoffset, 1); + proto_tree_add_uint_bits(optionals_tree, hf_ranap_subflowSDU_Size_present, tvb, + *offset, *bitoffset, 1, 0); + proceed_nbits(offset, bitoffset, 1); + + /* rAB_SubflowCombinationBitRate present ? */ + rAB_SubflowCombinationBitRate_present = extract_nbits(tvb, *offset, *bitoffset, 1); + proto_tree_add_uint_bits(optionals_tree, hf_ranap_rAB_SubflowCombinationBitRate_present, tvb, + *offset, *bitoffset, 1, 0); + proceed_nbits(offset, bitoffset, 1); + + /* ie_Extension present ? */ + sDU_FormatInformationParameters_iE_Extensions_present = + extract_nbits(tvb, *offset, *bitoffset, 1); + proto_tree_add_uint_bits(optionals_tree, hf_ranap_iE_Extensions_present, tvb, + *offset, *bitoffset, 1, 0); + proceed_nbits(offset, bitoffset, 1); + + if (subflowSDU_Size_present) + { + allign(offset, bitoffset); + proto_tree_add_item(sDU_tree, hf_ranap_subflowSDU_Size, + tvb, *offset, subflowSDU_Size_LENGTH, FALSE); + offset += subflowSDU_Size_LENGTH; + } + + if (rAB_SubflowCombinationBitRate_present) + { + proto_tree_add_PERint32(sDU_tree, hf_ranap_rAB_SubflowCombinationBitRate, + tvb, *offset, *bitoffset, &length, 0); + proceed_perint32(offset, bitoffset, length); + } + + if (sDU_FormatInformationParameters_iE_Extensions_present) + { + if ((ret=dissect_iE_Extension(tvb, sDU_tree, offset, bitoffset, + "sDU_FormatInformationParameters" )) != 0) + return (ret); + } + } + } + + if (extension_present) + { + /* extended sequence */ + /* decoding is not supported */ + proto_tree_add_text(ie_tree, tvb, *offset, IE_PROTOCOL_EXTENSION_LENGTH, + "Protocol extension for sDU_FormatInformationParameters present, dissection not supported"); + return(-1); + } + + return (0); + +} + + +static int +dissect_rAB_Parameters(tvbuff_t *tvb, proto_tree *ie_tree, gint *offset, gint *bitoffset) +{ + guint8 tmp_byte; + proto_item *rab_item = NULL; + proto_tree *rab_tree = NULL; + proto_item *optionals_item = NULL; + proto_tree *optionals_tree = NULL; + proto_item *prio_item = NULL; + proto_tree *prio_tree = NULL; + int ret; + int extension_present; + int tmp_extension_present; + int guaranteedBitRate_present; + int transferDelay_present; + int trafficHandlingPriority_present; + int allocationOrRetentionPriority_present; + int sourceStatisticsDescriptor_present; + int relocationRequirement_present; + int iE_Extensions_present; + int tmp_iE_Extensions_present; + int i; + gint length; + + /* create subtree for rAB_Parameters */ + rab_item = proto_tree_add_text(ie_tree, tvb, *offset, 0, + "rAB_Parameters"); + rab_tree = proto_item_add_subtree(rab_item, ett_ranap_rAB_Parameters); + + /* create subtree for extension/optional/default bitmap */ + optionals_item = proto_tree_add_text(rab_tree, tvb, *offset, IE_PROTOCOL_EXTENSION_LENGTH, + "rAB_Parameters Extension/Optional/Default bitmap"); + optionals_tree = proto_item_add_subtree(optionals_item, ett_ranap_optionals); + + /* protocol extension present ? */ + extension_present = extract_nbits(tvb, *offset, *bitoffset, 1); + proto_tree_add_uint_bits(optionals_tree, hf_ranap_ie_protocol_extension, tvb, + *offset, *bitoffset, 1, 0); + proceed_nbits(offset, bitoffset, 1); + + /* guaranteedBitRate present ? */ + guaranteedBitRate_present = extract_nbits(tvb, *offset, *bitoffset, 1); + proto_tree_add_uint_bits(optionals_tree, hf_ranap_guaranteedBitRate_present, + tvb, *offset, *bitoffset, 1, 0); + proceed_nbits(offset, bitoffset, 1); + + /* transferDelay present ? */ + transferDelay_present = extract_nbits(tvb, *offset, *bitoffset, 1); + proto_tree_add_uint_bits(optionals_tree, hf_ranap_transferDelay_present, + tvb, *offset, *bitoffset, 1, 0); + proceed_nbits(offset, bitoffset, 1); + + /* trafficHandlingPriority present ? */ + trafficHandlingPriority_present = extract_nbits(tvb, *offset, *bitoffset, 1); + proto_tree_add_uint_bits(optionals_tree, hf_ranap_trafficHandlingPriority_present, + tvb, *offset, *bitoffset, 1, 0); + proceed_nbits(offset, bitoffset, 1); + + /* allocationOrRetentionPriority present ? */ + allocationOrRetentionPriority_present = extract_nbits(tvb, *offset, *bitoffset, 1); + proto_tree_add_uint_bits(optionals_tree, hf_ranap_allocationOrRetentionPriority_present, + tvb, *offset, *bitoffset, 1, 0); + proceed_nbits(offset, bitoffset, 1); + + /* sourceStatisticsDescriptor present ? */ + sourceStatisticsDescriptor_present = extract_nbits(tvb, *offset, *bitoffset, 1); + proto_tree_add_uint_bits(optionals_tree, hf_ranap_sourceStatisticsDescriptor_present, + tvb, *offset, *bitoffset, 1, 0); + proceed_nbits(offset, bitoffset, 1); + + /* relocationRequirement present ? */ + relocationRequirement_present = extract_nbits(tvb, *offset, *bitoffset, 1); + proto_tree_add_uint_bits(optionals_tree, hf_ranap_relocationRequirement_present, + tvb, *offset, *bitoffset, 1, 0); + proceed_nbits(offset, bitoffset, 1); + + /* iE-Extensions present ? */ + iE_Extensions_present = extract_nbits(tvb, *offset, *bitoffset, 1); + proto_tree_add_uint_bits(optionals_tree, hf_ranap_iE_Extensions_present, + tvb, *offset, *bitoffset, 1, 0); + proceed_nbits(offset, bitoffset, 1); + + + /* trafficClass */ + tmp_extension_present = extract_nbits(tvb, *offset, *bitoffset, 1); + proceed_nbits(offset, bitoffset, 1); + + proto_tree_add_uint_bits(rab_tree, hf_ranap_trafficClass, + tvb, *offset, *bitoffset, 2, 0); + proceed_nbits(offset, bitoffset, 2); + + if (tmp_extension_present) + { + /* decoding is not supported */ + proto_tree_add_text(rab_tree, tvb, *offset, IE_PROTOCOL_EXTENSION_LENGTH, + "Protocol extension for trafficClass present, dissection not supported"); + return(-1); + } + + + /* rAB-AsymmetryIndicator */ + tmp_extension_present = extract_nbits(tvb, *offset, *bitoffset, 1); + proceed_nbits(offset, bitoffset, 1); + + proto_tree_add_uint_bits(rab_tree, hf_ranap_rAB_AsymmetryIndicator, + tvb, *offset, *bitoffset, 2, 0); + proceed_nbits(offset, bitoffset, 2); + + if (tmp_extension_present) + { + /* decoding is not supported */ + proto_tree_add_text(rab_tree, tvb, *offset, IE_PROTOCOL_EXTENSION_LENGTH, + "Protocol extension for rAB-AsymmetryIndicator present, dissection not supported"); + return(-1); + } + + + /* maxBitrate */ + tmp_byte = extract_nbits(tvb, *offset, *bitoffset, 1) +1 ; /*sequence 1..2 */ + proceed_nbits(offset, bitoffset, 1); + + for (i=1; i<= tmp_byte; i++) + { + proto_tree_add_PERint32(rab_tree, hf_ranap_maxBitrate, + tvb, *offset, *bitoffset, &length, 1); + proceed_perint32(offset, bitoffset, length); + } + + + /* guaranteedBitRate */ + if (guaranteedBitRate_present) + { + tmp_byte = extract_nbits(tvb, *offset, *bitoffset, 1) +1 ; /*sequence 1..2 */ + proceed_nbits(offset, bitoffset, 1); + + for (i=1; i<= tmp_byte; i++) + { + proto_tree_add_PERint32(rab_tree, hf_ranap_guaranteedBitrate, + tvb, *offset, *bitoffset, &length, 0); + proceed_perint32(offset, bitoffset, length); + } + } + + /* deliveryOrder */ + proto_tree_add_uint_bits(rab_tree, hf_ranap_deliveryOrder, tvb, *offset, + *bitoffset, 1, 0); + proceed_nbits(offset, bitoffset, 1); + + + /* maxSDU-Size */ + allign(offset, bitoffset); + proto_tree_add_item(rab_tree, hf_ranap_maxSDU_Size, + tvb, *offset, maxSDU_Size_LENGTH, FALSE); + *offset += maxSDU_Size_LENGTH; + + /* sDU-Parameters */ + tmp_byte = extract_nbits(tvb, *offset, *bitoffset, 3) + 1; /*sequence 1..7 */ + proceed_nbits(offset, bitoffset, 3); + for (i=1; i<= tmp_byte; i++) + { + if ((ret=dissect_sDU_Parameters(tvb, rab_tree, offset, bitoffset))!=0) return(ret); + } + + /* transferDelay */ + if (transferDelay_present) + { + allign(offset, bitoffset); + proto_tree_add_item(rab_tree, hf_ranap_transferDelay, + tvb, *offset, transferDelay_LENGTH, FALSE); + *offset += transferDelay_LENGTH; + } + + + /* trafficHandlingPriority */ + if (trafficHandlingPriority_present) + { + proto_tree_add_uint_bits(rab_tree, hf_ranap_trafficHandlingPriority, tvb, *offset, + *bitoffset, 4, 0); + proceed_nbits(offset, bitoffset, 4); + } + + /* allocationOrRetentionPriority */ + if (allocationOrRetentionPriority_present) + { + /* create subtree for */ + prio_item = proto_tree_add_text(rab_tree, tvb, *offset, 0, + "allocationOrRetentionPriority"); + prio_tree = proto_item_add_subtree(prio_item, ett_ranap_allocationOrRetentionPriority); + + /* protocol extension present ? */ + tmp_extension_present = extract_nbits(tvb, *offset, *bitoffset, 1); + proceed_nbits(offset, bitoffset, 1); + + /* iE Extension present ? */ + tmp_iE_Extensions_present = extract_nbits(tvb, *offset, *bitoffset, 1); + proceed_nbits(offset, bitoffset, 1); + + /* allocationOrRetentionPriority */ + proto_tree_add_uint_bits(prio_tree, hf_ranap_priorityLevel, tvb, *offset, + *bitoffset, 4, 0); + proceed_nbits(offset, bitoffset, 4); + + /* pre-emptionCapability */ + proto_tree_add_uint_bits(prio_tree, hf_ranap_pre_emptionCapability, tvb, *offset, + *bitoffset, 1, 0); + proceed_nbits(offset, bitoffset, 1); + + /* pre-emptionVulnerability */ + proto_tree_add_uint_bits(prio_tree, hf_ranap_pre_emptionVulnerability, tvb, *offset, + *bitoffset, 1, 0); + proceed_nbits(offset, bitoffset, 1); + + /* queuingAllowed */ + proto_tree_add_uint_bits(prio_tree, hf_ranap_queuingAllowed, tvb, *offset, + *bitoffset, 1, 0); + proceed_nbits(offset, bitoffset, 1); + + if (tmp_iE_Extensions_present) + { + if ((ret=dissect_iE_Extension(tvb, prio_tree, offset, bitoffset, + "AllocationOrRetentionPriority")) != 0) + return (ret); + } + + if (tmp_extension_present) + { + /* decoding is not supported */ + proto_tree_add_text(prio_tree, tvb, *offset, IE_PROTOCOL_EXTENSION_LENGTH, + "Protocol extension for rAB-allocationOrRetentionPriority present, dissection not supported"); + return(-1); + } + } + + /* sourceStatisticsDescriptor */ + if (sourceStatisticsDescriptor_present) + { + /* protocol extension */ + tmp_extension_present = extract_nbits(tvb, *offset, *bitoffset, 1); + proceed_nbits(offset, bitoffset, 1); + + if (tmp_extension_present) + { + /* decoding is not supported */ + proto_tree_add_text(prio_tree, tvb, *offset, IE_PROTOCOL_EXTENSION_LENGTH, + "Protocol extension for sourceStatisticsDescriptor present, dissection not supported"); + return(-1); + } + + proto_tree_add_uint_bits(rab_tree, hf_ranap_sourceStatisticsDescriptor, tvb, *offset, + *bitoffset, 1, 0); + proceed_nbits(offset, bitoffset, 1); + } + + /* relocationRequirement */ + if (relocationRequirement_present) + { + /* protocol extension */ + tmp_extension_present = extract_nbits(tvb, *offset, *bitoffset, 1); + proceed_nbits(offset, bitoffset, 1); + + if (tmp_extension_present) + { + /* decoding is not supported */ + proto_tree_add_text(prio_tree, tvb, *offset, IE_PROTOCOL_EXTENSION_LENGTH, + "Protocol extension for relocationRequirement present, dissection not supported"); + return(-1); + } + + proto_tree_add_uint_bits(rab_tree, hf_ranap_relocationRequirement, tvb, *offset, + *bitoffset, 1, 0); + proceed_nbits(offset, bitoffset, 1); + } + + + /* iE-Extensions */ + if (iE_Extensions_present) + { + if ((ret=dissect_iE_Extension(tvb, rab_tree, offset, bitoffset, "rAB_Parameters" )) != 0 ) + return (ret); + } + + /* extended */ + if (extension_present) + { + /* decoding is not supported */ + proto_tree_add_text(rab_tree, tvb, *offset, IE_PROTOCOL_EXTENSION_LENGTH, + "Protocol extension for rAB_Parameters present, dissection not supported"); + return(-1); + } + + return(0); +} + + + +static int +dissect_TransportLayerAddress(tvbuff_t *tvb, proto_tree *ie_tree, gint *offset, gint *bitoffset) +{ + gint extension_present; + gint str_length; + + extension_present = extract_nbits(tvb, *offset, *bitoffset, 1); + proceed_nbits(offset, bitoffset, 1); + if (extension_present) + { + /* extended integer */ + proto_tree_add_text(ie_tree, tvb, *offset, 0, + "extension present for TransportLayerAddress, dissection not supported"); + return (-1); + } + + /* extract and add length of transportLayerAddress bitstring */ + str_length = extract_nbits(tvb, *offset, *bitoffset, 8) + 1; + proto_tree_add_uint_bits(ie_tree, hf_ranap_transportLayerAddress_length, + tvb, *offset, *bitoffset, 8, 1); + proceed_nbits(offset, bitoffset, 8); + allign(offset, bitoffset); + + /* add transportLayerAddress */ + proto_tree_add_bitstring(ie_tree, hf_ranap_transportLayerAddress, tvb, *offset, + *bitoffset, str_length); + proceed_nbits(offset, bitoffset, str_length); + + return (0); +} + + + +static int +dissect_iuTransportAssociation(tvbuff_t *tvb, proto_tree *ie_tree, gint *offset, gint *bitoffset) +{ + guint extension_present; + guint choice_value; + + /* extension present ? */ + extension_present = extract_nbits(tvb, *offset, *bitoffset, 1); + if (extension_present) + { + /* extended choice */ + proto_tree_add_text(ie_tree, tvb, *offset, 0, + "extension present for IuTransportAssociation, dissection not supported"); + return (-1); + } + proceed_nbits(offset, bitoffset, 1); + + /* choice */ + choice_value = extract_nbits(tvb, *offset, *bitoffset, 1); + proceed_nbits(offset, bitoffset, 1); + allign(offset, bitoffset); + if (choice_value == 0) + { + /* gTP-TEI */ + proto_tree_add_item(ie_tree, hf_ranap_gTP_TEI, tvb, *offset, 4, FALSE); + *offset += 4; + } + else + { + /* bindingID */ + proto_tree_add_item(ie_tree, hf_ranap_bindingID, tvb, *offset, 4, FALSE); + *offset += 4; + } + + return (0); +} + + +static int +dissect_transportLayerInformation(tvbuff_t *tvb, proto_tree *ie_tree, gint *offset, gint *bitoffset) +{ + proto_item *optionals_item = NULL; + proto_tree *optionals_tree = NULL; + int extension_present; + int iE_Extensions_present; + int ret; + + /* create subtree for extension/optional/default bitmap */ + optionals_item = proto_tree_add_text(ie_tree, tvb, *offset, IE_PROTOCOL_EXTENSION_LENGTH, + "TransportLayerInformation Extension/Optional/Default bitmap"); + optionals_tree = proto_item_add_subtree(optionals_item, ett_ranap_optionals); + + + /* protocol extension present ? */ + extension_present = extract_nbits(tvb, *offset, *bitoffset, 1); + proto_tree_add_uint_bits(optionals_tree, hf_ranap_ie_protocol_extension, tvb, + *offset, *bitoffset, 1, 0); + proceed_nbits(offset, bitoffset, 1); + + /* iE-Extensions present ? */ + iE_Extensions_present = extract_nbits(tvb, *offset, *bitoffset, 1); + proto_tree_add_uint_bits(optionals_tree, hf_ranap_iE_Extensions_present, + tvb, *offset, *bitoffset, 1, 0); + proceed_nbits(offset, bitoffset, 1); + + + /* transportLayerAddress */ + if ((ret=dissect_TransportLayerAddress(tvb, ie_tree, offset, bitoffset)) != 0) + return (ret); + + /* iuTransportAssociation */ + if ((ret=dissect_iuTransportAssociation(tvb, ie_tree, offset, bitoffset)) != 0) + return (ret); + + /* iE-Extensions */ + if (iE_Extensions_present) + { + if ((ret=dissect_iE_Extension(tvb, ie_tree, offset, bitoffset, "TransportLayerInformation" )) != 0 ) + return (ret); + } + + /* protocol extension */ + if (extension_present) + { + /* extended sequence */ + proto_tree_add_text(ie_tree, tvb, *offset, 0, + "extension present for TransportLayerInformation, dissection not supported"); + return (-1); + } + + return(0); +} + + +static int +dissect_dataVolumeList (tvbuff_t *tvb, proto_tree *ie_tree, gint *offset, gint *bitoffset, char *parname) +{ + proto_item *optionals_item = NULL; + proto_tree *optionals_tree = NULL; + gint extension_present; + gint dataVolumeReference_present; + gint iE_Extensions_present; + gint number_vol; + gint length; + gint i; + int ret; + + /* number of volumes */ + number_vol = extract_nbits(tvb, *offset, *bitoffset, 1) + 1; + proceed_nbits(offset, bitoffset, 1); + + for (i=1; i<=number_vol; i++) + { + /* create subtree for extension/optional/default bitmap */ + optionals_item = proto_tree_add_text(ie_tree, tvb, *offset, 1, + "%d. %s Extension/Optional/Default bitmap", + i, parname); + optionals_tree = proto_item_add_subtree(optionals_item, ett_ranap_optionals); + + /* protocol_extension present ? */ + extension_present = extract_nbits(tvb, *offset, *bitoffset, 1); + proto_tree_add_uint_bits(optionals_tree, hf_ranap_ie_protocol_extension, tvb, + *offset, *bitoffset, 1, 0); + proceed_nbits(offset, bitoffset, 1); + + /* dataVolumeReference present ? */ + dataVolumeReference_present = extract_nbits(tvb, *offset, *bitoffset, 1); + proto_tree_add_uint_bits(optionals_tree, hf_ranap_dataVolumeReference_present, tvb, + *offset, *bitoffset, 1, 0); + proceed_nbits(offset, bitoffset, 1); + + /* iE_Extensions present ? */ + iE_Extensions_present = extract_nbits(tvb, *offset, *bitoffset, 1); + proto_tree_add_uint_bits(optionals_tree, hf_ranap_iE_Extensions_present, tvb, + *offset, *bitoffset, 1, 0); + proceed_nbits(offset, bitoffset, 1); + + + /* UnsuccessfullyTransmittedDataVolume */ + proto_tree_add_PERint32(ie_tree, hf_ranap_dl_UnsuccessfullyTransmittedDataVolume, + tvb, *offset, *bitoffset, &length, 0); + proceed_perint32(offset, bitoffset, length); + + /* DataVolumeReference */ + if (dataVolumeReference_present) + { + proto_tree_add_uint_bits(ie_tree, hf_ranap_dataVolumeReference, tvb, + *offset, *bitoffset, 8, 0); + proceed_nbits(offset, bitoffset, 8); + } + + /* iE-Extensions */ + if (iE_Extensions_present) + { + if ((ret=dissect_iE_Extension(tvb, ie_tree, offset, bitoffset, "dl-dataVolumes" )) != 0) + return(ret); + } + + /* protocol extended */ + if (extension_present) + { + /* extended sequence */ + /* decoding is not supported */ + proto_tree_add_text(ie_tree, tvb, *offset, IE_PROTOCOL_EXTENSION_LENGTH, + "Protocol extension for dl-dataVolumes present, dissection not supported"); + return(-1); + } + } + + return (0); + +} + +static int +dissect_cause(tvbuff_t *tvb, proto_tree *ie_tree, gint *offset, gint *bitoffset) +{ + gint extension_present; + int cause_choice; + + /* protocol extension present ? */ + extension_present = extract_nbits(tvb, *offset, *bitoffset, 1); + proceed_nbits(offset, bitoffset, 1); + if (extension_present) + { + /* choice extension present */ + proto_tree_add_text(ie_tree, tvb, *offset, 0, + "extension present for cause, dissection not supported"); + return (-1); + } + cause_choice = extract_nbits(tvb, *offset, *bitoffset, 3); + proto_tree_add_uint_bits(ie_tree, hf_ranap_cause_choice, + tvb, *offset, *bitoffset, 3, 0); + proceed_nbits(offset, bitoffset, 3); + + switch (cause_choice) + { + case CC_CauseRadioNetwork: + proto_tree_add_uint_bits(ie_tree, hf_ranap_cause_value, + tvb, *offset, *bitoffset, 6, 1); + proceed_nbits(offset, bitoffset, 6); + break; + case CC_CauseTransmissionNetwork: + proto_tree_add_uint_bits(ie_tree, hf_ranap_cause_value, + tvb, *offset, *bitoffset, 4, 65); + proceed_nbits(offset, bitoffset, 4); + break; + case CC_CauseNAS: + proto_tree_add_uint_bits(ie_tree, hf_ranap_cause_value, + tvb, *offset, *bitoffset, 4, 81); + proceed_nbits(offset, bitoffset, 4); + break; + case CC_CauseProtocol: + proto_tree_add_uint_bits(ie_tree, hf_ranap_cause_value, + tvb, *offset, *bitoffset, 4, 97); + proceed_nbits(offset, bitoffset, 4); + case CC_CauseMisc: + proto_tree_add_uint_bits(ie_tree, hf_ranap_cause_value, + tvb, *offset, *bitoffset, 4, 113); + proceed_nbits(offset, bitoffset, 4); + break; + case CC_CauseNon_Standard: + proto_tree_add_uint_bits(ie_tree, hf_ranap_cause_value, + tvb, *offset, *bitoffset, 7, 129); + proceed_nbits(offset, bitoffset, 7); + break; + default: + proto_tree_add_text(ie_tree, tvb, *offset, 0, + "unexpected cause choice value, dissection not supported"); + return(-1); + } + return(0); +} + + +static int +dissect_iEsCriticalityDiagnostics(tvbuff_t *tvb, proto_tree *ie_tree, gint *offset, gint *bitoffset) +{ + proto_item *diag_item = NULL; + proto_tree *diag_tree = NULL; + proto_item *optionals_item = NULL; + proto_tree *optionals_tree = NULL; + int extension_present; + int repetitionNumber_present; + int iE_Extensions_present; + int num_of_errors; + int i; + + allign(offset, bitoffset); + num_of_errors = extract_nbits(tvb, *offset, *bitoffset, 8) + 1; + proto_tree_add_uint_bits(ie_tree, hf_ranap_num_of_CriticalityDiagnostics_IEs, tvb, + *offset, *bitoffset, 8, 1); + proceed_nbits(offset, bitoffset, 8); + + for ( i= 1; i <= num_of_errors; i++) + { + /* add subtree for CriticalityDiagnostics-IE */ + diag_item = proto_tree_add_text(ie_tree, tvb, *offset, 0, + "%d. CriticalityDiagnostics-IE", i); + diag_tree = proto_item_add_subtree(diag_item, ett_ranap_CriticalityDiagnostics_IE); + + /* create subtree for extension/optional/default bitmap */ + optionals_item = proto_tree_add_text(diag_tree, tvb, *offset, 1, + "CriticalityDiagnostics-IE Extension/Optional/Default bitmap"); + optionals_tree = proto_item_add_subtree(optionals_item, ett_ranap_optionals); + + /* protocol_extension present ? */ + extension_present = extract_nbits(tvb, *offset, *bitoffset, 1); + proto_tree_add_uint_bits(optionals_tree, hf_ranap_ie_protocol_extension, tvb, + *offset, *bitoffset, 1, 0); + proceed_nbits(offset, bitoffset, 1); + + /* repetitionNumber present ? */ + repetitionNumber_present = extract_nbits(tvb, *offset, *bitoffset, 1); + proto_tree_add_uint_bits(optionals_tree, hf_ranap_repetitionNumber_present, tvb, + *offset, *bitoffset, 1, 0); + proceed_nbits(offset, bitoffset, 1); + + /* iE_Extensions present ? */ + iE_Extensions_present = extract_nbits(tvb, *offset, *bitoffset, 1); + proto_tree_add_uint_bits(optionals_tree, hf_ranap_iE_Extensions_present, + tvb, *offset, *bitoffset, 1, 0); + proceed_nbits(offset, bitoffset, 1); + + /* iECriticality */ + proto_tree_add_uint_bits(diag_tree, hf_ranap_iECriticality, + tvb, *offset, *bitoffset, 2, 0); + proceed_nbits(offset, bitoffset, 2); + + /* iE-ID */ + allign(offset, bitoffset); + proto_tree_add_item(diag_tree, hf_ranap_ie_ie_id, tvb, + *offset, IE_ID_LENGTH, FALSE); + *offset += IE_ID_LENGTH; + + /* repetitionNumber */ + if (repetitionNumber_present) + { + allign(offset, bitoffset); + proto_tree_add_uint_bits(diag_tree, hf_ranap_repetitionNumber, + tvb, *offset, *bitoffset, 8, 1); + proceed_nbits(offset, bitoffset, 8); + } + + /* iE-Extensions */ + if (iE_Extensions_present) + { + return(dissect_iE_Extension(tvb, diag_tree, offset, bitoffset, "CriticalityDiagnostics-IE")); + } + + + /* protocol extended */ + if (extension_present) + { + /* extended sequence */ + /* decoding is not supported */ + proto_tree_add_text(diag_tree, tvb, *offset, IE_PROTOCOL_EXTENSION_LENGTH, + "Protocol extension for CriticalityDiagnostics-IE present, dissection not supported"); + return(-1); + } + } + + return(0); +} + + + +/*****************************************************************************/ +/* */ +/* Dissecting Functions for IEs */ +/* */ +/*****************************************************************************/ + +static int +dissect_IE_RAB_ID(tvbuff_t *tvb, proto_tree *ie_tree) +{ + if (ie_tree) + { + proto_tree_add_item(ie_tree, hf_ranap_rab_id, tvb, + 0, RAB_ID_LENGTH, FALSE); + } + return(0); +} + + +static int +dissect_IE_RAC(tvbuff_t *tvb, proto_tree *ie_tree) +{ + if (ie_tree) + { + proto_tree_add_item(ie_tree, hf_ranap_rac, tvb, + 0, RAC_LENGTH, FALSE); + } + return(0); +} + + +static int +dissect_IE_LAI(tvbuff_t *tvb, proto_tree *ie_tree) +{ + proto_item *optionals_item = NULL; + proto_tree *optionals_tree = NULL; + int iE_Extensions_present; + gint offset = 0; + gint bitoffset = 0; + int ret; + + if (ie_tree) + { + /* create subtree for extension/optional/default bitmap */ + optionals_item = proto_tree_add_text(ie_tree, tvb, offset, 1, + "LAI Extension/Optional/Default bitmap"); + optionals_tree = proto_item_add_subtree(optionals_item, ett_ranap_optionals); + + /* iE_Extensions_present present ? */ + iE_Extensions_present = extract_nbits(tvb, offset, bitoffset, 1); + proto_tree_add_uint_bits(optionals_tree, hf_ranap_iE_Extensions_present, tvb, + offset, bitoffset, 1, 0); + proceed_nbits(&offset, &bitoffset, 1); + + /* plmn_id */ + allign(&offset, &bitoffset); + proto_tree_add_item(ie_tree, hf_ranap_plmn_id, tvb, + offset, PLMN_ID_LENGTH, FALSE); + offset += PLMN_ID_LENGTH; + + /* lac */ + proto_tree_add_item(ie_tree, hf_ranap_lac, tvb, + offset, LAC_LENGTH, FALSE); + offset += LAC_LENGTH; + + /* iE_Extensions */ + if (iE_Extensions_present) + { + if ((ret=dissect_iE_Extension(tvb, ie_tree, &offset, &bitoffset, "LAI")) != 0) + return (ret); + } + } + return(0); +} + + +static int +dissect_IE_GlobalRNC_ID(tvbuff_t *tvb, proto_tree *ie_tree) +{ + gint offset = 0; + + if (ie_tree) + { + /* plmn_id */ + proto_tree_add_item(ie_tree, hf_ranap_plmn_id, tvb, + offset, PLMN_ID_LENGTH, FALSE); + offset += PLMN_ID_LENGTH; + + /* RNC ID */ + proto_tree_add_item(ie_tree, hf_ranap_RNC_ID, tvb, offset, 2, FALSE); + offset += 2; + } + + return(0); +} + + +static int +dissect_IE_SAI(tvbuff_t *tvb, proto_tree *ie_tree) +{ + proto_item *optionals_item = NULL; + proto_tree *optionals_tree = NULL; + int iE_Extensions_present; + gint offset = 0; + gint bitoffset = 0; + int ret; + + if (ie_tree) + { + /* create subtree for extension/optional/default bitmap */ + optionals_item = proto_tree_add_text(ie_tree, tvb, offset, 1, + "SAI Extension/Optional/Default bitmap"); + optionals_tree = proto_item_add_subtree(optionals_item, ett_ranap_optionals); + + /* iE_Extensions_present present ? */ + iE_Extensions_present = extract_nbits(tvb, offset, bitoffset, 1); + proto_tree_add_uint_bits(optionals_tree, hf_ranap_iE_Extensions_present, tvb, + offset, bitoffset, 1, 0); + proceed_nbits(&offset, &bitoffset, 1); + + /* plmn_id */ + allign(&offset, &bitoffset); + proto_tree_add_item(ie_tree, hf_ranap_plmn_id, tvb, + offset, PLMN_ID_LENGTH, FALSE); + offset += PLMN_ID_LENGTH; + + /* lac */ + proto_tree_add_item(ie_tree, hf_ranap_lac, tvb, + offset, LAC_LENGTH, FALSE); + offset += LAC_LENGTH; + + /* sac */ + proto_tree_add_item(ie_tree, hf_ranap_sac, tvb, + offset, SAC_LENGTH, FALSE); + offset += SAC_LENGTH; + + /* iE_Extensions */ + if (iE_Extensions_present) + { + if ((ret=dissect_iE_Extension(tvb, ie_tree, &offset, &bitoffset, "SAI")) != 0) + return (ret); + } + } + return(0); +} + + +static int +dissect_IE_NAS_PDU(tvbuff_t *tvb, proto_tree *ie_tree) +{ + tvbuff_t *next_tvb; + gint length; + gint length_size; + + if (extract_length(tvb, 0, &length, &length_size) != 0) + { + if (ie_tree) + { + /* decoding is not supported */ + proto_tree_add_text(ie_tree, tvb, 0, + 2, "Number of Octets greater than 0x3FFF, dissection not supported"); + } + return(-1); + } + + if (ie_tree) + { + /* NAS - PDU length */ + proto_tree_add_item(ie_tree, hf_ranap_nas_pdu_length, tvb, + 0, length_size, FALSE); + } + + if (ie_tree) + { + /* NAS - PDU */ + proto_tree_add_item(ie_tree, hf_ranap_nas_pdu, tvb, + length_size, length, FALSE); + } + + /* call NAS dissector */ + next_tvb = tvb_new_subset(tvb, length_size, length, length); + + if (dissector_try_port(nas_pdu_dissector_table, 0x1, next_tvb, g_pinfo, g_tree)) return(0); + return(0); +} + + +static int +dissect_IE_CN_DomainIndicator(tvbuff_t *tvb, proto_tree *ie_tree) +{ + gint offset = 0; + gint bitoffset = 0; + + if (ie_tree) + { + proto_tree_add_uint_bits(ie_tree, hf_ranap_CN_DomainIndicator, tvb, + offset, bitoffset, 1, 0); + } + return(0); +} + + +static int +dissect_IE_IuSigConId(tvbuff_t *tvb, proto_tree *ie_tree) +{ + guint32 value; + + if (ie_tree) + { + value = tvb_get_ntoh24(tvb, 0); + proto_tree_add_uint(ie_tree, hf_ranap_IuSigConId, + tvb, 0, 3, value); + + } + return(0); +} + + +static int +dissect_IE_SAPI(tvbuff_t *tvb, proto_tree *ie_tree) +{ + gint offset = 0; + gint bitoffset = 0; + int extension_present; + + if (ie_tree) + { + /* protocol_extension present ? */ + extension_present = extract_nbits(tvb, offset, bitoffset, 1); + proceed_nbits(&offset, &bitoffset, 1); + + if (extension_present) + { + /* extended enum */ + /* decoding is not supported */ + proto_tree_add_text(ie_tree, tvb, offset, IE_PROTOCOL_EXTENSION_LENGTH, + "Protocol extension for IE_SAPI present, dissection not supported"); + return(-1); + } + + /* SAPI */ + proto_tree_add_uint_bits(ie_tree, hf_ranap_SAPI, tvb, + offset, bitoffset, 1, 0); + } + return(0); +} + + +static int +dissect_IE_TransportLayerAddress(tvbuff_t *tvb, proto_tree *ie_tree) +{ + gint offset = 0; + gint bitoffset = 0; + + if (ie_tree) + { + return(dissect_TransportLayerAddress(tvb, ie_tree, &offset, &bitoffset)); + } + return(0); +} + + +static int +dissect_IE_IuTransportAssociation(tvbuff_t *tvb, proto_tree *ie_tree) +{ + gint offset = 0; + gint bitoffset = 0; + + if (ie_tree) + { + return(dissect_iuTransportAssociation(tvb, ie_tree, &offset, &bitoffset)); + } + return(0); +} + + +static int +dissect_IE_Cause(tvbuff_t *tvb, proto_tree *ie_tree) +{ + gint offset = 0; + gint bitoffset = 0; + + if (ie_tree) + { + return(dissect_cause(tvb, ie_tree, &offset, &bitoffset)); + } + return(0); +} + + +static int +dissect_IE_RAB_ReleasedItem_IuRelComp(tvbuff_t *tvb, proto_tree *ie_tree) +{ + proto_item *optionals_item = NULL; + proto_tree *optionals_tree = NULL; + int extension_present; + int dl_GTP_PDU_SequenceNumber_present; + int ul_GTP_PDU_SequenceNumber_present; + int iE_Extensions_present; + gint offset = 0; + gint bitoffset = 0; + int ret; + + if (ie_tree) + { + /* create subtree for extension/optional/default bitmap */ + optionals_item = proto_tree_add_text(ie_tree, tvb, offset, 1, + "RAB_ReleasedItem_IuRelComp Extension/Optional/Default bitmap"); + optionals_tree = proto_item_add_subtree(optionals_item, ett_ranap_optionals); + + /* protocol_extension present ? */ + extension_present = extract_nbits(tvb, offset, bitoffset, 1); + proto_tree_add_uint_bits(optionals_tree, hf_ranap_ie_protocol_extension, tvb, + offset, bitoffset, 1, 0); + proceed_nbits(&offset, &bitoffset, 1); + + /* dl_GTP_PDU_SequenceNumber present ? */ + dl_GTP_PDU_SequenceNumber_present = extract_nbits(tvb, offset, bitoffset, 1); + proto_tree_add_uint_bits(optionals_tree, hf_ranap_dl_GTP_PDU_SequenceNumber_present, tvb, + offset, bitoffset, 1, 0); + proceed_nbits(&offset, &bitoffset, 1); + + /* ul_GTP_PDU_SequenceNumber present ? */ + ul_GTP_PDU_SequenceNumber_present = extract_nbits(tvb, offset, bitoffset, 1); + proto_tree_add_uint_bits(optionals_tree, hf_ranap_ul_GTP_PDU_SequenceNumber_present, tvb, + offset, bitoffset, 1, 0); + proceed_nbits(&offset, &bitoffset, 1); + + /* iE_Extensions_present present ? */ + iE_Extensions_present = extract_nbits(tvb, offset, bitoffset, 1); + proto_tree_add_uint_bits(optionals_tree, hf_ranap_iE_Extensions_present, tvb, + offset, bitoffset, 1, 0); + proceed_nbits(&offset, &bitoffset, 1); + + + /* rAB-ID */ + proto_tree_add_uint_bits(ie_tree, hf_ranap_rab_id, + tvb, offset, bitoffset, 8, 0); + proceed_nbits(&offset, &bitoffset, 8); + + /* dl-GTP-PDU-SequenceNumber */ + if (dl_GTP_PDU_SequenceNumber_present) + { + allign(&offset, &bitoffset); + proto_tree_add_item(ie_tree, hf_ranap_dl_GTP_PDU_SequenceNumber, tvb, offset, 2, FALSE); + offset += 2; + } + + /* ul-GTP-PDU-SequenceNumber */ + if (ul_GTP_PDU_SequenceNumber_present) + { + allign(&offset, &bitoffset); + proto_tree_add_item(ie_tree, hf_ranap_ul_GTP_PDU_SequenceNumber, tvb, offset, 2, FALSE); + offset += 2; + } + + /* iE-Extensions */ + if (iE_Extensions_present) + { + if ((ret=dissect_iE_Extension(tvb, ie_tree, &offset, &bitoffset, "RAB_ReleasedItem_IuRelComp")) != 0) + return (ret); + } + + /* protocol extended */ + if (extension_present) + { + /* extended sequence */ + /* decoding is not supported */ + proto_tree_add_text(ie_tree, tvb, offset, IE_PROTOCOL_EXTENSION_LENGTH, + "Protocol extension for RAB_ReleasedItem_IuRelComp present, dissection not supported"); + return(-1); + } + } + return(0); +} + + +static int +dissect_IE_RAB_DataVolumeReportItem(tvbuff_t *tvb, proto_tree *ie_tree) +{ + proto_item *optionals_item = NULL; + proto_tree *optionals_tree = NULL; + int extension_present; + int dl_UnsuccessfullyTransmittedDataVolume_present; + int iE_Extensions_present; + gint offset = 0; + gint bitoffset = 0; + int ret; + + if (ie_tree) + { + /* create subtree for extension/optional/default bitmap */ + optionals_item = proto_tree_add_text(ie_tree, tvb, offset, 1, + "RAB_DataVolumeReportItem Extension/Optional/Default bitmap"); + optionals_tree = proto_item_add_subtree(optionals_item, ett_ranap_optionals); + + /* protocol_extension present ? */ + extension_present = extract_nbits(tvb, offset, bitoffset, 1); + proto_tree_add_uint_bits(optionals_tree, hf_ranap_ie_protocol_extension, tvb, + offset, bitoffset, 1, 0); + proceed_nbits(&offset, &bitoffset, 1); + + /* dl_UnsuccessfullyTransmittedDataVolume present ? */ + dl_UnsuccessfullyTransmittedDataVolume_present = extract_nbits(tvb, offset, bitoffset, 1); + proto_tree_add_uint_bits(optionals_tree, hf_ranap_dl_UnsuccessfullyTransmittedDataVolume_present, tvb, + offset, bitoffset, 1, 0); + proceed_nbits(&offset, &bitoffset, 1); + + /* iE_Extensions_present present ? */ + iE_Extensions_present = extract_nbits(tvb, offset, bitoffset, 1); + proto_tree_add_uint_bits(optionals_tree, hf_ranap_iE_Extensions_present, tvb, + offset, bitoffset, 1, 0); + proceed_nbits(&offset, &bitoffset, 1); + + + /* rAB-ID */ + proto_tree_add_uint_bits(ie_tree, hf_ranap_rab_id, + tvb, offset, bitoffset, 8, 0); + proceed_nbits(&offset, &bitoffset, 8); + + /* dl_UnsuccessfullyTransmittedDataVolume */ + if (dl_UnsuccessfullyTransmittedDataVolume_present) + { + + if ((ret = dissect_dataVolumeList(tvb, ie_tree, &offset, &bitoffset, + "dl_UnsuccessfullyTransmittedDataVolume")) != 0) + return (ret); + } + + /* iE-Extensions */ + if (iE_Extensions_present) + { + if ((ret=dissect_iE_Extension(tvb, ie_tree, &offset, &bitoffset, "IE_RAB_DataVolumeReportItem")) != 0) + return (ret); + } + + /* protocol extended */ + if (extension_present) + { + /* extended enum */ + /* decoding is not supported */ + proto_tree_add_text(ie_tree, tvb, offset, IE_PROTOCOL_EXTENSION_LENGTH, + "Protocol extension for IE_RAB_DataVolumeReportItem present, dissection not supported"); + return(-1); + } + } + return(0); +} + + +static int +dissect_IE_RAB_SetupOrModifyItemSecond(tvbuff_t *tvb, proto_tree *ie_tree) +{ + proto_item *optionals_item = NULL; + proto_tree *optionals_tree = NULL; + int extension_present; + int tmp_extension; + int pDP_TypeInformation_present; + int dataVolumeReportingIndication_present; + int dl_GTP_PDU_SequenceNumber_present; + int ul_GTP_PDU_SequenceNumber_present; + int dl_N_PDU_SequenceNumber_present; + int ul_N_PDU_SequenceNumber_present; + int iE_Extensions_present; + gint offset = 0; + gint bitoffset = 0; + gint8 tmp_byte; + gint i; + int ret; + + if (ie_tree) + { + /* create subtree for extension/optional/default bitmap */ + optionals_item = proto_tree_add_text(ie_tree, tvb, offset, 1, + "SetupOrModifyItemSecond Extension/Optional/Default bitmap"); + optionals_tree = proto_item_add_subtree(optionals_item, ett_ranap_optionals); + + /* protocol_extension present ? */ + extension_present = extract_nbits(tvb, offset, bitoffset, 1); + proto_tree_add_uint_bits(optionals_tree, hf_ranap_ie_protocol_extension, tvb, + offset, bitoffset, 1, 0); + proceed_nbits(&offset, &bitoffset, 1); + + /* pDP_TypeInformation present ? */ + pDP_TypeInformation_present = extract_nbits(tvb, offset, bitoffset, 1); + proto_tree_add_uint_bits(optionals_tree, hf_ranap_pDP_TypeInformation_present, tvb, + offset, bitoffset, 1, 0); + proceed_nbits(&offset, &bitoffset, 1); + + /* dataVolumeReportingIndication present ? */ + dataVolumeReportingIndication_present = extract_nbits(tvb, offset, bitoffset, 1); + proto_tree_add_uint_bits(optionals_tree, hf_ranap_dataVolumeReportingIndication_present, tvb, + offset, bitoffset, 1, 0); + proceed_nbits(&offset, &bitoffset, 1); + + /* dl_GTP_PDU_SequenceNumber present present ? */ + dl_GTP_PDU_SequenceNumber_present = extract_nbits(tvb, offset, bitoffset, 1); + proto_tree_add_uint_bits(optionals_tree, hf_ranap_dl_GTP_PDU_SequenceNumber_present, tvb, + offset, bitoffset, 1, 0); + proceed_nbits(&offset, &bitoffset, 1); + + + /* ul_GTP_PDU_SequenceNumber present ? */ + ul_GTP_PDU_SequenceNumber_present = extract_nbits(tvb, offset, bitoffset, 1); + proto_tree_add_uint_bits(optionals_tree, hf_ranap_ul_GTP_PDU_SequenceNumber_present, tvb, + offset, bitoffset, 1, 0); + proceed_nbits(&offset, &bitoffset, 1); + + /* dl_N_PDU_SequenceNumber present ? */ + dl_N_PDU_SequenceNumber_present = extract_nbits(tvb, offset, bitoffset, 1); + proto_tree_add_uint_bits(optionals_tree, hf_ranap_dl_N_PDU_SequenceNumber_present, tvb, + offset, bitoffset, 1, 0); + proceed_nbits(&offset, &bitoffset, 1); + + /* ul_N_PDU_SequenceNumber present ? */ + ul_N_PDU_SequenceNumber_present = extract_nbits(tvb, offset, bitoffset, 1); + proto_tree_add_uint_bits(optionals_tree, hf_ranap_ul_N_PDU_SequenceNumber_present, tvb, + offset, bitoffset, 1, 0); + proceed_nbits(&offset, &bitoffset, 1); + + /* iE_Extensions present ? */ + iE_Extensions_present = extract_nbits(tvb, offset, bitoffset, 1); + proto_tree_add_uint_bits(optionals_tree, hf_ranap_iE_Extensions_present, tvb, + offset, bitoffset, 1, 0); + proceed_nbits(&offset, &bitoffset, 1); + + /* pDP-TypeInformation */ + if (pDP_TypeInformation_present) + { + tmp_byte = extract_nbits(tvb, offset, bitoffset, 1) + 1; /* Sequence 1..2 */ + proceed_nbits(&offset, &bitoffset, 1); + for (i=1; i<=tmp_byte; i++) + { + tmp_extension = extract_nbits(tvb, offset, bitoffset, 1); + proceed_nbits(&offset, &bitoffset, 1); + if (tmp_extension != 0) + { + /* extended enum */ + /* decoding is not supported */ + proto_tree_add_text(ie_tree, tvb, offset, IE_PROTOCOL_EXTENSION_LENGTH, + "Protocol extension for PDP-Type present, dissection not supported"); + return(-1); + } + + proto_tree_add_uint_bits(ie_tree, hf_ranap_PDP_Type, tvb, + offset, bitoffset, 3, 0); + proceed_nbits(&offset, &bitoffset, 3); + } + } + + /* dataVolumeReportingIndication */ + if (dataVolumeReportingIndication_present) + { + proto_tree_add_uint_bits(ie_tree, hf_ranap_dataVolumeReportingIndication, tvb, + offset, bitoffset, 1, 0); + proceed_nbits(&offset, &bitoffset, 1); + } + + /* dl-GTP-PDU-SequenceNumber */ + if (dl_GTP_PDU_SequenceNumber_present) + { + allign(&offset, &bitoffset); + proto_tree_add_item(ie_tree, hf_ranap_dl_GTP_PDU_SequenceNumber, tvb, offset, 2, FALSE); + offset += 2; + } + + /* ul-GTP-PDU-SequenceNumber */ + if (ul_GTP_PDU_SequenceNumber_present) + { + allign(&offset, &bitoffset); + proto_tree_add_item(ie_tree, hf_ranap_ul_GTP_PDU_SequenceNumber, tvb, offset, 2, FALSE); + offset += 2; + } + + /* dl-N-PDU-SequenceNumber */ + if (dl_N_PDU_SequenceNumber_present) + { + allign(&offset, &bitoffset); + proto_tree_add_item(ie_tree, hf_ranap_dl_N_PDU_SequenceNumber, tvb, offset, 2, FALSE); + offset += 2; + } + + /* ul-N-PDU-SequenceNumber */ + if (ul_N_PDU_SequenceNumber_present) + { + allign(&offset, &bitoffset); + proto_tree_add_item(ie_tree, hf_ranap_ul_N_PDU_SequenceNumber, tvb, offset, 2, FALSE); + offset += 2; + } + + /* iE-Extensions */ + if (iE_Extensions_present) + { + if ((ret=dissect_iE_Extension(tvb, ie_tree, &offset, &bitoffset, "SetupOrModifyItemSecond")) != 0) + return (ret); + } + + /* protocol extended */ + if (extension_present) + { + /* extended enum */ + /* decoding is not supported */ + proto_tree_add_text(ie_tree, tvb, offset, IE_PROTOCOL_EXTENSION_LENGTH, + "Protocol extension for SetupOrModifyItemSecond present, dissection not supported"); + return(-1); + } + } + return(0); +} + + +static int +dissect_IE_RAB_SetupOrModifiedItem (tvbuff_t *tvb, proto_tree *ie_tree) +{ + proto_item *optionals_item = NULL; + proto_tree *optionals_tree = NULL; + int ret; + int extension_present; + int transportLayerAddress_present; + int iuTransportAssociation_present; + int dl_dataVolumes_present; + int iE_Extensions_present; + gint offset = 0; + gint bitoffset = 0; + + + if (ie_tree) + { + /* create subtree for extension/optional/default bitmap */ + optionals_item = proto_tree_add_text(ie_tree, tvb, offset, 1, + "RAB-SetupOrModifiedItem Extension/Optional/Default bitmap"); + optionals_tree = proto_item_add_subtree(optionals_item, ett_ranap_optionals); + + /* protocol_extension present ? */ + extension_present = extract_nbits(tvb, offset, bitoffset, 1); + proto_tree_add_uint_bits(optionals_tree, hf_ranap_ie_protocol_extension, tvb, + offset, bitoffset, 1, 0); + proceed_nbits(&offset, &bitoffset, 1); + + /* transportLayerAddress present ? */ + transportLayerAddress_present = extract_nbits(tvb, offset, bitoffset, 1); + proto_tree_add_uint_bits(optionals_tree, hf_ranap_transportLayerAddress_present, tvb, + offset, bitoffset, 1, 0); + proceed_nbits(&offset, &bitoffset, 1); + + /* iuTransportAssociation present ? */ + iuTransportAssociation_present = extract_nbits(tvb, offset, bitoffset, 1); + proto_tree_add_uint_bits(optionals_tree, hf_ranap_iuTransportAssociation_present, tvb, + offset, bitoffset, 1, 0); + proceed_nbits(&offset, &bitoffset, 1); + + /* dl_dataVolumes present ? */ + dl_dataVolumes_present = extract_nbits(tvb, offset, bitoffset, 1); + proto_tree_add_uint_bits(optionals_tree, hf_ranap_dl_dataVolumes_present, tvb, + offset, bitoffset, 1, 0); + proceed_nbits(&offset, &bitoffset, 1); + + /* iE_Extensions present ? */ + iE_Extensions_present = extract_nbits(tvb, offset, bitoffset, 1); + proto_tree_add_uint_bits(optionals_tree, hf_ranap_iE_Extensions_present, tvb, + offset, bitoffset, 1, 0); + proceed_nbits(&offset, &bitoffset, 1); + + + /* rAB-ID */ + proto_tree_add_uint_bits(ie_tree, hf_ranap_rab_id, + tvb, offset, bitoffset, 8, 0); + proceed_nbits(&offset, &bitoffset, 8); + + /* transportLayerAddress */ + if (transportLayerAddress_present) + { + if ((ret=dissect_TransportLayerAddress(tvb, ie_tree, &offset, &bitoffset)) != 0) + return (ret); + } + + /* iuTransportAssociation */ + if (iuTransportAssociation_present) + { + if ((ret=dissect_iuTransportAssociation(tvb, ie_tree, &offset, &bitoffset)) != 0) + return (ret); + } + + /* dl-dataVolumes */ + if (dl_dataVolumes_present) + { + if ((ret = dissect_dataVolumeList(tvb, ie_tree, &offset, &bitoffset, + "dl-dataVolumes")) != 0) + return (ret); + } + + /* iE-Extensions */ + if (iE_Extensions_present) + { + if ((ret=dissect_iE_Extension(tvb, ie_tree, &offset, &bitoffset, "RAB_SetupOrModifiedItem")) != 0) + return (ret); + } + + /* protocol extended */ + if (extension_present) + { + /* extended sequence */ + /* decoding is not supported */ + proto_tree_add_text(ie_tree, tvb, offset, IE_PROTOCOL_EXTENSION_LENGTH, + "Protocol extension for RAB_SetupOrModifiedItem present, dissection not supported"); + return(-1); + } + } + + return (0); +} + + +static int +dissect_IE_RAB_SetupOrModifyItemFirst (tvbuff_t *tvb, proto_tree *ie_tree) +{ + gint offset; + gint bitoffset; + proto_item *optionals_item = NULL; + proto_tree *optionals_tree = NULL; + int extension_present; + int nAS_SynchronisationIndicator_present; + int rAB_Parameters_present; + int userPlaneInformation_present; + int transportLayerInformation_present; + int service_Handover_present; + int iE_Extensions_present; + int tmp_extension_present; + int ret; + + if (ie_tree) + { + offset = 0; bitoffset = 0; + + /* create subtree for extension/optional/default bitmap */ + optionals_item = proto_tree_add_text(ie_tree, tvb, offset,IE_PROTOCOL_EXTENSION_LENGTH, + "RAB_SetupOrModifyItemFirst Extension/Optional/Default bitmap"); + optionals_tree = proto_item_add_subtree(optionals_item, ett_ranap_optionals); + + /* protocol extension present ? */ + extension_present = extract_nbits(tvb, offset, bitoffset, 1); + proto_tree_add_uint_bits(optionals_tree, hf_ranap_ie_protocol_extension, + tvb, offset, bitoffset, 1, 0); + proceed_nbits(&offset, &bitoffset, 1); + + /* nAS_SynchronisationIndicator present ? */ + nAS_SynchronisationIndicator_present = extract_nbits(tvb, offset, bitoffset, 1); + proto_tree_add_uint_bits(optionals_tree, hf_ranap_nAS_SynchronisationIndicator_present, + tvb, offset, bitoffset, 1, 0); + proceed_nbits(&offset, &bitoffset, 1); + + /* rAB_Parameters present ? */ + rAB_Parameters_present = extract_nbits(tvb, offset, bitoffset, 1); + proto_tree_add_uint_bits(optionals_tree, hf_ranap_rAB_Parameters_present, + tvb, offset, bitoffset, 1, 0); + proceed_nbits(&offset, &bitoffset, 1); + + /* userPlaneInformation present ? */ + userPlaneInformation_present = extract_nbits(tvb, offset, bitoffset, 1); + proto_tree_add_uint_bits(optionals_tree, hf_ranap_userPlaneInformation_present, + tvb, offset, bitoffset, 1, 0); + proceed_nbits(&offset, &bitoffset, 1); + + /* transportLayerInformation present ? */ + transportLayerInformation_present = extract_nbits(tvb, offset, bitoffset, 1); + proto_tree_add_uint_bits(optionals_tree, hf_ranap_transportLayerInformation_present, + tvb, offset, bitoffset, 1, 0); + proceed_nbits(&offset, &bitoffset, 1); + + /* service_Handover present ? */ + service_Handover_present = extract_nbits(tvb, offset, bitoffset, 1); + proto_tree_add_uint_bits(optionals_tree, hf_ranap_service_Handover_present, + tvb, offset, bitoffset, 1, 0); + proceed_nbits(&offset, &bitoffset, 1); + + /* iE_Extensions present ? */ + iE_Extensions_present = extract_nbits(tvb, offset, bitoffset, 1); + proto_tree_add_uint_bits(optionals_tree, hf_ranap_iE_Extensions_present, + tvb, offset, bitoffset, 1, 0); + proceed_nbits(&offset, &bitoffset, 1); + + + /* add RAB-ID */ + proto_tree_add_uint_bits(ie_tree, hf_ranap_rab_id, + tvb, offset, bitoffset, 8, 0); + proceed_nbits(&offset, &bitoffset, 8); + + /* nAS-SynchronisationIndicator */ + if (nAS_SynchronisationIndicator_present) + { + proto_tree_add_uint_bits(ie_tree, hf_ranap_nAS_SynchronisationIndicator, + tvb, offset, bitoffset, 4, 0); + proceed_nbits(&offset, &bitoffset, 4); + } + + /* rAB-Parameters */ + if (rAB_Parameters_present) + { + if ((ret=dissect_rAB_Parameters(tvb, ie_tree, &offset, &bitoffset)) != 0) + return(ret); + } + + /* userPlaneInformation */ + if (userPlaneInformation_present) + { + if ((ret=dissect_userPlaneInformation(tvb, ie_tree, &offset, &bitoffset)) != 0) + return(ret); + } + + /* transportLayerInformation */ + if (transportLayerInformation_present) + { + if ((ret=dissect_transportLayerInformation(tvb, ie_tree, &offset, &bitoffset)) != 0) + return(ret); + } + + /* service_Handover */ + if (service_Handover_present) + { + tmp_extension_present = extract_nbits(tvb, offset, bitoffset, 1); + proceed_nbits(&offset, &bitoffset, 1); + + if (tmp_extension_present) + { + /* extended enum */ + /* decoding is not supported */ + proto_tree_add_text(ie_tree, tvb, offset, IE_PROTOCOL_EXTENSION_LENGTH, + "Protocol extension for service_Handover present, dissection not supported"); + return(-1); + } + + proto_tree_add_uint_bits(ie_tree, hf_ranap_service_Handover, + tvb, offset, bitoffset, 2, 0); + proceed_nbits(&offset, &bitoffset, 2); + } + + /* iE-Extensions */ + if (iE_Extensions_present) + { + if ((ret=dissect_iE_Extension(tvb, ie_tree, &offset, &bitoffset, "SetupOrModifyItemFirst" )) != 0) + return(ret); + } + + } + return(0); +} + + +static int +dissect_IE_RAB_ReleaseItem(tvbuff_t *tvb, proto_tree *ie_tree) +{ + proto_item *optionals_item = NULL; + proto_tree *optionals_tree = NULL; + gint offset = 0; + gint bitoffset = 0; + int extension_present; + int iE_Extensions_present; + int ret; + + + /* create subtree for extension/optional/default bitmap */ + optionals_item = proto_tree_add_text(ie_tree, tvb, offset,IE_PROTOCOL_EXTENSION_LENGTH, + "RAB_ReleaseItem Extension/Optional/Default bitmap"); + optionals_tree = proto_item_add_subtree(optionals_item, ett_ranap_optionals); + + /* protocol extension present ? */ + extension_present = extract_nbits(tvb, offset, bitoffset, 1); + proto_tree_add_uint_bits(optionals_tree, hf_ranap_ie_protocol_extension, + tvb, offset, bitoffset, 1, 0); + proceed_nbits(&offset, &bitoffset, 1); + + + /* iE_Extensions present ? */ + iE_Extensions_present = extract_nbits(tvb, offset, bitoffset, 1); + proto_tree_add_uint_bits(optionals_tree, hf_ranap_iE_Extensions_present, + tvb, offset, bitoffset, 1, 0); + proceed_nbits(&offset, &bitoffset, 1); + + + /* add RAB-ID */ + proto_tree_add_uint_bits(ie_tree, hf_ranap_rab_id, + tvb, offset, bitoffset, 8, 0); + proceed_nbits(&offset, &bitoffset, 8); + + + /* add cause */ + if ((ret=dissect_cause(tvb, ie_tree, &offset, &bitoffset)) != 0) + return (ret); + + /* iE Extensions */ + if (iE_Extensions_present) + { + if ((ret=dissect_iE_Extension(tvb, ie_tree, &offset, &bitoffset, "RAB_ReleasedItem")) != 0) + return (ret); + } + + /* protocol extended */ + if (extension_present) + { + /* extended sequence */ + /* decoding is not supported */ + proto_tree_add_text(ie_tree, tvb, offset, IE_PROTOCOL_EXTENSION_LENGTH, + "Protocol extension for RAB_ReleasedItem present, dissection not supported"); + return(-1); + } + + return(0); +} + + +static int +dissect_IE_RAB_ReleasedItem (tvbuff_t *tvb, proto_tree *ie_tree) +{ + proto_item *optionals_item = NULL; + proto_tree *optionals_tree = NULL; + int ret; + int extension_present; + int dl_dataVolumes_present; + int dl_GTP_PDU_SequenceNumber_present; + int ul_GTP_PDU_SequenceNumber_present; + int iE_Extensions_present; + gint offset = 0; + gint bitoffset = 0; + + if (ie_tree) + { + /* create subtree for extension/optional/default bitmap */ + optionals_item = proto_tree_add_text(ie_tree, tvb, offset, 1, + "RAB-ReleasedItem Extension/Optional/Default bitmap"); + optionals_tree = proto_item_add_subtree(optionals_item, ett_ranap_optionals); + + /* protocol_extension present ? */ + extension_present = extract_nbits(tvb, offset, bitoffset, 1); + proto_tree_add_uint_bits(optionals_tree, hf_ranap_ie_protocol_extension, tvb, + offset, bitoffset, 1, 0); + proceed_nbits(&offset, &bitoffset, 1); + + /* dl_dataVolumes present ? */ + dl_dataVolumes_present = extract_nbits(tvb, offset, bitoffset, 1); + proto_tree_add_uint_bits(optionals_tree, hf_ranap_dl_dataVolumes_present, tvb, + offset, bitoffset, 1, 0); + proceed_nbits(&offset, &bitoffset, 1); + + /* dL_GTP_PDU_SequenceNumber present ? */ + dl_GTP_PDU_SequenceNumber_present = extract_nbits(tvb, offset, bitoffset, 1); + proto_tree_add_uint_bits(optionals_tree, hf_ranap_dl_GTP_PDU_SequenceNumber_present, + tvb, offset, bitoffset, 1, 0); + proceed_nbits(&offset, &bitoffset, 1); + + /* uL_GTP_PDU_SequenceNumber present ? */ + ul_GTP_PDU_SequenceNumber_present = extract_nbits(tvb, offset, bitoffset, 1); + proto_tree_add_uint_bits(optionals_tree, hf_ranap_ul_GTP_PDU_SequenceNumber_present, + tvb, offset, bitoffset, 1, 0); + proceed_nbits(&offset, &bitoffset, 1); + + /* iE_Extensions present ? */ + iE_Extensions_present = extract_nbits(tvb, offset, bitoffset, 1); + proto_tree_add_uint_bits(optionals_tree, hf_ranap_iE_Extensions_present, + tvb, offset, bitoffset, 1, 0); + proceed_nbits(&offset, &bitoffset, 1); + + /* rAB-ID */ + proto_tree_add_uint_bits(ie_tree, hf_ranap_rab_id, + tvb, offset, bitoffset, 8, 0); + proceed_nbits(&offset, &bitoffset, 8); + + /* dl-dataVolumes */ + if (dl_dataVolumes_present) + { + if ((ret=dissect_dataVolumeList(tvb, ie_tree, &offset, &bitoffset, + "dl-dataVolumes")) != 0) + return (ret); + } + + /* dL-GTP-PDU-SequenceNumber */ + if (dl_GTP_PDU_SequenceNumber_present) + { + allign(&offset, &bitoffset); + proto_tree_add_item(ie_tree, hf_ranap_dl_GTP_PDU_SequenceNumber, tvb, offset, 2, FALSE); + offset += 2; + } + + /* uL-GTP-PDU-SequenceNumber */ + if (ul_GTP_PDU_SequenceNumber_present) + { + allign(&offset, &bitoffset); + proto_tree_add_item(ie_tree, hf_ranap_ul_GTP_PDU_SequenceNumber, tvb, offset, 2, FALSE); + offset += 2; + } + + /* iE-Extensions */ + if (iE_Extensions_present) + { + if ((ret=dissect_iE_Extension(tvb, ie_tree, &offset, &bitoffset, "UserPlaneInformation")) != 0) + return(ret); + } + + /* protocol extended */ + if (extension_present) + { + /* extended sequence */ + /* decoding is not supported */ + proto_tree_add_text(ie_tree, tvb, offset, IE_PROTOCOL_EXTENSION_LENGTH, + "Protocol extension for RAB_ReleasedItem present, dissection not supported"); + return(-1); + } + } + + return(0); +} + + +static int +dissect_IE_RAB_QueuedItem (tvbuff_t *tvb, proto_tree *ie_tree) +{ + proto_item *optionals_item = NULL; + proto_tree *optionals_tree = NULL; + int ret; + int extension_present; + int iE_Extensions_present; + gint offset = 0; + gint bitoffset = 0; + + + if (ie_tree) + { + /* create subtree for extension/optional/default bitmap */ + optionals_item = proto_tree_add_text(ie_tree, tvb, offset, 1, + "RAB-QueuedItem Extension/Optional/Default bitmap"); + optionals_tree = proto_item_add_subtree(optionals_item, ett_ranap_optionals); + + /* protocol_extension present ? */ + extension_present = extract_nbits(tvb, offset, bitoffset, 1); + proto_tree_add_uint_bits(optionals_tree, hf_ranap_ie_protocol_extension, tvb, + offset, bitoffset, 1, 0); + proceed_nbits(&offset, &bitoffset, 1); + + /* iE_Extensions present ? */ + iE_Extensions_present = extract_nbits(tvb, offset, bitoffset, 1); + proto_tree_add_uint_bits(optionals_tree, hf_ranap_iE_Extensions_present, + tvb, offset, bitoffset, 1, 0); + proceed_nbits(&offset, &bitoffset, 1); + + /* rAB-ID */ + proto_tree_add_uint_bits(ie_tree, hf_ranap_rab_id, + tvb, offset, bitoffset, 8, 0); + proceed_nbits(&offset, &bitoffset, 8); + + /* iE-Extensions */ + if (iE_Extensions_present) + { + if ((ret=dissect_iE_Extension(tvb, ie_tree, &offset, &bitoffset, "RAB_QueuedItem" )) != 0 ) + return (ret); + } + + /* protocol extended */ + if (extension_present) + { + /* extended sequence */ + /* decoding is not supported */ + proto_tree_add_text(ie_tree, tvb, offset, IE_PROTOCOL_EXTENSION_LENGTH, + "Protocol extension for RAB_QueuedItem present, dissection not supported"); + return(-1); + } + } + + return(0); +} + + +static int +dissect_IE_RAB_FailedItem(tvbuff_t *tvb, proto_tree *ie_tree) +{ + proto_item *optionals_item = NULL; + proto_tree *optionals_tree = NULL; + int ret; + int extension_present; + int iE_Extensions_present; + gint offset = 0; + gint bitoffset = 0; + + if (ie_tree) + { + /* create subtree for extension/optional/default bitmap */ + optionals_item = proto_tree_add_text(ie_tree, tvb, offset, 1, + "RAB-FailedItem Extension/Optional/Default bitmap"); + optionals_tree = proto_item_add_subtree(optionals_item, ett_ranap_optionals); + + /* protocol_extension present ? */ + extension_present = extract_nbits(tvb, offset, bitoffset, 1); + proto_tree_add_uint_bits(optionals_tree, hf_ranap_ie_protocol_extension, tvb, + offset, bitoffset, 1, 0); + proceed_nbits(&offset, &bitoffset, 1); + + /* iE_Extensions present ? */ + iE_Extensions_present = extract_nbits(tvb, offset, bitoffset, 1); + proto_tree_add_uint_bits(optionals_tree, hf_ranap_iE_Extensions_present, + tvb, offset, bitoffset, 1, 0); + proceed_nbits(&offset, &bitoffset, 1); + + /* rAB-ID */ + proto_tree_add_uint_bits(ie_tree, hf_ranap_rab_id, + tvb, offset, bitoffset, 8, 0); + proceed_nbits(&offset, &bitoffset, 8); + + /* cause */ + if ((ret=dissect_cause(tvb, ie_tree, &offset, &bitoffset)) != 0) + return (ret); + + /* iE-Extensions */ + if (iE_Extensions_present) + { + if ((ret=dissect_iE_Extension(tvb, ie_tree, &offset, &bitoffset, "RAB-FailedItem")) != 0) + return (ret); + } + + + /* protocol extended */ + if (extension_present) + { + /* extended sequence */ + /* decoding is not supported */ + proto_tree_add_text(ie_tree, tvb, offset, IE_PROTOCOL_EXTENSION_LENGTH, + "Protocol extension for RAB-FailedItem present, dissection not supported"); + return(-1); + } + } + return(0); +} + + +static int +dissect_IE_CriticalityDiagnostics(tvbuff_t *tvb, proto_tree *ie_tree) + +{ + proto_item *optionals_item = NULL; + proto_tree *optionals_tree = NULL; + int ret; + int extension_present; + int procedureCode_present; + int triggeringMessage_present; + int procedureCriticality_present; + int iEsCriticalityDiagnostics_present; + int iE_Extensions_present; + gint offset = 0; + gint bitoffset = 0; + + + if (ie_tree) + { + /* create subtree for extension/optional/default bitmap */ + optionals_item = proto_tree_add_text(ie_tree, tvb, offset, 1, + "IE-CriticalityDiagnostics Extension/Optional/Default bitmap"); + optionals_tree = proto_item_add_subtree(optionals_item, ett_ranap_optionals); + + /* protocol_extension present ? */ + extension_present = extract_nbits(tvb, offset, bitoffset, 1); + proto_tree_add_uint_bits(optionals_tree, hf_ranap_ie_protocol_extension, tvb, + offset, bitoffset, 1, 0); + proceed_nbits(&offset, &bitoffset, 1); + + /* procedureCode present ? */ + procedureCode_present = extract_nbits(tvb, offset, bitoffset, 1); + proto_tree_add_uint_bits(optionals_tree, hf_ranap_procedureCode_present, + tvb, offset, bitoffset, 1, 0); + proceed_nbits(&offset, &bitoffset, 1); + + /* triggeringMessage present ? */ + triggeringMessage_present = extract_nbits(tvb, offset, bitoffset, 1); + proto_tree_add_uint_bits(optionals_tree, hf_ranap_triggeringMessage_present, + tvb, offset, bitoffset, 1, 0); + proceed_nbits(&offset, &bitoffset, 1); + + /* procedureCriticality present ? */ + procedureCriticality_present = extract_nbits(tvb, offset, bitoffset, 1); + proto_tree_add_uint_bits(optionals_tree, hf_ranap_procedureCriticality_present, + tvb, offset, bitoffset, 1, 0); + proceed_nbits(&offset, &bitoffset, 1); + + /* iEsCriticalityDiagnostics present ? */ + iEsCriticalityDiagnostics_present = extract_nbits(tvb, offset, bitoffset, 1); + proto_tree_add_uint_bits(optionals_tree, hf_ranap_iEsCriticalityDiagnostics_present, + tvb, offset, bitoffset, 1, 0); + proceed_nbits(&offset, &bitoffset, 1); + + /* iE_Extensions present ? */ + iE_Extensions_present = extract_nbits(tvb, offset, bitoffset, 1); + proto_tree_add_uint_bits(optionals_tree, hf_ranap_iE_Extensions_present, + tvb, offset, bitoffset, 1, 0); + proceed_nbits(&offset, &bitoffset, 1); + + + /* procedureCode */ + if (procedureCode_present) + { + allign (&offset, &bitoffset); + proto_tree_add_item(ie_tree, hf_ranap_procedure_code, tvb, offset, 1, FALSE); + offset += 1; + } + + /* triggeringMessage */ + if (triggeringMessage_present) + { + proto_tree_add_uint_bits(ie_tree, hf_ranap_triggeringMessage, + tvb, offset, bitoffset, 2, 0); + proceed_nbits(&offset, &bitoffset, 2); + } + + /* procedureCriticality */ + if (procedureCriticality_present) + { + proto_tree_add_uint_bits(ie_tree, hf_ranap_procedureCriticality, + tvb, offset, bitoffset, 2, 0); + proceed_nbits(&offset, &bitoffset, 2); + } + + /* iEsCriticalityDiagnostics */ + if (iEsCriticalityDiagnostics_present) + { + if ((ret=dissect_iEsCriticalityDiagnostics(tvb, ie_tree, &offset, &bitoffset)) != 0) + return(ret); + } + + /* iE-Extensions */ + if (iE_Extensions_present) + { + if ((ret=dissect_iE_Extension(tvb, ie_tree, &offset, &bitoffset, "IE_CriticalityDiagnostics")) != 0) + return(ret); + } + + + /* protocol extended */ + if (extension_present) + { + /* extended sequence */ + /* decoding is not supported */ + proto_tree_add_text(ie_tree, tvb, offset, IE_PROTOCOL_EXTENSION_LENGTH, + "Protocol extension for IE CriticalityDiagnostics present, dissection not supported"); + return(-1); + } + } + return(0); +} + + +static int +dissect_unknown_IE(tvbuff_t *tvb, proto_tree *ie_tree) +{ + if (ie_tree) + { + proto_tree_add_text(ie_tree, tvb, 0, -1, + "IE Contents (dissection not implemented)"); + } + return(0); +} + + + +/*****************************************************************************/ +/* */ +/* Dissecting Functions for IE Lists / Containers */ +/* */ +/*****************************************************************************/ + +static int +dissect_RAB_IE_ContainerPairList(tvbuff_t *tvb, proto_tree *ie_tree) +{ + proto_item *rab_item = NULL; + proto_tree *rab_tree = NULL; + proto_item *ie_pair_item = NULL; + proto_tree *ie_pair_tree = NULL; + proto_item *first_value_item = NULL; + proto_tree *first_value_tree = NULL; + proto_item *second_value_item = NULL; + proto_tree *second_value_tree = NULL; + guint number_of_RABs, currentRAB; + guint number_of_IEs, currentIE; + gint number_of_octets_first, number_of_octets_second; + gint number_of_octets_first_size, number_of_octets_second_size ; + gint offset = 0; + gint bitoffset = 0; + gint tmp_offset; + guint16 ie_id; + tvbuff_t *first_value_tvb; + tvbuff_t *second_value_tvb; + + if (ie_tree) + { + /* number of RABs in the list */ + number_of_RABs = 1 + tvb_get_guint8(tvb, offset); + proto_tree_add_uint(ie_tree, hf_ranap_num_rabs, + tvb, offset, + NUM_RABS_LENGTH, number_of_RABs); + + offset += NUM_RABS_LENGTH; + + /* do for each RAB */ + for (currentRAB=1; currentRAB<=number_of_RABs; currentRAB++) + { + /* create subtree for RAB */ + rab_item = proto_tree_add_text(ie_tree, tvb, offset, 0, "%d. RAB", currentRAB); + rab_tree = proto_item_add_subtree(rab_item, ett_ranap_rab); + + /* number of IE pairs for this RAB */ + number_of_IEs = tvb_get_ntohs(tvb, offset); + proto_tree_add_uint(rab_tree, hf_ranap_number_of_ies_in_list, + tvb, offset, 2, number_of_IEs); + + offset += 2; /*points now to beginning of first IE pair */ + + /* do for each IE pair */ + for (currentIE=1; currentIE<=number_of_IEs; currentIE++) + { + /* use tmp_offset to point to current field */ + tmp_offset = offset; + /* IE pair ID */ + ie_id = tvb_get_ntohs(tvb, tmp_offset); + tmp_offset += IE_ID_LENGTH; + + tmp_offset += 1; /* skip first criticality byte */ + /* number of octets in first value */ + extract_length(tvb, tmp_offset, &number_of_octets_first, &number_of_octets_first_size); + tmp_offset += number_of_octets_first_size + number_of_octets_first; + + tmp_offset += 1; /* skip second criticality byte */ + /* number of octets in second value */ + extract_length(tvb, tmp_offset, &number_of_octets_second, &number_of_octets_second_size); + tmp_offset += number_of_octets_second_size + number_of_octets_second; + + /* create subtree for ie_pair */ + ie_pair_item = proto_tree_add_text(rab_tree, tvb, offset, + tmp_offset - offset, + "%s IE Pair (%u)", + val_to_str(ie_id, ranap_ie_id_values, "Unknown"), + ie_id); + ie_pair_tree = proto_item_add_subtree(ie_pair_item, ett_ranap_ie_pair); + + /* add fields to ie pair subtee */ + /* use offset to point to current field */ + /* IE ID */ + proto_tree_add_item(ie_pair_tree, hf_ranap_ie_ie_id, tvb, offset, IE_ID_LENGTH, FALSE); + offset += IE_ID_LENGTH; + + /* first criticality */ + proto_tree_add_uint_bits(ie_pair_tree, hf_ranap_ie_pair_first_criticality, tvb, + offset, bitoffset, 2, 0); + proceed_nbits(&offset, &bitoffset, 2); + + /* number of octets in first value */ + allign(&offset, &bitoffset); + if (number_of_octets_first != 0) + { + proto_tree_add_uint(ie_pair_tree, hf_ranap_first_value_number_of_octets, + tvb, offset, + number_of_octets_first_size, + number_of_octets_first); + } + else + { + /* decoding is not supported */ + proto_tree_add_text(ie_pair_tree, tvb, offset, + 2, "Number of Octets greater than 0x3FFF, dissection not supported"); + return(-1); + } + offset += number_of_octets_first_size; + + /* add subtree for first value */ + first_value_item = proto_tree_add_text(ie_pair_tree, tvb, offset, + number_of_octets_first, + "%sFirst", + val_to_str(ie_id, ranap_ie_id_values, "Unknown")); + first_value_tree = proto_item_add_subtree(first_value_item, ett_ranap_ie_pair_first_value); + + /* create tvb containing first value */ + first_value_tvb = tvb_new_subset(tvb, offset, number_of_octets_first, number_of_octets_first); + + /* add fields of first value */ + switch (ie_id) + { + case IE_RAB_SetupOrModifyItem: + dissect_IE_RAB_SetupOrModifyItemFirst (first_value_tvb, first_value_tree); + break; + + default: + dissect_unknown_IE(first_value_tvb, first_value_tree); + break; + } + + offset += number_of_octets_first; + + + /* second criticality */ + proto_tree_add_uint_bits(ie_pair_tree, hf_ranap_ie_pair_second_criticality, tvb, + offset, bitoffset, 2, 0); + proceed_nbits(&offset, &bitoffset, 2); + + /* number of octets of second value */ + allign(&offset, &bitoffset); + if (number_of_octets_second != 0) + { + proto_tree_add_uint(ie_pair_tree, hf_ranap_second_value_number_of_octets, + tvb, offset, + number_of_octets_second_size, + number_of_octets_second); + } + else + { + /* decoding is not supported */ + proto_tree_add_text(ie_pair_tree, tvb, offset, + 2, "Number of Octets greater than 0x3FFF, dissection not supported"); + return(-1); + } + offset += number_of_octets_second_size; + + /* add subtree for second value */ + second_value_item = proto_tree_add_text(ie_pair_tree, tvb, offset, + number_of_octets_second, + "%sSecond", + val_to_str(ie_id, ranap_ie_id_values, "Unknown")); + second_value_tree = proto_item_add_subtree(second_value_item, ett_ranap_ie_pair_second_value); + + /* create tvb containing first value */ + second_value_tvb = tvb_new_subset(tvb, offset, number_of_octets_second, number_of_octets_second); + + /* add fields of second value */ + switch (ie_id) + { + case IE_RAB_SetupOrModifyItem: + dissect_IE_RAB_SetupOrModifyItemSecond (second_value_tvb, second_value_tree); + break; + + default: + dissect_unknown_IE(second_value_tvb, second_value_tree); + break; + } + + offset += number_of_octets_second; + + }/* for each IE ... */ + }/* for each RAB ... */ + } + return(0); +} + + +static int +dissect_RAB_IE_ContainerList(tvbuff_t *tvb, proto_tree *list_tree) +{ + proto_item *rab_item = NULL; + proto_tree *rab_tree = NULL; + proto_item *ie_item = NULL; + proto_tree *ie_tree = NULL; + + guint number_of_RABs, currentRAB; + guint number_of_IEs, currentIE; + gint ie_number_of_octets = 0; + gint ie_number_of_octets_size = 0; + gint offset = 0; + gint bitoffset = 0; + gint ie_offset = 0; + gint ie_header_length; + guint16 ie_id; + tvbuff_t *ie_tvb; + + + if (list_tree) + { + /* number of RABs in the list */ + number_of_RABs = 1 + tvb_get_guint8(tvb, offset); + proto_tree_add_uint(list_tree, hf_ranap_num_rabs, + tvb, offset, + NUM_RABS_LENGTH, number_of_RABs); + + offset += NUM_RABS_LENGTH; + + /* do for each RAB */ + for (currentRAB=1; currentRAB<=number_of_RABs; currentRAB++) + { + /* create subtree for RAB */ + rab_item = proto_tree_add_text(list_tree, tvb, offset, 0, "%d. RAB", currentRAB); + rab_tree = proto_item_add_subtree(rab_item, ett_ranap_rab); + + /* number of IEs for this RAB */ + number_of_IEs = tvb_get_ntohs(tvb, offset); + proto_tree_add_uint(rab_tree, hf_ranap_number_of_ies_in_list, + tvb, offset, 2, number_of_IEs); + + offset += 2; /*points now to beginning of first IE in list */ + ie_offset = offset; + + /* do for each IE */ + for (currentIE=1; currentIE<=number_of_IEs; currentIE++) + { + /* extract IE ID */ + ie_id = tvb_get_ntohs(tvb, offset); + offset += IE_ID_LENGTH; + + offset += IE_CRITICALITY_LENGTH; /* skip criticality byte */ + + /* number of octets */ + extract_length(tvb, offset, &ie_number_of_octets, &ie_number_of_octets_size); + ie_header_length = IE_ID_LENGTH + IE_CRITICALITY_LENGTH + ie_number_of_octets_size; + + /* reset offset to beginning of ie */ + offset = ie_offset; + + /* create subtree for ie */ + ie_item = proto_tree_add_text(rab_tree, tvb, offset, + ie_header_length + ie_number_of_octets, + "%s IE (%u)", + val_to_str(ie_id, ranap_ie_id_values, "Unknown"), + ie_id); + ie_tree = proto_item_add_subtree(ie_item, ett_ranap_ie); + + /* IE ID */ + proto_tree_add_item(ie_tree, hf_ranap_ie_ie_id, tvb, + offset, IE_ID_LENGTH, FALSE); + offset += IE_ID_LENGTH; + + /* criticality */ + proto_tree_add_uint_bits(ie_tree, hf_ranap_ie_criticality, tvb, + offset, bitoffset, 2, 0); + proceed_nbits(&offset, &bitoffset, 2); + + allign(&offset, &bitoffset); + if (ie_number_of_octets != 0) + { + proto_tree_add_uint(ie_tree, hf_ranap_ie_number_of_octets, tvb, + offset, ie_number_of_octets_size, ie_number_of_octets); + } + else + { + /* decoding is not supported */ + proto_tree_add_text(ie_tree, tvb, offset, + 0, "Number of Octets greater than 0x3FFF, dissection not supported"); + return(-1); + } + offset += ie_number_of_octets_size; + + + /* create tvb containing ie */ + ie_tvb = tvb_new_subset(tvb, offset, ie_number_of_octets, ie_number_of_octets); + + /* add fields of ie */ + switch (ie_id) + { + case IE_RAB_SetupOrModifiedItem: + dissect_IE_RAB_SetupOrModifiedItem(ie_tvb, ie_tree); + break; + case IE_RAB_ReleaseItem: + dissect_IE_RAB_ReleaseItem(ie_tvb, ie_tree); + break; + case IE_RAB_ReleasedItem: + dissect_IE_RAB_ReleasedItem(ie_tvb, ie_tree); + break; + case IE_RAB_ReleasedItem_IuRelComp: + dissect_IE_RAB_ReleasedItem_IuRelComp(ie_tvb, ie_tree); + break; + case IE_RAB_QueuedItem: + dissect_IE_RAB_QueuedItem(ie_tvb, ie_tree); + break; + case IE_RAB_FailedItem: + dissect_IE_RAB_FailedItem(ie_tvb, ie_tree); + break; + case IE_RAB_DataVolumeReportItem: + dissect_IE_RAB_DataVolumeReportItem(ie_tvb, ie_tree); + break; + default: + dissect_unknown_IE(ie_tvb, ie_tree); + break; + } + + ie_offset += (ie_header_length + ie_number_of_octets); + offset = ie_offset; + } /* for each IE */ + } /* for each RAB */ + } + return (0); +} + + +static int +dissect_ranap_ie(guint16 ie_id, tvbuff_t *ie_contents_tvb, proto_tree *ie_tree) +{ + /* call specific dissection function for ie contents */ + switch(ie_id) + { + case IE_RAB_ID: + return(dissect_IE_RAB_ID(ie_contents_tvb, ie_tree)); + break; + case IE_NAS_PDU: + return(dissect_IE_NAS_PDU(ie_contents_tvb, ie_tree)); + break; + case IE_LAI: + return(dissect_IE_LAI(ie_contents_tvb, ie_tree)); + break; + case IE_RAC: + return(dissect_IE_RAC(ie_contents_tvb, ie_tree)); + break; + case IE_SAI: + return(dissect_IE_SAI(ie_contents_tvb, ie_tree)); + break; + case IE_GlobalRNC_ID: + return(dissect_IE_GlobalRNC_ID(ie_contents_tvb, ie_tree)); + break; + case IE_CN_DomainIndicator: + return(dissect_IE_CN_DomainIndicator(ie_contents_tvb, ie_tree)); + break; + case IE_IuSigConId: + return(dissect_IE_IuSigConId(ie_contents_tvb, ie_tree)); + break; + case IE_SAPI: + return(dissect_IE_SAPI(ie_contents_tvb, ie_tree)); + break; + case IE_TransportLayerAddress: + return(dissect_IE_TransportLayerAddress(ie_contents_tvb, ie_tree)); + break; + case IE_IuTransportAssociation: + return(dissect_IE_IuTransportAssociation(ie_contents_tvb, ie_tree)); + break; + case IE_RAB_SetupOrModifyList: + return(dissect_RAB_IE_ContainerPairList(ie_contents_tvb, ie_tree)); + break; + case IE_RAB_SetupOrModifiedList: + case IE_RAB_ReleaseList: + case IE_RAB_ReleasedList: + case IE_RAB_QueuedList: + case IE_RAB_FailedList: + case IE_RAB_ReleaseFailedList: + case IE_RAB_DataVolumeReportList: + case IE_RAB_ReleasedList_IuRelComp: + case IE_RAB_RelocationReleaseList: + case IE_RAB_DataForwardingList: + case IE_RAB_SetupList_RelocReq: + case IE_RAB_SetupList_RelocReqAck: + case IE_RAB_DataForwardingList_SRNS_CtxReq: + case IE_RAB_ContextList: + case IE_RAB_ContextFailedtoTransferList: + case IE_RAB_DataVolumeReportRequestList: + case IE_RAB_FailedtoReportList: + case IE_RAB_ContextList_RANAP_RelocInf: + return(dissect_RAB_IE_ContainerList(ie_contents_tvb, ie_tree)); + break; + case IE_CriticalityDiagnostics: + return(dissect_IE_CriticalityDiagnostics(ie_contents_tvb, ie_tree)); + break; + case IE_Cause: + return(dissect_IE_Cause(ie_contents_tvb, ie_tree)); + break; + default: + return(dissect_unknown_IE(ie_contents_tvb, ie_tree)); + break; + } +} + + +static int +dissect_ranap_ie_container(tvbuff_t *tvb, proto_tree *ranap_tree) +{ + proto_item *ie_item = NULL; + proto_tree *ie_tree = NULL; + proto_item *optionals_item = NULL; + proto_tree *optionals_tree = NULL; + + int msg_extension_present; + int ProtocolExtensionContainer_present; + + guint16 number_of_ies; + guint16 ie_id; + gint ie_number_of_octets = 0; + gint ie_number_of_octets_size = 0; + guint16 ie_header_length; + gint offset = 0; + gint bitoffset = 0; + gint i, ie_offset; + tvbuff_t *ie_contents_tvb; + + if (ranap_tree) + { + /* create subtree for extension/optional bitmap of message */ + optionals_item = proto_tree_add_text(ranap_tree, tvb, offset, 1, + "Message Extension/Optional/Default bitmap"); + optionals_tree = proto_item_add_subtree(optionals_item, ett_ranap_optionals); + } + + /* msg_extension present ? */ + msg_extension_present = extract_nbits(tvb, offset, bitoffset, 1); + + if (ranap_tree) + { + proto_tree_add_uint_bits(optionals_tree, hf_ranap_msg_extension_present, tvb, + offset, bitoffset, 1, 0); + } + proceed_nbits(&offset, &bitoffset, 1); + + /* ProtocolExtensionContainer present ? */ + ProtocolExtensionContainer_present = extract_nbits(tvb, offset, bitoffset, 1); + if (ranap_tree) + { + proto_tree_add_uint_bits(optionals_tree, hf_ranap_ProtocolExtensionContainer_present, + tvb, offset, bitoffset, 1, 0); + } + proceed_nbits(&offset, &bitoffset, 1); + + + /* extract ie container data */ + /* number of ies */ + allign(&offset, &bitoffset); + number_of_ies = tvb_get_ntohs(tvb, offset); + if (ranap_tree) + { + proto_tree_add_uint(ranap_tree, hf_ranap_number_of_ies, + tvb, offset, 2, number_of_ies); + } + offset += 2; + + ie_offset = offset; /* ie_offset marks beginning of IE-Header */ + + /* do the following for each IE in the PDU */ + for (i=1; i <= number_of_ies; i++) + { + /* extract IE header fields which are needed even if no ranap tree exists*/ + /* IE-ID */ + ie_id = tvb_get_ntohs(tvb, offset); + offset += IE_ID_LENGTH; + + /* number of octets in the IE */ + offset += IE_CRITICALITY_LENGTH; /* skip criticality byte */ + ie_number_of_octets = 0; + extract_length(tvb, offset, &ie_number_of_octets, &ie_number_of_octets_size); + ie_header_length = IE_ID_LENGTH + IE_CRITICALITY_LENGTH + ie_number_of_octets_size; + + if (ranap_tree) + { + offset = ie_offset; /* start from beginning of IE */ + /* create subtree for ie */ + ie_item = proto_tree_add_text(ranap_tree, tvb, offset, + ie_header_length + ie_number_of_octets, + "%s IE (%u)", + val_to_str(ie_id, ranap_ie_id_values, "Unknown"), + ie_id); + ie_tree = proto_item_add_subtree(ie_item, ett_ranap_ie); + + /* add fields to ie subtee */ + /* IE ID */ + proto_tree_add_item(ie_tree, hf_ranap_ie_ie_id, tvb, + offset, IE_ID_LENGTH, FALSE); + offset += IE_ID_LENGTH; + + /* criticality */ + proto_tree_add_uint_bits(ie_tree, hf_ranap_ie_criticality, tvb, + offset, bitoffset, 2, 0); + proceed_nbits(&offset, &bitoffset, 2); + + /* number of octets */ + allign(&offset, &bitoffset); + if (ie_number_of_octets != 0) + { + proto_tree_add_uint(ie_tree, hf_ranap_ie_number_of_octets, tvb, + offset, ie_number_of_octets_size, ie_number_of_octets); + offset += ie_number_of_octets_size; + } + else + { + /* decoding is not supported */ + proto_tree_add_text(ranap_tree, tvb, offset, + 2, "Number of Octets greater than 0x3FFF, dissection not supported"); + return(-1); + } + } + + /* check if number_of_octets could be decoded */ + /* in case we skipped if (ranap_tree) {....} */ + if (ie_number_of_octets == 0) return (-1); + + /* create tvb containing the ie contents */ + ie_contents_tvb = tvb_new_subset(tvb, ie_offset + ie_header_length, + ie_number_of_octets, ie_number_of_octets); + + /* call specific dissection function for ie contents */ + dissect_ranap_ie(ie_id, ie_contents_tvb, ie_tree); + + /* set ie_offset to beginning of next ie */ + ie_offset += (ie_header_length + ie_number_of_octets); + offset = ie_offset; + } + + /* protocol Extensions */ + if (ProtocolExtensionContainer_present) + { + return(dissect_iE_Extension(tvb, ranap_tree, &offset, &bitoffset, "PDU")); + } + + return(0); + +} + + +static void +dissect_ranap(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) +{ + proto_item *ranap_item = NULL; + proto_tree *ranap_tree = NULL; + + guint procedure_code; + guint pdu_index; + gint number_of_octets = 0; + gint number_of_octets_size = 0; + gint offset = 0; + gint tmp_offset = 0; + gint bitoffset = 0; + gint tmp_bitoffset = 0; + guint extension_present; + + tvbuff_t *ie_tvb; + + + g_pinfo = pinfo; + + /* make entry in the Protocol column on summary display */ + if (check_col(pinfo->cinfo, COL_PROTOCOL)) + col_set_str(pinfo->cinfo, COL_PROTOCOL, "RANAP"); + + /* extract header fields which are needed even if no tree exists */ + + /* protocol_extension present ? */ + extension_present = extract_nbits(tvb, tmp_offset, tmp_bitoffset, 1); + proceed_nbits(&tmp_offset, &tmp_bitoffset, 1); + if (extension_present) + { + /* extended choice */ + /* decoding is not supported */ + if (check_col(pinfo->cinfo, COL_INFO)) + { + col_append_str(pinfo->cinfo, COL_INFO, "RANAP-PDU Protocol extension present, dissection not supported"); + } + + if (tree) + { + proto_tree_add_text(tree, tvb, 0, -1, "RANAP Message"); + } + return; + } + + /* pdu_index choice 0..3 */ + pdu_index = extract_nbits(tvb, tmp_offset, tmp_bitoffset, 2); + proceed_nbits(&tmp_offset, &tmp_bitoffset, 2); + + /* procedure code */ + allign(&tmp_offset, &tmp_bitoffset); + procedure_code = tvb_get_guint8(tvb, tmp_offset); + tmp_offset += 1; + + /* add Procedure Code to Info Column */ + if (check_col(pinfo->cinfo, COL_INFO)) + { + if (procedure_code <= PC_max) + { + col_add_fstr(pinfo->cinfo, COL_INFO, "%s ", + val_to_str(pdu_index, ranap_message_names[procedure_code], + "unknown message")); + } + } + + /* extract number of octets */ + tmp_offset += 1; /* leave out criticality byte */ + extract_length(tvb, tmp_offset, &number_of_octets, &number_of_octets_size); + + /* In the interest of speed, if "tree" is NULL, don't do any work not + necessary to generate protocol tree items. */ + if (tree) + { + g_tree = tree; + + /* create the ranap protocol tree */ + ranap_item = proto_tree_add_item(tree, proto_ranap, tvb, 0, -1, FALSE); + ranap_tree = proto_item_add_subtree(ranap_item, ett_ranap); + + /* Add fields to ranap protocol tree */ + /* PDU Index */ + proceed_nbits(&offset, &bitoffset, 1); /* leave out extension bit, checked above */ + proto_tree_add_uint_bits(ranap_tree, hf_ranap_pdu_index, tvb, + offset, bitoffset, 2, 0); + proceed_nbits(&offset, &bitoffset, 2); + + + /* Procedure Code */ + allign(&offset, &bitoffset); + proto_tree_add_item(ranap_tree, hf_ranap_procedure_code, tvb, offset, 1, FALSE); + offset += 1; + + /* PDU Criticality */ + proto_tree_add_uint_bits(ranap_tree, hf_ranap_pdu_criticality, tvb, + offset, bitoffset, 2, 0); + proceed_nbits(&offset, &bitoffset, 2); + + /* number of octets */ + allign(&offset, &bitoffset); + if (number_of_octets != 0) + { + proto_tree_add_uint(ranap_tree, hf_ranap_pdu_number_of_octets, + tvb, offset, + number_of_octets_size, number_of_octets); + offset += number_of_octets_size; + } + else + { + /* decoding is not supported */ + proto_tree_add_text(ranap_tree, tvb, offset, + 2, "Number of Octets greater than 0x3FFF, dissection not supported"); + return; + } + } + + /* set offset to the beginning of ProtocolIE-Container */ + /* in case we skipped "if(tree){...}" above */ + offset = PDU_NUMBER_OF_OCTETS_OFFSET + number_of_octets_size; + + /* create a tvb containing the remainder of the PDU */ + ie_tvb = tvb_new_subset(tvb, offset, -1, -1); + + /* dissect the ies */ + dissect_ranap_ie_container(ie_tvb, ranap_tree); +} + + +static gboolean +dissect_sccp_ranap_heur(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) +{ + guint8 temp; + + /* Is it a ranap packet? + * + * 4th octet should be the length of the rest of the message. + * note: I believe the length octet may actually be represented + * by more than one octet. Something like... + * bit 01234567 octets + * 0xxxxxxx 1 + * 10xxxxxx xxxxxxxx 2 + * For now, we have ignored this. I hope that's safe. + * + * 2nd octet is the message-type e Z[0, 28] + * (obviously there must be at least four octets) + * + * If both hold true we'll assume its RANAP + */ + + #define LENGTH_OFFSET 3 + #define MSG_TYPE_OFFSET 1 + if (tvb_length(tvb) < 4) { return FALSE; } + if (tvb_get_guint8(tvb, LENGTH_OFFSET) != (tvb_length(tvb) - 4)) { return FALSE; } + temp = tvb_get_guint8(tvb, MSG_TYPE_OFFSET); + if (temp > 28) { return FALSE; } + + dissect_ranap(tvb, pinfo, tree); + + return TRUE; +} + + +/*****************************************************************************/ +/* */ +/* Protocol Registration Functions */ +/* */ +/*****************************************************************************/ + +void +proto_register_ranap(void) +{ + /* Setup list of header fields */ + static hf_register_info hf[] = { + { &hf_ranap_pdu_index, + { "RANAP-PDU Index", + "ranap.ranap_pdu_index", + FT_UINT8, BASE_HEX, VALS(&ranap_pdu_index_values), 0x0, + "", HFILL } + }, + { &hf_ranap_procedure_code, + { "Procedure Code", + "ranap.procedure_code", + FT_UINT8, BASE_DEC, VALS(&ranap_procedure_code_values), 0x0, + "", HFILL } + }, + { &hf_ranap_pdu_criticality, + { "Criticality of PDU", + "ranap.pdu.criticality", + FT_UINT8, BASE_HEX, VALS(&ranap_criticality_values), 0x0, + "", HFILL } + }, + { &hf_ranap_pdu_number_of_octets, + { "Number of Octets in PDU", + "ranap.pdu.num_of_octets", + FT_UINT16, BASE_DEC, NULL, 0x0, + "", HFILL } + }, + { &hf_ranap_ie_protocol_extension, + { "Protocol Extension", + "ranap.ie.protocol_extension_present", + FT_UINT8, BASE_HEX, VALS(&ranap_presence_values), 0x0, + "", HFILL } + }, + { &hf_ranap_number_of_ies, + { "Number of IEs in PDU", + "ranap.pdu.number_of_ies", + FT_UINT16, BASE_DEC, NULL, 0x0, + "", HFILL } + }, + { &hf_ranap_number_of_ies_in_list, + { "Number of IEs in list", + "ranap.number_of_ies", + FT_UINT16, BASE_DEC, NULL, 0x0, + "", HFILL } + }, + { &hf_ranap_ie_ie_id, + { "IE-ID", + "ranap.ie.ie_id", + FT_UINT16, BASE_DEC, VALS(&ranap_ie_id_values), 0x0, + "", HFILL } + }, + { &hf_ranap_ext_field_id, + { "ProtocolExtensionField ID", + "ranap.ie.ProtocolExtensionFields.Id", + FT_UINT16, BASE_DEC, NULL, 0x0, + "", HFILL } + }, + { &hf_ranap_ie_criticality, + { "Criticality of IE", + "ranap.ie.criticality", + FT_UINT8, BASE_HEX, VALS(&ranap_criticality_values), 0x0, + "", HFILL } + }, + { &hf_ranap_ext_field_criticality, + { "Criticality of ProtocolExtensionField", + "ranap.ie.ProtocolExtensionFields.criticality", + FT_UINT8, BASE_HEX, VALS(&ranap_criticality_values), 0x0, + "", HFILL } + }, + { &hf_ranap_ie_pair_first_criticality, + { "First Criticality", + "ranap.ie_pair.first_criticality", + FT_UINT8, BASE_HEX, VALS(&ranap_criticality_values), 0x0, + "", HFILL } + }, + { &hf_ranap_ie_pair_second_criticality, + { "Second Criticality", + "ranap.ie_pair.second_criticality", + FT_UINT8, BASE_HEX, VALS(&ranap_criticality_values), 0x0, + "", HFILL } + }, + { &hf_ranap_ie_number_of_octets, + { "Number of Octets in IE", + "ranap.ie.number_of_octets", + FT_UINT16, BASE_DEC, NULL, 0x0, + "", HFILL } + }, + { &hf_ranap_first_value_number_of_octets, + { "Number of Octets in first value", + "ranap.ie_pair.first_value.number_of_octets", + FT_UINT16, BASE_DEC, NULL, 0x0, + "", HFILL } + }, + { &hf_ranap_second_value_number_of_octets, + { "Number of Octets in second value", + "ranap.ie_pair.second_value.number_of_octets", + FT_UINT16, BASE_DEC, NULL, 0x0, + "", HFILL } + }, + { &hf_ranap_rab_id, + { "RAB-ID", + "ranap.RAB_ID", + FT_UINT8, BASE_HEX, NULL, 0x0, + "", HFILL } + }, + { &hf_ranap_nas_pdu, + { "NAS-PDU", + "ranap.NAS_PDU", + FT_BYTES, BASE_NONE, NULL, 0x0, + "", HFILL } + }, + { &hf_ranap_extension_field, + { "Extension Field Value", + "ranap.Extension_Field_Value", + FT_BYTES, BASE_NONE, NULL, 0x0, + "", HFILL } + }, + { &hf_ranap_plmn_id, + { "PLMN-ID", + "ranap.PLMN_ID", + FT_BYTES, BASE_NONE, NULL, 0x0, + "", HFILL } + }, + { &hf_ranap_lac, + { "LAC", + "ranap.LAC", + FT_BYTES, BASE_NONE, NULL, 0x0, + "", HFILL } + }, + { &hf_ranap_sac, + { "SAC", + "ranap.SAC", + FT_BYTES, BASE_NONE, NULL, 0x0, + "", HFILL } + }, + { &hf_ranap_rac, + { "RAC", + "ranap.RAC", + FT_BYTES, BASE_NONE, NULL, 0x0, + "", HFILL } + }, + { &hf_ranap_num_rabs, + { "Number of RABs", + "ranap.number_of_RABs", + FT_UINT8, BASE_DEC, NULL, 0x0, + "", HFILL } + }, + { &hf_ranap_nAS_SynchronisationIndicator_present, + { "nAS-SynchronisationIndicator", + "ranap.nAS-SynchronisationIndicator_present", + FT_UINT8, BASE_HEX, VALS(&ranap_presence_values), 0x0, + "", HFILL } + }, + { &hf_ranap_rAB_Parameters_present, + { "rAB-Parameters", + "ranap.rAB_Parameters_present", + FT_UINT8, BASE_HEX, VALS(&ranap_presence_values), 0x0, + "", HFILL } + }, + { &hf_ranap_userPlaneInformation_present, + { "userPlaneInformation", + "ranap.userPlaneInformation_present", + FT_UINT8, BASE_HEX, VALS(&ranap_presence_values), 0x0, + "", HFILL } + }, + { &hf_ranap_transportLayerInformation_present, + { "transportLayerInformation", + "ranap.transportLayerInformation_present", + FT_UINT8, BASE_HEX, VALS(&ranap_presence_values), 0x0, + "", HFILL } + }, + { &hf_ranap_service_Handover_present, + { "service-Handover", + "ranap.service_Handover_present", + FT_UINT8, BASE_HEX, VALS(&ranap_presence_values), 0x0, + "", HFILL } + }, + { &hf_ranap_iE_Extensions_present, + { "iE-Extensions", + "ranap.ie.iE-Extensions_present", + FT_UINT8, BASE_HEX, VALS(&ranap_presence_values), 0x0, + "", HFILL } + }, + { &hf_ranap_nAS_SynchronisationIndicator, + { "nAS-SynchronisationIndicator", + "ranap.nAS-SynchronisationIndicator", + FT_UINT8, BASE_HEX, NULL, 0x0, + "", HFILL } + }, + { &hf_ranap_guaranteedBitRate_present, + { "guaranteedBitRate", + "ranap.guaranteedBitRate_present", + FT_UINT8, BASE_HEX, VALS(&ranap_presence_values), 0x0, + "", HFILL } + }, + { &hf_ranap_transferDelay_present, + { "transferDelay", + "ranap.transferDelay_present", + FT_UINT8, BASE_HEX, VALS(&ranap_presence_values), 0x0, + "", HFILL } + }, + { &hf_ranap_trafficHandlingPriority_present, + { "trafficHandlingPriority", + "ranap.trafficHandlingPriority_present", + FT_UINT8, BASE_HEX, VALS(&ranap_presence_values), 0x0, + "", HFILL } + }, + { &hf_ranap_allocationOrRetentionPriority_present, + { "allocationOrRetentionPriority", + "ranap.allocationOrRetentionPriority_present", + FT_UINT8, BASE_HEX, VALS(&ranap_presence_values), 0x0, + "", HFILL } + }, + { &hf_ranap_sourceStatisticsDescriptor_present, + { "sourceStatisticsDescriptor", + "ranap.sourceStatisticsDescriptor_present", + FT_UINT8, BASE_HEX, VALS(&ranap_presence_values), 0x0, + "", HFILL } + }, + { &hf_ranap_relocationRequirement_present, + { "relocationRequirement", + "ranap.relocationRequirement_present", + FT_UINT8, BASE_HEX, VALS(&ranap_presence_values), 0x0, + "", HFILL } + }, + { &hf_ranap_trafficClass, + { "Traffic Class", + "ranap.rab_Parameters.trafficClass", + FT_UINT8, BASE_DEC, VALS(&ranap_trafficClass_values), 0x0, + "", HFILL } + }, + { &hf_ranap_rAB_AsymmetryIndicator, + { "rAB_AsymmetryIndicator", + "ranap.rab_Parameters.rAB_AsymmetryIndicator", + FT_UINT8, BASE_DEC, VALS(&ranap_rAB_AsymmetryIndicator_values), 0x0, + "", HFILL } + }, + { &hf_ranap_maxBitrate, + { "maxBitrate", + "ranap.rab_Parameters.maxBitrate", + FT_UINT32, BASE_DEC, NULL, 0x0, + "", HFILL } + }, + { &hf_ranap_guaranteedBitrate, + { "guaranteedBitrate", + "ranap.rab_Parameters.guaranteedBitrate", + FT_UINT32, BASE_DEC, NULL, 0x0, + "", HFILL } + }, + { &hf_ranap_deliveryOrder, + { "deliveryOrder", + "ranap.rab_Parameters.deliveryOrder", + FT_UINT8, BASE_DEC, VALS(&ranap_DeliveryOrder_values), 0x0, + "", HFILL } + }, + { &hf_ranap_maxSDU_Size, + { "maxSDU_Size", + "ranap.rab_Parameters.maxSDU_Size", + FT_UINT16, BASE_DEC, NULL, 0x0, + "", HFILL } + }, + { &hf_ranap_sDU_ErrorRatio_mantissa, + { "sDU_ErrorRatio: mantissa", + "ranap.rab_Parameters.sDU_ErrorRatio.mantissa", + FT_UINT8, BASE_DEC, NULL, 0x0, + "", HFILL } + }, + { &hf_ranap_sDU_ErrorRatio_exponent, + { "sDU_ErrorRatio: exponent", + "ranap.rab_Parameters.sDU_ErrorRatio.exponent", + FT_UINT8, BASE_DEC, NULL, 0x0, + "", HFILL } + }, + { &hf_ranap_residualBitErrorRatio_mantissa, + { "residualBitErrorRatio: mantissa", + "ranap.rab_Parameters.residualBitErrorRatio.mantissa", + FT_UINT8, BASE_DEC, NULL, 0x0, + "", HFILL } + }, + { &hf_ranap_residualBitErrorRatio_exponent, + { "residualBitErrorRatio: exponent", + "ranap.rab_Parameters.residualBitErrorRatio.exponent", + FT_UINT8, BASE_DEC, NULL, 0x0, + "", HFILL } + }, + { &hf_ranap_deliveryOfErroneousSDU, + { "deliveryOfErroneousSDU", + "ranap.rab_Parameters.ranap_deliveryOfErroneousSDU", + FT_UINT8, BASE_DEC, VALS(&ranap_deliveryOfErroneousSDU_values), 0x0, + "", HFILL } + }, + { &hf_ranap_subflowSDU_Size, + { "subflowSDU_Size", + "ranap.rab_Parameters.subflowSDU_Size", + FT_UINT8, BASE_DEC, NULL, 0x0, + "", HFILL } + }, + { &hf_ranap_rAB_SubflowCombinationBitRate, + { "rAB_SubflowCombinationBitRate", + "ranap.rab_Parameters.rAB_SubflowCombinationBitRate", + FT_UINT32, BASE_DEC, NULL, 0x0, + "", HFILL } + }, + { &hf_ranap_sDU_ErrorRatio_present, + { "sDU_ErrorRatio", + "ranap.sDU_ErrorRatio_present", + FT_UINT8, BASE_HEX, VALS(&ranap_presence_values), 0x0, + "", HFILL } + }, + { &hf_ranap_sDU_FormatInformationParameters_present, + { "sDU_FormatInformationParameters", + "ranap.sDU_FormatInformationParameters_present", + FT_UINT8, BASE_HEX, VALS(&ranap_presence_values), 0x0, + "", HFILL } + }, + { &hf_ranap_subflowSDU_Size_present, + { "subflowSDU_Size", + "ranap.subflowSDU_Size_present", + FT_UINT8, BASE_HEX, VALS(&ranap_presence_values), 0x0, + "", HFILL } + }, + { &hf_ranap_rAB_SubflowCombinationBitRate_present, + { "subflowSDU_Size", + "ranap.rAB_SubflowCombinationBitRate_present", + FT_UINT8, BASE_HEX, VALS(&ranap_presence_values), 0x0, + "", HFILL } + }, + { &hf_ranap_transferDelay, + { "transferDelay", + "ranap.rab_Parameters.transferDelay", + FT_UINT16, BASE_DEC, NULL, 0x0, + "", HFILL } + }, + { &hf_ranap_trafficHandlingPriority, + { "trafficHandlingPriority", + "ranap.rab_Parameters.trafficHandlingPriority", + FT_UINT8, BASE_DEC, VALS(&ranap_priority_values), 0x0, + "", HFILL } + }, + { &hf_ranap_priorityLevel, + { "priorityLevel", + "ranap.rab_Parameters.allocationOrRetentionPriority.priorityLevel", + FT_UINT8, BASE_DEC, VALS(&ranap_priority_values), 0x0, + "", HFILL } + }, + { &hf_ranap_pre_emptionCapability, + { "pre-emptionCapability", + "ranap.rab_Parameters.allocationOrRetentionPriority.pre_emptionCapability", + FT_UINT8, BASE_DEC, VALS(&ranap_pre_emptionCapability_values), 0x0, + "", HFILL } + }, + { &hf_ranap_pre_emptionVulnerability, + { "pre-emptionVulnerability", + "ranap.rab_Parameters.allocationOrRetentionPriority.pre_emptionVulnerability", + FT_UINT8, BASE_DEC, VALS(&ranap_pre_emptionVulnerability_values), 0x0, + "", HFILL } + }, + { &hf_ranap_queuingAllowed, + { "queuingAllowed", + "ranap.rab_Parameters.allocationOrRetentionPriority.queuingAllowed", + FT_UINT8, BASE_DEC, VALS(&ranap_queuingAllowed_values), 0x0, + "", HFILL } + }, + { &hf_ranap_sourceStatisticsDescriptor, + { "sourceStatisticsDescriptor", + "ranap.rab_Parameters.sourceStatisticsDescriptor", + FT_UINT8, BASE_DEC, VALS(&ranap_sourceStatisticsDescriptor_values), 0x0, + "", HFILL } + }, + { &hf_ranap_relocationRequirement, + { "relocationRequirement", + "ranap.rab_Parameters.relocationRequirement", + FT_UINT8, BASE_DEC, VALS(&ranap_relocationRequirement_values), 0x0, + "", HFILL } + }, + { &hf_ranap_userPlaneMode, + { "userPlaneMode", + "ranap.userPlaneMode", + FT_UINT8, BASE_DEC, VALS(&ranap_userPlaneMode_values), 0x0, + "", HFILL } + }, + { &hf_ranap_uP_ModeVersions, + { "uP_ModeVersions", + "ranap.uP_ModeVersions", + FT_BYTES, BASE_NONE, NULL, 0x0, + "", HFILL } + }, + { &hf_ranap_number_of_ProtocolExtensionFields, + { "Number of ProtocolExtensionFields", + "ranap.number_of_ProtocolExtensionFields", + FT_UINT16, BASE_DEC, NULL, 0x0, + "", HFILL } + }, + { &hf_ranap_ext_field_number_of_octets, + { "Number of octets", + "ranap.ProtocolExtensionFields.octets", + FT_UINT16, BASE_DEC, NULL, 0x0, + "", HFILL } + }, + { &hf_ranap_transportLayerAddress_length, + { "bit length of transportLayerAddress", + "ranap.transportLayerAddress_length", + FT_UINT8, BASE_DEC, NULL, 0x0, + "", HFILL } + }, + { &hf_ranap_transportLayerAddress, + { "transportLayerAddress", + "ranap.transportLayerAddress", + FT_BYTES, BASE_NONE, NULL, 0x0, + "", HFILL } + }, + { &hf_ranap_gTP_TEI, + { "gTP_TEI", + "ranap.gTP_TEI", + FT_BYTES, BASE_NONE, NULL, 0x0, + "", HFILL } + }, + { &hf_ranap_bindingID, + { "bindingID", + "ranap.bindingID", + FT_BYTES, BASE_NONE, NULL, 0x0, + "", HFILL } + }, + { &hf_ranap_pDP_TypeInformation_present, + { "pDP_TypeInformation", + "ranap.pDP_TypeInformation_present", + FT_UINT8, BASE_HEX, VALS(&ranap_presence_values), 0x0, + "", HFILL } + }, + { &hf_ranap_dataVolumeReportingIndication_present, + { "dataVolumeReportingIndication", + "ranap.dataVolumeReportingIndication_present", + FT_UINT8, BASE_HEX, VALS(&ranap_presence_values), 0x0, + "", HFILL } + }, + { &hf_ranap_dl_GTP_PDU_SequenceNumber_present, + { "dl_GTP_PDU_SequenceNumber", + "ranap.dl_GTP_PDU_SequenceNumber_present", + FT_UINT8, BASE_HEX, VALS(&ranap_presence_values), 0x0, + "", HFILL } + }, + { &hf_ranap_ul_GTP_PDU_SequenceNumber_present, + { "ul_GTP_PDU_SequenceNumber", + "ranap.ul_GTP_PDU_SequenceNumber_present", + FT_UINT8, BASE_HEX, VALS(&ranap_presence_values), 0x0, + "", HFILL } + }, + { &hf_ranap_dl_N_PDU_SequenceNumber_present, + { "dl_N_PDU_SequenceNumber", + "ranap.dl_N_PDU_SequenceNumber_present", + FT_UINT8, BASE_HEX, VALS(&ranap_presence_values), 0x0, + "", HFILL } + }, + { &hf_ranap_ul_N_PDU_SequenceNumber_present, + { "ul_N_PDU_SequenceNumber", + "ranap.ul_N_PDU_SequenceNumber_present", + FT_UINT8, BASE_HEX, VALS(&ranap_presence_values), 0x0, + "", HFILL } + }, + { &hf_ranap_PDP_Type, + { "PDP-Type", + "ranap.RAB_SetupOrModifyItemSecond.PDP_Type", + FT_UINT8, BASE_HEX, VALS(&ranap_PDP_Type_values), 0x0, + "", HFILL } + }, + { &hf_ranap_dataVolumeReportingIndication, + { "dataVolumeReportingIndication", + "ranap.RAB_SetupOrModifyItemSecond.dataVolumeReportingIndication", + FT_UINT8, BASE_HEX, VALS(&ranap_dataVolumeReportingIndication_values), 0x0, + "", HFILL } + }, + { &hf_ranap_dl_GTP_PDU_SequenceNumber, + { "dl_GTP_PDU_SequenceNumber", + "ranap.RAB_SetupOrModifyItemSecond.dl_GTP_PDU_SequenceNumber", + FT_UINT16, BASE_DEC, NULL, 0x0, + "", HFILL } + }, + { &hf_ranap_ul_GTP_PDU_SequenceNumber, + { "ul_GTP_PDU_SequenceNumber", + "ranap.RAB_SetupOrModifyItemSecond.ul_GTP_PDU_SequenceNumber", + FT_UINT16, BASE_DEC, NULL, 0x0, + "", HFILL } + }, + { &hf_ranap_dl_N_PDU_SequenceNumber, + { "ul_GTP_PDU_SequenceNumber", + "ranap.RAB_SetupOrModifyItemSecond.ul_GTP_PDU_SequenceNumber", + FT_UINT16, BASE_DEC, NULL, 0x0, + "", HFILL } + }, + { &hf_ranap_ul_N_PDU_SequenceNumber, + { "ul_GTP_PDU_SequenceNumber", + "ranap.RAB_SetupOrModifyItemSecond.ul_GTP_PDU_SequenceNumber", + FT_UINT16, BASE_DEC, NULL, 0x0, + "", HFILL } + }, + { &hf_ranap_cause_choice, + { "cause choice", + "ranap.cause_choice", + FT_UINT8, BASE_HEX, VALS(&ranap_cause_choice_values), 0x0, + "", HFILL } + }, + { &hf_ranap_cause_value, + { "cause value", + "ranap.cause_value", + FT_UINT8, BASE_DEC,VALS(&ranap_cause_value_str), 0x0, + "", HFILL } + }, + { &hf_ranap_transportLayerAddress_present, + { "transportLayerAddress", + "ranap.transportLayerAddress_present", + FT_UINT8, BASE_HEX, VALS(&ranap_presence_values), 0x0, + "", HFILL } + }, + { &hf_ranap_iuTransportAssociation_present, + { "iuTransportAssociation", + "ranap.iuTransportAssociation_present", + FT_UINT8, BASE_HEX, VALS(&ranap_presence_values), 0x0, + "", HFILL } + }, + { &hf_ranap_dl_dataVolumes_present, + { "dl_dataVolumes", + "ranap.dl_dataVolumes_present", + FT_UINT8, BASE_HEX, VALS(&ranap_presence_values), 0x0, + "", HFILL } + }, + { &hf_ranap_dataVolumeReference_present, + { "dataVolumeReference", + "ranap.dataVolumeReference_present", + FT_UINT8, BASE_HEX, VALS(&ranap_presence_values), 0x0, + "", HFILL } + }, + { &hf_ranap_dl_UnsuccessfullyTransmittedDataVolume, + { "dl-UnsuccessfullyTransmittedDataVolume", + "ranap.dl-UnsuccessfullyTransmittedDataVolume", + FT_UINT32, BASE_DEC, NULL, 0x0, + "", HFILL } + }, + { &hf_ranap_dataVolumeReference, + { "dataVolumeReference", + "ranap.dataVolumeReference", + FT_UINT8, BASE_DEC, NULL, 0x0, + "", HFILL } + }, + { &hf_ranap_procedureCode_present, + { "procedureCode", + "ranap.procedureCode_present", + FT_UINT8, BASE_HEX, VALS(&ranap_presence_values), 0x0, + "", HFILL } + }, + { &hf_ranap_triggeringMessage_present, + { "triggeringMessage", + "ranap.triggeringMessage_present", + FT_UINT8, BASE_HEX, VALS(&ranap_presence_values), 0x0, + "", HFILL } + }, + { &hf_ranap_procedureCriticality_present, + { "procedureCriticality", + "ranap.procedureCriticality_present", + FT_UINT8, BASE_HEX, VALS(&ranap_presence_values), 0x0, + "", HFILL } + }, + { &hf_ranap_iEsCriticalityDiagnostics_present, + { "iEsCriticalityDiagnostics", + "ranap.iEsCriticalityDiagnostics_present", + FT_UINT8, BASE_HEX, VALS(&ranap_presence_values), 0x0, + "", HFILL } + }, + { &hf_ranap_triggeringMessage, + { "triggeringMessage", + "ranap.triggeringMessage", + FT_UINT8, BASE_HEX, VALS(&ranap_pdu_index_values), 0x0, + "", HFILL } + }, + { &hf_ranap_procedureCriticality, + { "procedureCriticality", + "ranap.procedureCriticality", + FT_UINT8, BASE_HEX, VALS(&ranap_criticality_values), 0x0, + "", HFILL } + }, + { &hf_ranap_iECriticality, + { "iECriticality", + "ranap.iECriticality", + FT_UINT8, BASE_HEX, VALS(&ranap_criticality_values), 0x0, + "", HFILL } + }, + { &hf_ranap_repetitionNumber, + { "repetitionNumber", + "ranap.repetitionNumber", + FT_UINT16, BASE_DEC, NULL, 0x0, + "", HFILL } + }, + { &hf_ranap_num_of_CriticalityDiagnostics_IEs, + { "Number of CriticalityDiagnostics-IEs", + "ranap.num_of_CriticalityDiagnostics_IEs", + FT_UINT16, BASE_DEC, NULL, 0x0, + "", HFILL } + }, + { &hf_ranap_repetitionNumber_present, + { "repetitionNumber", + "ranap.repetitionNumber_present", + FT_UINT8, BASE_HEX, VALS(&ranap_presence_values), 0x0, + "", HFILL } + }, + { &hf_ranap_dl_UnsuccessfullyTransmittedDataVolume_present, + { "dl-UnsuccessfullyTransmittedDataVolume", + "ranap.dl_UnsuccessfullyTransmittedDataVolume_present", + FT_UINT8, BASE_HEX, VALS(&ranap_presence_values), 0x0, + "", HFILL } + }, + { &hf_ranap_CN_DomainIndicator, + { "CN-DomainIndicator", + "ranap.CN_DomainIndicator", + FT_UINT8, BASE_HEX, VALS(&ranap_CN_DomainIndicator_values), 0x0, + "", HFILL } + }, + { &hf_ranap_service_Handover, + { "service-Handover", + "ranap.service_Handover", + FT_UINT8, BASE_HEX, VALS(&ranap_service_Handover_values), 0x0, + "", HFILL } + }, + { &hf_ranap_IuSigConId, + { "IuSigConId", + "ranap.IuSigConId", + FT_UINT24, BASE_DEC, NULL, 0x0, + "", HFILL } + }, + { &hf_ranap_SAPI, + { "SAPI", + "ranap.sapi", + FT_UINT8, BASE_HEX, VALS(&ranap_SAPI_values), 0x0, + "", HFILL } + }, + { &hf_ranap_msg_extension_present, + { "Message Extension", + "ranap.msg_extension_present", + FT_UINT8, BASE_HEX, VALS(&ranap_presence_values), 0x0, + "", HFILL } + }, + { &hf_ranap_ProtocolExtensionContainer_present, + { "ProtocolExtensionContainer", + "ranap.ProtocolExtensionContainer_present", + FT_UINT8, BASE_HEX, VALS(&ranap_presence_values), 0x0, + "", HFILL } + }, + { &hf_ranap_nas_pdu_length, + { "length of NAS-PDU", + "ranap.nas_pdu_length", + FT_UINT16, BASE_DEC, NULL, 0x0, + "", HFILL } + }, + { &hf_ranap_RNC_ID, + { "RNC ID", + "ranap.RNC_ID", + FT_UINT16, BASE_DEC, NULL, 0x0fff, + "", HFILL } + } + }; + + /* Setup protocol subtree array */ + static gint *ett[] = { + &ett_ranap, + &ett_ranap_optionals, + &ett_ranap_iE_Extension, + &ett_ranap_ie, + &ett_ranap_ie_pair, + &ett_ranap_rab, + &ett_ranap_ie_pair_first_value, + &ett_ranap_ie_pair_second_value, + &ett_ranap_sDU, + &ett_ranap_rAB_Parameters, + &ett_ranap_allocationOrRetentionPriority , + &ett_ranap_CriticalityDiagnostics_IE + }; + + + /* Register the protocol name and description */ + proto_ranap = proto_register_protocol("Radio Access Network Application Part", + "RANAP", "ranap"); + + /* Register the header fields and subtrees */ + proto_register_field_array(proto_ranap, hf, array_length(hf)); + proto_register_subtree_array(ett, array_length(ett)); + + nas_pdu_dissector_table = register_dissector_table("ranap.nas_pdu", "RANAP NAS PDU", FT_UINT8, BASE_DEC); +} + + +void +proto_reg_handoff_ranap(void) +{ + dissector_handle_t ranap_handle; + + ranap_handle = create_dissector_handle(dissect_ranap, proto_ranap); + /* + dissector_add("sua.ssn", SCCP_SSN_RANAP, ranap_handle); + */ + dissector_add("sccp.ssn", SCCP_SSN_RANAP, ranap_handle); + + /* Add heuristic dissector + * Perhaps we want a preference whether the heuristic dissector + * is or isn't enabled + */ + heur_dissector_add("sccp", dissect_sccp_ranap_heur, proto_ranap); +} |