From 091039d47e619c01979a4d6fb278b7fb0528e29d Mon Sep 17 00:00:00 2001 From: Harald Welte Date: Thu, 17 Dec 2015 20:37:40 +0100 Subject: test-ranap.c: More WIP code for convoluted RANAP message encoding --- src/tests/test-ranap.c | 314 ++++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 283 insertions(+), 31 deletions(-) diff --git a/src/tests/test-ranap.c b/src/tests/test-ranap.c index c8e0280..bb091b7 100644 --- a/src/tests/test-ranap.c +++ b/src/tests/test-ranap.c @@ -1,4 +1,9 @@ +#include "asn1helpers.h" +#include "iu_helpers.h" + +#include "ranap_common.h" +#include "ranap_ies_defs.h" /* This is just some non-compiling work in progress code to generate the * minimum set of RANAP messages that the core network side needs to send @@ -38,8 +43,8 @@ static const enum RANAP_IntegrityProtectionAlgorithm ip_alg[2] = { RANAP_IntegrityProtectionAlgorithm_standard_UMTS_integrity_algorithm_UIA2, }; -static const enum RANAP_EncryptionAlgorithm enc_alg[2] = { - RANAP_EncryptionAlgorithm_standard_UMTS_encryption_algorithm_UEA1, +static const RANAP_EncryptionAlgorithm_t enc_alg[2] = { + RANAP_EncryptionAlgorithm_standard_UMTS_encryption_algorith_UEA1, RANAP_EncryptionAlgorithm_standard_UMTS_encryption_algorithm_UEA2, }; @@ -48,21 +53,32 @@ int ranap_tx_sec_mod_cmd(void) RANAP_SecurityModeCommandIEs_t ies; RANAP_SecurityModeCommand_t out; struct msgb *msg; - int rc; + int i, rc; memset(&ies, 0, sizeof(ies)); ies.presenceMask = SECURITYMODECOMMANDIES_RANAP_ENCRYPTIONINFORMATION_PRESENT; - ASN_SEQUENCE_ADD(&ies.integrityProtectionInformation.permittedAlgorithms, &ip_alg[0]); - ASN_SEQUENCE_ADD(&ies.integrityProtectionInformation.permittedAlgorithms, &ip_alg[1]); + for (i = 0; i < ARRAY_SIZE(ip_alg); i++) { + /* needs to be dynamically allocated, as + * SET_OF_free() will call FREEMEM() on it */ + RANAP_IntegrityProtectionAlgorithm_t *alg = MALLOC(*alg); + *alg = ip_alg[i]; + ASN_SEQUENCE_ADD(&ies.integrityProtectionInformation.permittedAlgorithms, alg); + } ies.integrityProtectionInformation.key; /* FIXME */ if (0) { - ASN_SEQUENCE_ADD(&ies.encryptionInformation.permittedAlgorithms, &enc_alg[0]); - ASN_SEQUENCE_ADD(&ies.encryptionInformation.permittedAlgorithms, &enc_alg[1]); + for (i = 0; i < ARRAY_SIZE(ip_alg); i++) { + /* needs to be dynamically allocated, as + * SET_OF_free() will call FREEMEM() on it */ + RANAP_EncryptionAlgorithm_t *alg = MALLOC(*alg); + *alg = enc_alg[i]; + ASN_SEQUENCE_ADD(&ies.encryptionInformation.permittedAlgorithms, alg); + } ies.encryptionInformation.key; /* FIXME */ } + ies.keyStatus = RANAP_KeyStatus_new; /* FIXME */ rc = ranap_encode_securitymodecommandies(&out, &ies); @@ -114,14 +130,17 @@ int ranap_tx_iu_rel_cmd(RANAP_Cause_t cause) msg = ranap_generate_initiating_message(RANAP_ProcedureCode_id_Iu_Release, RANAP_Criticality_reject, - &asn_DEF_RANAP_ReleaseCommand, + &asn_DEF_RANAP_Iu_ReleaseCommand, &out); } -int ranap_tx_paging_cmd(const char *imsi, uint32_t *tmsi, uint32_t cause) +int ranap_tx_paging_cmd(const char *imsi, uint32_t *tmsi, int is_ps, uint32_t cause) { - RANAP_PagingIEs_s ies; + RANAP_PagingIEs_t ies; RANAP_Paging_t out; + struct msgb *msg; + uint8_t *imsi_buf = CALLOC(1, 16); + int rc; memset(&ies, 0, sizeof(ies)); @@ -130,7 +149,10 @@ int ranap_tx_paging_cmd(const char *imsi, uint32_t *tmsi, uint32_t cause) else ies.cN_DomainIndicator = RANAP_CN_DomainIndicator_cs_domain; - ies.permanentNAS_UE_ID; /* FIXME */ + rc = encode_iu_imsi(imsi_buf, 16, imsi); + ies.permanentNAS_UE_ID.present = RANAP_PermanentNAS_UE_ID_PR_iMSI; + ies.permanentNAS_UE_ID.choice.iMSI.buf = imsi_buf; + ies.permanentNAS_UE_ID.choice.iMSI.size = rc; if (tmsi) { ies.presenceMask |= PAGINGIES_RANAP_TEMPORARYUE_ID_PRESENT; @@ -150,35 +172,224 @@ int ranap_tx_paging_cmd(const char *imsi, uint32_t *tmsi, uint32_t cause) rc = ranap_encode_iu_pagingies(&out, &ies); - msg = ranap_generate_initiating_message(RANAP_ProcedureCode_id_Iu_Paging, + msg = ranap_generate_initiating_message(RANAP_ProcedureCode_id_Paging, RANAP_Criticality_reject, &asn_DEF_RANAP_Paging, &out); } +static RANAP_SDU_ErrorRatio_t *new_sdu_error_ratio(long mantissa, long exponent) +{ + RANAP_SDU_ErrorRatio_t *err = CALLOC(1, sizeof(*err)); + err->mantissa = mantissa; + err->exponent = exponent; -static RANAP_RAB_Parameters_t rab_par_voice = { - .trafficClass = RANAP_TrafficClass_conversational, - .rAB_AsymmetryIndicator = ANAP_RAB_AsymmetryIndicator_symmetric_bidirectional - .maxBitrate = , - .deliveryOrder = RANAP_DeliveryOrder_delivery_order_not_requested - .maxSDU_Size = 1234, - .sDU_Parameters = , -}; + return err; +} + + +static RANAP_SDU_FormatInformationParameters_t * +new_format_info_pars(long sdu_size) +{ + RANAP_SDU_FormatInformationParameters_t *fmti = CALLOC(1, sizeof(*fmti)); + fmti->subflowSDU_Size = new_long(sdu_size); + return fmti; +} -static RANAP_UserPlaneInformation_t rab_upl_voice = { - .userPlaneMode = RANAP_UserPlaneMode_transparent_mode, - .uP_ModeVersions = FIXME, +enum sdu_par_profile { + SDUPAR_P_VOICE0, + SDUPAR_P_VOICE1, + SDUPAR_P_VOICE2, + SDUPAR_P_DATA, }; -int ranap_tx_rab_assign() +static RANAP_SDU_Parameters_t *new_sdu_pars(enum sdu_par_profile profile) +{ + RANAP_SDU_Parameters_t *sdup = MALLOC(sizeof(*sdup)); + RANAP_SDU_FormatInformationParameters_t *fmti; + + memset(&sdup, 0, sizeof(sdup)); + + switch (profile) { + case SDUPAR_P_VOICE0: + sdup->sDU_ErrorRatio = new_sdu_error_ratio(1, 5); + sdup->residualBitErrorRatio.mantissa = 1; + sdup->residualBitErrorRatio.exponent = 6; + sdup->deliveryOfErroneousSDU = RANAP_DeliveryOfErroneousSDU_yes; + fmti = new_format_info_pars(81); + ASN_SEQUENCE_ADD(&sdup->sDU_FormatInformationParameters, fmti); + fmti = new_format_info_pars(39); + ASN_SEQUENCE_ADD(&sdup->sDU_FormatInformationParameters, fmti); + /* FIXME: could be 10 SDU descriptors for AMR! */ + break; + case SDUPAR_P_VOICE1: + sdup->residualBitErrorRatio.mantissa = 1; + sdup->residualBitErrorRatio.exponent = 3; + sudp->deliveryOfErroneousSDU = RANAP_DeliveryOfErroneousSDU_no_error_detection_consideration; + fmti = new_format_info_pars(103); + ASN_SEQUENCE_ADD(&sdup->sDU_FormatInformationParameters, fmti); + fmti = new_format_info_pars(0); + ASN_SEQUENCE_ADD(&sdup->sDU_FormatInformationParameters, fmti); + /* FIXME: could be 10 SDU descriptors for AMR! */ + break; + case SDUPAR_P_VOICE2: + sdup->residualBitErrorRatio.mantissa = 5; + sdup->residualBitErrorRatio.exponent = 3; + sudp->deliveryOfErroneousSDU = RANAP_DeliveryOfErroneousSDU_no_error_detection_consideration; + fmti = new_format_info_pars(60); + ASN_SEQUENCE_ADD(&sdup->sDU_FormatInformationParameters, fmti); + fmti = new_format_info_pars(0); + ASN_SEQUENCE_ADD(&sdup->sDU_FormatInformationParameters, fmti); + /* FIXME: could be 10 SDU descriptors for AMR! */ + break; + case SDUPAR_P_DATA: + sdup->sDU_ErrorRatio = new_sdu_error_ratio(1, 4); + sdup->residualBitErrorRatio.mantissa = 1; + sdup->residualBitErrorRatio.exponent = 5; + sdup->deliveryOfErroneousSDU = RANAP_DeliveryOfErroneousSDU_no; + break; + } + + return sdup; +} + +static long *new_long(long in) +{ + long *out = MALLOC(sizeof(long)); + *out = in; + return out; +} + +static RANAP_AllocationOrRetentionPriority_t * +new_alloc_ret_prio(RANAP_PriorityLevel_t level, bool capability, bool vulnerability, + bool qeueing_allowed) +{ + RANAP_AllocationOrRetentionPriority_t *arp = MALLOC(sizeof(*arp)); + + arp->priorityLevel = level; + + if (capability) + arp->pre_emptionCapability = RANAP_Pre_emptionCapability_may_trigger_pre_emption; + else + arp->pre_emptionCapability = RANAP_Pre_emptionCapability_shall_not_trigger_pre_emption; + + if (vulnerability) + arp->pre_emptionVulnerability = RANAP_Pre_emptionVulnerability_pre_emptable; + else + arp->pre_emptionVulnerability = RANAP_Pre_emptionVulnerability_not_pre_emptable; + + if (queueing_allowed) + arp->queuingAllowed = RANAP_QueuingAllowed_queueing_allowed; + else + arp->queuingAllowed = RANAP_QueuingAllowed_queueing_not_allowed; + + return arp; +} + +static RANAP_RAB_Parameters_t *new_rab_par_voice(void) +{ + RANAP_RAB_Parameters_t *rab = CALLOC(1, sizeof(*rab)); + + rab->trafficClass = RANAP_TrafficClass_conversational; + rab->rAB_AsymmetryIndicator = RANAP_RAB_AsymmetryIndicator_symmetric_bidirectional; + + ASN_SEQUENCE_ADD(&rab->maxBitrate, new_long(12200)); + rab->guaranteedBitrate = MALLOC(sizeof(*rab->guaranteedBitrate)); + ASN_SEQUENCE_ADD(&rab->guaranteedBitrate, new_long(12200)); + rab->deliveryOrder = RANAP_DeliveryOrder_delivery_order_requested; + rab->maxSDU_Size = 244; + + sdup = new_sdu_pars(SDUPAR_P_VOICE0); + ASN_SEQUENCE_ADD(&rab->sDU_Parameters, sdup); + sdup = new_sdu_pars(SDUPAR_P_VOICE1); + ASN_SEQUENCE_ADD(&rab->sDU_Parameters, sdup); + sdup = new_sdu_pars(SDUPAR_P_VOICE2); + ASN_SEQUENCE_ADD(&rab->sDU_Parameters, sdup); + + rab->transferDelay = new_long(80); + rab->allocationOrRetentionPriority = new_alloc_ret_prio(RANAP_PriorityLevel_no_priority, 0, 1, 0); + + rab->sourceStatisticsDescriptor = new_long(RANAP_SourceStatisticsDescriptor_speech); + + return rab; +} + +static RANAP_RAB_Parameters_t *new_rab_par_data(void) +{ + RANAP_RAB_Parameters_t *rab = CALLOC(1, sizeof(*rab)); + + rab->trafficClass = RANAP_TrafficClass_background; + rab->rAB_AsymmetryIndicator = RANAP_RAB_AsymmetryIndicator_asymmetric_bidirectional; + + ASN_SEQUENCE_ADD(&rab->maxBitrate, new_long(16000000)); + ASN_SEQUENCE_ADD(&rab->maxBitrate, new_long(8000000)); + rab->deliveryOrder = RANAP_DeliveryOrder_delivery_order_requested; + rab->maxSDU_Size = 8000; + + sdup = new_sdu_pars(SDUPAR_P_DATA); + ASN_SEQUENCE_ADD(&rab->sDU_Parameters, sdup); + + rab->allocationOrRetentionPriority = new_alloc_ret_prio(RANAP_PriorityLevel_no_priority, 0, 0, 0); + + /* FIXME: RAB-Parameter-ExtendedMaxBitrateList for 42Mbps? */ + + return rab; +} + +static RANAP_TransportLayerInformation_t *new_transp_info_rtp(uint32_t ip, uint16_t port) +{ + RANAP_TransportLayerInformation_t *tli = CALLOC(1, sizeof(*tli)); + uint32_t *ipbuf = CALLOC(1, sizeof(*ipbuf)); + uint8_t binding_id[4]; + + binding_id[0] = port >> 8; + binding_id[1] = port & 0xff; + binding_id[2] = binding_id[3] = 0; + + asn1_u32_to_bitstring(&tli->transportLayerAddress, ipbuf, htonl(ip)); + tli->iuTransportAssociation.present = RANAP_IuTransportAssociation_PR_bindingID; + OCTET_STRING_fromBuf(tli->iuTransportAssociation.choice.bindingID.buf, + (const char *) binding_id, sizeof(binding_id)); + + return tli; +} + +static RANAP_TransportLayerInformation_t *new_transp_info_gtp(uint32_t ip, uint32_t tei) +{ + RANAP_TransportLayerInformation_t *tli = CALLOC(1, sizeof(*tli)); + uint32_t *ipbuf = CALLOC(1, sizeof(*ipbuf)); + uint32_t binding_buf = htonl(tei); + + asn1_u32_to_bitstring(&tli->transportLayerAddress, ipbuf, htonl(ip)); + tli->iuTransportAssociation.present = RANAP_IuTransportAssociation_PR_gTP_TEI; + OCTET_STRING_fromBuf(&tli->iuTransportAssociation.choice.bindingID, + (const char *) binding_buf, sizeof(binding_buf)); + + return tli; +} + +static RANAP_UserPlaneInformation_t *new_upi(long mode, uint8_t mode_versions) +{ + RANAP_UserPlaneInformation_t *upi = CALLOC(1, sizeof(*upi)); + uint8_t *buf = CALLOC(1, sizeof(*buf)); + + *buf = mode_versions; + + upi->userPlaneMode = mode; + upi->uP_ModeVersions.buf = buf; + upi->uP_ModeVersions.size = 1; + upi->uP_ModeVersions.bits_unused = 0; + + return upi; +} + +int ranap_tx_rab_assign_voice(uint8_t rab_id) { RANAP_ProtocolIE_FieldPair_t *pair; RANAP_RAB_AssignmentRequestIEs_t ies; RANAP_RAB_AssignmentRequest_t out; - memset(&ies, 0, sizeof(ies)); ies.presenceMask = RAB_ASSIGNMENTREQUESTIES_RANAP_RAB_SETUPORMODIFYLIST_PRESENT; @@ -186,20 +397,61 @@ int ranap_tx_rab_assign() RANAP_RAB_SetupOrModifyItemFirst_t first; - first.rAB_ID = FIXME; + first.rAB_ID = rab_id; first.nAS_SynchronisationIndicator = FIXME; - first.rAB_Parameters = &rab_par_voice; - first.userPlaneInformation = &rab_upl_voice; - first.transportLayerInformation = NULL; + first.rAB_Parameters = new_rab_par_voice(); + first.userPlaneInformation = new_upi(RANAP_UserPlaneMode_support_mode_for_predefined_SDU_sizes, 1); /* 2? */ + first.transportLayerInformation = new_transp_info_rtp(ip, port); RANAP_RAB_SetupOrModifyItemSecond_t second; + memset(&second, 0, sizeof(second)); + pair = ranap_new_ie_pair(RANAP_ProtocolIE_ID_id_RAB_SetupOrModifyItem, + RANAP_Criticality_reject, + &asn_DEF_RANAP_RAB_SetupOrModifyItemFirst, &first, + RANAP_Criticality_ignore, + &asn_DEF_RANAP_RAB_SetupOrModifyItemSecond, &second); + + ASN_SEQUENCE_ADD(&ies.raB_SetupOrModifyList.list, pair); + + rc = ranap_encode_rab_assignmentrequesties(&out, &ies); +} + +int ranap_tx_rab_assign_data(uint8_t rab_id, uint32_t gtp_ip, uint16_t gtp_port) +{ + RANAP_ProtocolIE_FieldPair_t *pair; + RANAP_RAB_AssignmentRequestIEs_t ies; + RANAP_RAB_AssignmentRequest_t out; + RANAP_DataVolumeReportingIndication_t *dat_vol_ind = CALLOC(1, sizeof(*dat_vol_ind)); + int rc; + + memset(&ies, 0, sizeof(ies)); + + ies.presenceMask = RAB_ASSIGNMENTREQUESTIES_RANAP_RAB_SETUPORMODIFYLIST_PRESENT; + /* RANAP_RAB_IE_ContainerPairList_t */ + + RANAP_RAB_SetupOrModifyItemFirst_t first; + + first.rAB_ID = rab_id; + first.nAS_SynchronisationIndicator = FIXME; + first.rAB_Parameters = new_rab_par_data(); + first.userPlaneInformation = new_upi(RANAP_UserPlaneMode_transparent_mode, 1); + first.transportLayerInformation = new_transp_info_rtp(gtp_ip, gtp_port); + + RANAP_RAB_SetupOrModifyItemSecond_t second; + memset(&second, 0, sizeof(second)); + second.pDP_TypeInformation = CALLOC(1, sizeof(*second.pDP_TypeInformation)); + ASN_SEQUENCE_ADD(&second.pDP_TypeInformation, new_long(RANAP_PDP_Type_ipv4)); + *dat_vol_ind = RANAP_DataVolumeReportingIndication_do_not_report; + second.dataVolumeReportingIndication = dat_vol_ind; + second.dl_GTP_PDU_SequenceNumber = new_long(0); + second.ul_GTP_PDU_SequenceNumber = new_long(0); pair = ranap_new_ie_pair(RANAP_ProtocolIE_ID_id_RAB_SetupOrModifyItem, RANAP_Criticality_reject, - SetupOrModifyItemFirst, &first, + &asn_DEF_RANAP_RAB_SetupOrModifyItemFirst, &first, RANAP_Criticality_ignore, - SetupOrModifyItemSecond, &second); + &asn_DEF_RANAP_RAB_SetupOrModifyItemSecond, &second); ASN_SEQUENCE_ADD(&ies.raB_SetupOrModifyList.list, pair); -- cgit v1.2.3