diff options
Diffstat (limited to 'src/ranap_msg_factory.c')
-rw-r--r-- | src/ranap_msg_factory.c | 153 |
1 files changed, 78 insertions, 75 deletions
diff --git a/src/ranap_msg_factory.c b/src/ranap_msg_factory.c index 2ae2dbf..44b879f 100644 --- a/src/ranap_msg_factory.c +++ b/src/ranap_msg_factory.c @@ -20,6 +20,7 @@ #include <osmocom/core/utils.h> #include <osmocom/core/msgb.h> +#include <osmocom/core/socket.h> #include "asn1helpers.h" #include <osmocom/ranap/iu_helpers.h> @@ -42,6 +43,14 @@ static long *new_long(long in) struct msgb *ranap_new_msg_reset(RANAP_CN_DomainIndicator_t domain, const RANAP_Cause_t *cause) { + return ranap_new_msg_reset2(domain, cause, NULL); +} + +/*! generate RANAP RESET message. Like ranap_new_msg_reset(), but allows passing a Global-RNC-ID. */ +struct msgb *ranap_new_msg_reset2(RANAP_CN_DomainIndicator_t domain, + const RANAP_Cause_t *cause, + RANAP_GlobalRNC_ID_t *rnc_id) +{ RANAP_ResetIEs_t ies; RANAP_Reset_t out; struct msgb *msg; @@ -52,6 +61,14 @@ struct msgb *ranap_new_msg_reset(RANAP_CN_DomainIndicator_t domain, if (cause) memcpy(&ies.cause, cause, sizeof(ies.cause)); + if (rnc_id) { + ies.presenceMask = RESETIES_RANAP_GLOBALRNC_ID_PRESENT; + OCTET_STRING_noalloc(&ies.globalRNC_ID.pLMNidentity, + rnc_id->pLMNidentity.buf, + rnc_id->pLMNidentity.size); + ies.globalRNC_ID.rNC_ID = rnc_id->rNC_ID; + } + memset(&out, 0, sizeof(out)); rc = ranap_encode_reseties(&out, &ies); if (rc < 0) { @@ -202,18 +219,15 @@ struct msgb *ranap_new_msg_dt(uint8_t sapi, const uint8_t *nas, unsigned int nas return msg; } -static const enum RANAP_IntegrityProtectionAlgorithm ip_alg[2] = { - RANAP_IntegrityProtectionAlgorithm_standard_UMTS_integrity_algorithm_UIA1, - RANAP_IntegrityProtectionAlgorithm_standard_UMTS_integrity_algorithm_UIA2, -}; - -static const RANAP_EncryptionAlgorithm_t enc_alg[2] = { - RANAP_EncryptionAlgorithm_standard_UMTS_encryption_algorith_UEA1, - RANAP_EncryptionAlgorithm_standard_UMTS_encryption_algorithm_UEA2, -}; - -/*! \brief generate RANAP SECURITY MODE COMMAND message */ -struct msgb *ranap_new_msg_sec_mod_cmd(const uint8_t *ik, const uint8_t *ck, enum RANAP_KeyStatus status) +/*! \brief generate RANAP SECURITY MODE COMMAND message. + * \param[in] ik 128bit integrity protection key (mandatory) + * \param[in] ck 128bit ciphering key (optional) + * \param[in] status key status + * \param[in] uia_bitmask bit-mask of UIA algorithms; Bit0 = UIA0 .. Bit2 = UIA2 + * \param[in] uea_bitmask bit-mask of UEA algorithms; Bit0 = UEA0 .. Bit2 = UEA2; ck required + * \returns message buffer with encoded command message */ +struct msgb *ranap_new_msg_sec_mod_cmd2(const uint8_t *ik, const uint8_t *ck, enum RANAP_KeyStatus status, + uint8_t uia_bitmask, uint8_t uea_bitmask) { RANAP_SecurityModeCommandIEs_t ies; RANAP_SecurityModeCommand_t out; @@ -223,11 +237,26 @@ struct msgb *ranap_new_msg_sec_mod_cmd(const uint8_t *ik, const uint8_t *ck, enu memset(&ies, 0, sizeof(ies)); memset(&out, 0, sizeof(out)); - for (i = 0; i < ARRAY_SIZE(ip_alg); i++) { + for (i = 0; i < 8; i++) { + RANAP_IntegrityProtectionAlgorithm_t ialg; + if (!(uia_bitmask & (1 << i))) + continue; + switch (i) { + case 1: + ialg = RANAP_IntegrityProtectionAlgorithm_standard_UMTS_integrity_algorithm_UIA1; + break; + case 2: + ialg = RANAP_IntegrityProtectionAlgorithm_standard_UMTS_integrity_algorithm_UIA2; + break; + default: + LOGP(DRANAP, LOGL_ERROR, "Unsupported UIA algorithm UIA%d specified\n", i); + return NULL; + } + /* needs to be dynamically allocated, as * SET_OF_free() will call FREEMEM() on it */ RANAP_IntegrityProtectionAlgorithm_t *alg = CALLOC(1, sizeof(*alg)); - *alg = ip_alg[i]; + *alg = ialg; ASN_SEQUENCE_ADD(&ies.integrityProtectionInformation.permittedAlgorithms, alg); } @@ -235,11 +264,27 @@ struct msgb *ranap_new_msg_sec_mod_cmd(const uint8_t *ik, const uint8_t *ck, enu if (ck) { ies.presenceMask = SECURITYMODECOMMANDIES_RANAP_ENCRYPTIONINFORMATION_PRESENT; - for (i = 0; i < ARRAY_SIZE(ip_alg); i++) { + for (i = 0; i < 8; i++) { + RANAP_EncryptionAlgorithm_t ealg; + if (!(uea_bitmask & (1 << i))) + continue; + switch (i) { + case 1: + ealg = RANAP_EncryptionAlgorithm_standard_UMTS_encryption_algorith_UEA1; + break; + case 2: + ealg = RANAP_EncryptionAlgorithm_standard_UMTS_encryption_algorithm_UEA2; + break; + default: + LOGP(DRANAP, LOGL_ERROR, "Unsupported UEA algorithm UEA%d specified\n", i); + asn_set_empty(&ies.integrityProtectionInformation.permittedAlgorithms); + return NULL; + } + /* needs to be dynamically allocated, as * SET_OF_free() will call FREEMEM() on it */ RANAP_EncryptionAlgorithm_t *alg = CALLOC(1, sizeof(*alg)); - *alg = enc_alg[i]; + *alg = ealg; ASN_SEQUENCE_ADD(&ies.encryptionInformation.permittedAlgorithms, alg); } BIT_STRING_fromBuf(&ies.encryptionInformation.key, ck, 16*8); @@ -271,6 +316,10 @@ struct msgb *ranap_new_msg_sec_mod_cmd(const uint8_t *ik, const uint8_t *ck, enu return msg; } +struct msgb *ranap_new_msg_sec_mod_cmd(const uint8_t *ik, const uint8_t *ck, enum RANAP_KeyStatus status) +{ + return ranap_new_msg_sec_mod_cmd2(ik, ck, status, 0x06, 0x06); +} /*! \brief generate RANAP SECURITY MODE COMPLETE message */ struct msgb *ranap_new_msg_sec_mod_compl( @@ -659,61 +708,6 @@ static RANAP_RAB_Parameters_t *new_rab_par_data(uint32_t dl_max_bitrate, uint32_ return rab; } -static void new_transp_layer_addr(BIT_STRING_t *out, uint32_t ip, bool use_x213_nsap) -{ - uint8_t *buf; - unsigned int len; - uint32_t ip_h = ntohl(ip); - - if (use_x213_nsap) { - len = 160/8; - buf = CALLOC(len, sizeof(uint8_t)); - buf[0] = 0x35; /* AFI For IANA ICP */ - buf[1] = 0x00; /* See A.5.2.1.2.7 of X.213 */ - buf[2] = 0x01; - memcpy(&buf[3], &ip_h, sizeof(ip_h)); - } else { - len = sizeof(ip_h); - buf = CALLOC(len, sizeof(uint8_t)); - memcpy(buf, &ip_h, sizeof(ip_h)); - } - out->buf = buf; - out->size = len; - out->bits_unused = 0; -} - -static RANAP_TransportLayerInformation_t *new_transp_info_rtp(uint32_t ip, uint16_t port, - bool use_x213_nsap) -{ - RANAP_TransportLayerInformation_t *tli = CALLOC(1, sizeof(*tli)); - uint8_t binding_id[4]; - - binding_id[0] = port >> 8; - binding_id[1] = port & 0xff; - binding_id[2] = binding_id[3] = 0; - - new_transp_layer_addr(&tli->transportLayerAddress, ip, use_x213_nsap); - tli->iuTransportAssociation.present = RANAP_IuTransportAssociation_PR_bindingID; - OCTET_STRING_fromBuf(&tli->iuTransportAssociation.choice.bindingID, - (const char *) binding_id, sizeof(binding_id)); - - return tli; -} - -static RANAP_TransportLayerInformation_t *new_transp_info_gtp(uint32_t ip, uint32_t tei, - bool use_x213_nsap) -{ - RANAP_TransportLayerInformation_t *tli = CALLOC(1, sizeof(*tli)); - uint32_t binding_buf = htonl(tei); - - new_transp_layer_addr(&tli->transportLayerAddress, ip, use_x213_nsap); - tli->iuTransportAssociation.present = RANAP_IuTransportAssociation_PR_gTP_TEI; - OCTET_STRING_fromBuf(&tli->iuTransportAssociation.choice.gTP_TEI, - (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)); @@ -754,6 +748,7 @@ struct msgb *ranap_new_msg_rab_assign_voice(uint8_t rab_id, uint32_t rtp_ip, RANAP_RAB_AssignmentRequest_t out; struct msgb *msg; int rc; + struct osmo_sockaddr rtp_addr; memset(&ies, 0, sizeof(ies)); memset(&out, 0, sizeof(out)); @@ -768,8 +763,11 @@ struct msgb *ranap_new_msg_rab_assign_voice(uint8_t rab_id, uint32_t rtp_ip, first.nAS_SynchronisationIndicator = new_rab_nas_sync_ind(60); first.rAB_Parameters = new_rab_par_voice(6700, 12200); first.userPlaneInformation = new_upi(RANAP_UserPlaneMode_support_mode_for_predefined_SDU_sizes, 1); /* 2? */ - first.transportLayerInformation = new_transp_info_rtp(rtp_ip, rtp_port, - use_x213_nsap); + + rtp_addr.u.sin.sin_family = AF_INET; + rtp_addr.u.sin.sin_port = htons(rtp_port); + rtp_addr.u.sin.sin_addr.s_addr = htonl(rtp_ip); + first.transportLayerInformation = ranap_new_transp_info_rtp(&rtp_addr, use_x213_nsap); /* put together the 'Second' part */ RANAP_RAB_SetupOrModifyItemSecond_t second; @@ -823,6 +821,7 @@ struct msgb *ranap_new_msg_rab_assign_data(uint8_t rab_id, uint32_t gtp_ip, RANAP_DataVolumeReportingIndication_t *dat_vol_ind; struct msgb *msg; int rc; + struct osmo_sockaddr gtp_addr; memset(&ies, 0, sizeof(ies)); memset(&out, 0, sizeof(out)); @@ -838,8 +837,10 @@ struct msgb *ranap_new_msg_rab_assign_data(uint8_t rab_id, uint32_t gtp_ip, first.rAB_Parameters = new_rab_par_data(1600000, 800000); first.userPlaneInformation = new_upi(RANAP_UserPlaneMode_transparent_mode, 1); - first.transportLayerInformation = new_transp_info_gtp(gtp_ip, gtp_tei, - use_x213_nsap); + + gtp_addr.u.sin.sin_family = AF_INET; + gtp_addr.u.sin.sin_addr.s_addr = htonl(gtp_ip); + first.transportLayerInformation = ranap_new_transp_info_gtp(>p_addr, gtp_tei, use_x213_nsap); /* put together the 'Second' part */ RANAP_RAB_SetupOrModifyItemSecond_t second; @@ -891,6 +892,7 @@ struct msgb *ranap_new_msg_rab_assign_data(uint8_t rab_id, uint32_t gtp_ip, return msg; } +/*! \brief generate RANAP IU RELEASE REQUEST message */ struct msgb *ranap_new_msg_iu_rel_req(const RANAP_Cause_t *cause) { RANAP_Iu_ReleaseRequestIEs_t ies; @@ -920,6 +922,7 @@ struct msgb *ranap_new_msg_iu_rel_req(const RANAP_Cause_t *cause) return msg; } +/*! \brief generate RANAP RAB RELEASE REQUEST message */ struct msgb *ranap_new_msg_rab_rel_req(uint8_t rab_id, const RANAP_Cause_t *cause) { RANAP_RAB_ReleaseItemIEs_t item_ies; |