aboutsummaryrefslogtreecommitdiffstats
path: root/src/ranap_msg_factory.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/ranap_msg_factory.c')
-rw-r--r--src/ranap_msg_factory.c153
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(&gtp_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;