dexter has uploaded this change for review. ( https://gerrit.osmocom.org/c/osmo-hnbgw/+/27138 )
Change subject: ranap_rab_ass: ensure specific rab_id ......................................................................
ranap_rab_ass: ensure specific rab_id
The parser functions currently ignore the rab_id. An exception is ranap_rab_ass_req_ies_extract_inet_addr, which extracts the rab_id of the first RAB. To make the handling of the RAB assignment parsing more robust lets add a rab_id parameter to the other functions. This parameter can then be used to ensure thet the correct RAB is handled.
Change-Id: I2259ffce9f4b508c555d60618c5983ac6294e0ae Related: OS#5152 --- M include/osmocom/hnbgw/ranap_rab_ass.h M src/osmo-hnbgw/ranap_rab_ass.c M tests/ranap_rab_ass/ranap_rab_ass_test.c M tests/ranap_rab_ass/ranap_rab_ass_test.ok 4 files changed, 116 insertions(+), 58 deletions(-)
git pull ssh://gerrit.osmocom.org:29418/osmo-hnbgw refs/changes/38/27138/1
diff --git a/include/osmocom/hnbgw/ranap_rab_ass.h b/include/osmocom/hnbgw/ranap_rab_ass.h index 4cb8e37..f4d5cb6 100644 --- a/include/osmocom/hnbgw/ranap_rab_ass.h +++ b/include/osmocom/hnbgw/ranap_rab_ass.h @@ -6,8 +6,11 @@ RANAP_RAB_AssignmentResponseIEs_t *rab_assignment_response_ies);
int ranap_rab_ass_req_ies_extract_inet_addr(struct osmo_sockaddr *addr, uint8_t *rab_id, - RANAP_RAB_AssignmentRequestIEs_t *ies); -int ranap_rab_ass_resp_ies_extract_inet_addr(struct osmo_sockaddr *addr, RANAP_RAB_AssignmentResponseIEs_t *ies); + RANAP_RAB_AssignmentRequestIEs_t *ies, unsigned int index); +int ranap_rab_ass_resp_ies_extract_inet_addr(struct osmo_sockaddr *addr, RANAP_RAB_AssignmentResponseIEs_t *ies, + uint8_t rab_id);
-int ranap_rab_ass_req_ies_replace_inet_addr(RANAP_RAB_AssignmentRequestIEs_t *ies, struct osmo_sockaddr *addr); -int ranap_rab_ass_resp_ies_replace_inet_addr(RANAP_RAB_AssignmentResponseIEs_t *ies, struct osmo_sockaddr *addr); +int ranap_rab_ass_req_ies_replace_inet_addr(RANAP_RAB_AssignmentRequestIEs_t *ies, struct osmo_sockaddr *addr, + uint8_t rab_id); +int ranap_rab_ass_resp_ies_replace_inet_addr(RANAP_RAB_AssignmentResponseIEs_t *ies, struct osmo_sockaddr *addr, + uint8_t rab_id); diff --git a/src/osmo-hnbgw/ranap_rab_ass.c b/src/osmo-hnbgw/ranap_rab_ass.c index f5d86a1..23505f2 100644 --- a/src/osmo-hnbgw/ranap_rab_ass.c +++ b/src/osmo-hnbgw/ranap_rab_ass.c @@ -111,10 +111,9 @@ return rc; }
-/* Pick the first item from the RAB setup-or-modify list and return the first protocol-ie-field-pair. This is based on - * the assumption that a PS call will only assign a signle RAB. This could be different for video calls and IMS but - * those are in practice a corner case, so we go for this simplified assumption for now. */ -static RANAP_ProtocolIE_FieldPair_t *prot_ie_field_pair_from_ass_req_ies(const RANAP_RAB_AssignmentRequestIEs_t *ies) +/* Pick the indexed item from the RAB setup-or-modify list and return the first protocol-ie-field-pair. */ +static RANAP_ProtocolIE_FieldPair_t *prot_ie_field_pair_from_ass_req_ies(const RANAP_RAB_AssignmentRequestIEs_t *ies, + unsigned int index) { RANAP_ProtocolIE_ContainerPair_t *protocol_ie_container_pair; RANAP_ProtocolIE_FieldPair_t *protocol_ie_field_pair; @@ -126,14 +125,19 @@ return NULL; }
- protocol_ie_container_pair = ies->raB_SetupOrModifyList.list.array[0]; + /* Detect the end of the list */ + if (index >= ies->raB_SetupOrModifyList.list.count) + return NULL; + + protocol_ie_container_pair = ies->raB_SetupOrModifyList.list.array[index]; protocol_ie_field_pair = protocol_ie_container_pair->list.array[0];
return protocol_ie_field_pair; }
-/* See also comment above prot_ie_field_pair_from_ass_req_ies */ -static RANAP_IE_t *setup_or_modif_item_from_rab_ass_resp(const RANAP_RAB_AssignmentResponseIEs_t *ies) +/* Pick the indexed item from the RAB setup-or-modified list and return a pointer to it */ +static RANAP_IE_t *setup_or_modif_item_from_rab_ass_resp(const RANAP_RAB_AssignmentResponseIEs_t *ies, + unsigned int index) { /* Make sure we indeed deal with a setup-or-modified list */ if (!(ies->presenceMask & RAB_ASSIGNMENTRESPONSEIES_RANAP_RAB_SETUPORMODIFIEDLIST_PRESENT)) { @@ -142,16 +146,82 @@ return NULL; }
- return ies->raB_SetupOrModifiedList.raB_SetupOrModifiedList_ies.list.array[0]; + /* Detect the end of the list */ + if (index >= ies->raB_SetupOrModifiedList.raB_SetupOrModifiedList_ies.list.count) + return NULL; + + return ies->raB_SetupOrModifiedList.raB_SetupOrModifiedList_ies.list.array[index]; +} + +/* find the RAB specified by rab_id in ies and when found, decode the result into items_ies */ +static int decode_rab_smditms_from_resp_ies(RANAP_RAB_SetupOrModifiedItemIEs_t *items_ies, + RANAP_RAB_AssignmentResponseIEs_t *ies, uint8_t rab_id) +{ + RANAP_IE_t *setup_or_modified_list_ie; + RANAP_RAB_SetupOrModifiedItem_t *rab_setup_or_modified_item; + int rc; + uint8_t rab_id_decoded; + unsigned int index = 0; + + while (1) { + setup_or_modified_list_ie = setup_or_modif_item_from_rab_ass_resp(ies, index); + if (!setup_or_modified_list_ie) + return -EINVAL; + + rc = ranap_decode_rab_setupormodifieditemies_fromlist(items_ies, &setup_or_modified_list_ie->value); + if (rc < 0) + return -EINVAL; + + rab_setup_or_modified_item = &items_ies->raB_SetupOrModifiedItem; + /* The RAB-ID is defined as a bitstring with a size of 8 (1 byte), + * See also RANAP-IEs.asn, RAB-ID ::= BIT STRING (SIZE (8)) */ + rab_id_decoded = rab_setup_or_modified_item->rAB_ID.buf[0]; + if (rab_id_decoded == rab_id) + return index; + + ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_RANAP_RAB_SetupOrModifiedItem, items_ies); + index++; + } +} + +/* find the RAB specified by rab_id in ies and when found, decode the result into item */ +static int decode_rab_smditms_from_req_ies(RANAP_RAB_SetupOrModifyItemFirst_t *item, + RANAP_RAB_AssignmentRequestIEs_t *ies, uint8_t rab_id) +{ + RANAP_ProtocolIE_FieldPair_t *protocol_ie_field_pair; + int rc; + uint8_t rab_id_decoded; + unsigned int index = 0; + + while (1) { + protocol_ie_field_pair = prot_ie_field_pair_from_ass_req_ies(ies, index); + if (!protocol_ie_field_pair) + return -EINVAL; + + if (protocol_ie_field_pair->id != RANAP_ProtocolIE_ID_id_RAB_SetupOrModifyItem) { + RANAP_DEBUG + ("Decoding failed, the protocol IE field-pair is not of type RANAP RAB setup-or-modify-item!\n"); + return -EINVAL; + } + + rc = ranap_decode_rab_setupormodifyitemfirst(item, &protocol_ie_field_pair->firstValue); + if (rc < 0) + return -EINVAL; + + rab_id_decoded = item->rAB_ID.buf[0]; + if (rab_id_decoded == rab_id) + return index; + } }
/*! Extract IP address and port from RANAP_RAB_AssignmentRequestIEs. * \ptmap[out] addr user provided memory to store extracted RTP stream IP-Address and port number. * \ptmap[out] rab_id pointer to store RAB-ID (optional, can be NULL). * \ptmap[in] ies user provided memory with RANAP_RAB_AssignmentRequestIEs. + * \ptmap[in] index index of the SetupOrModifyItem (e.g. 0 for the first list item). * \returns 0 on success; negative on error. */ int ranap_rab_ass_req_ies_extract_inet_addr(struct osmo_sockaddr *addr, uint8_t *rab_id, - RANAP_RAB_AssignmentRequestIEs_t *ies) + RANAP_RAB_AssignmentRequestIEs_t *ies, unsigned int index) { RANAP_ProtocolIE_FieldPair_t *protocol_ie_field_pair; RANAP_RAB_SetupOrModifyItemFirst_t _rab_setup_or_modify_item_first; @@ -161,7 +231,7 @@ uint16_t port; int rc;
- protocol_ie_field_pair = prot_ie_field_pair_from_ass_req_ies(ies); + protocol_ie_field_pair = prot_ie_field_pair_from_ass_req_ies(ies, index); if (!protocol_ie_field_pair) return -EINVAL;
@@ -219,26 +289,20 @@ /*! Extract IP address and port from RANAP_RAB_AssignmentResponseIEs. * \ptmap[out] addr user provided memory to store extracted RTP stream IP-Address and port number. * \ptmap[in] ies user provided memory with RANAP_RAB_AssignmentResponseIEs. + * \ptmap[in] rab_id expected rab id to look for. * \returns 0 on success; negative on error. */ -int ranap_rab_ass_resp_ies_extract_inet_addr(struct osmo_sockaddr *addr, RANAP_RAB_AssignmentResponseIEs_t *ies) +int ranap_rab_ass_resp_ies_extract_inet_addr(struct osmo_sockaddr *addr, RANAP_RAB_AssignmentResponseIEs_t *ies, uint8_t rab_id) { - RANAP_IE_t *setup_or_modified_list_ie; RANAP_RAB_SetupOrModifiedItemIEs_t _rab_setup_or_modified_items_ies; RANAP_RAB_SetupOrModifiedItemIEs_t *rab_setup_or_modified_items_ies = &_rab_setup_or_modified_items_ies; RANAP_RAB_SetupOrModifiedItem_t *rab_setup_or_modified_item; uint16_t port; int rc;
- setup_or_modified_list_ie = setup_or_modif_item_from_rab_ass_resp(ies); - if (!setup_or_modified_list_ie) + rc = decode_rab_smditms_from_resp_ies(rab_setup_or_modified_items_ies, ies, rab_id); + if (rc < 0) return -EINVAL;
- rc = ranap_decode_rab_setupormodifieditemies_fromlist(rab_setup_or_modified_items_ies, - &setup_or_modified_list_ie->value); - if (rc < 0) { - return -EINVAL; - } - rab_setup_or_modified_item = &rab_setup_or_modified_items_ies->raB_SetupOrModifiedItem;
/* Decode IP-Address */ @@ -276,8 +340,9 @@ /*! Replace IP address and port in RANAP_RAB_AssignmentRequestIEs. * \ptmap[inout] ies user provided memory with RANAP_RAB_AssignmentRequestIEs. * \ptmap[in] addr user provided memory that contains the new RTP stream IP-Address and port number. + * \ptmap[in] rab_id expected rab id to look for. * \returns 0 on success; negative on error. */ -int ranap_rab_ass_req_ies_replace_inet_addr(RANAP_RAB_AssignmentRequestIEs_t *ies, struct osmo_sockaddr *addr) +int ranap_rab_ass_req_ies_replace_inet_addr(RANAP_RAB_AssignmentRequestIEs_t *ies, struct osmo_sockaddr *addr, uint8_t rab_id) { RANAP_ProtocolIE_FieldPair_t *protocol_ie_field_pair; RANAP_RAB_SetupOrModifyItemFirst_t _rab_setup_or_modify_item_first; @@ -287,20 +352,10 @@ struct osmo_sockaddr addr_old; bool uses_x213_nsap; int rc; + int index;
- protocol_ie_field_pair = prot_ie_field_pair_from_ass_req_ies(ies); - if (!protocol_ie_field_pair) - return -EINVAL; - - if (protocol_ie_field_pair->id != RANAP_ProtocolIE_ID_id_RAB_SetupOrModifyItem) { - RANAP_DEBUG("Rewriting transport layer information failed, unexpected IE field-pair type!\n"); - return -EINVAL; - } - - /* Decode setup-or-modifiy item (first) */ - rc = ranap_decode_rab_setupormodifyitemfirst(rab_setup_or_modify_item_first, - &protocol_ie_field_pair->firstValue); - if (rc < 0) + index = decode_rab_smditms_from_req_ies(rab_setup_or_modify_item_first, ies, rab_id); + if (index < 0) return -EINVAL;
/* Replace transport-layer-information */ @@ -332,6 +387,7 @@ }
/* Reencode transport-layer-information */ + protocol_ie_field_pair = prot_ie_field_pair_from_ass_req_ies(ies, index); rc = ANY_fromType_aper(&protocol_ie_field_pair->firstValue, &asn_DEF_RANAP_RAB_SetupOrModifyItemFirst, rab_setup_or_modify_item_first); if (rc < 0) { @@ -354,8 +410,9 @@ /*! Replace IP address and port in RANAP_RAB_AssignmentResponseIEs. * \ptmap[inout] ies user provided memory with RANAP_RAB_AssignmentResponseIEs. * \ptmap[in] addr user provided memory that contains the new RTP stream IP-Address and port number. + * \ptmap[in] rab_id expected rab id to look for. * \returns 0 on success; negative on error. */ -int ranap_rab_ass_resp_ies_replace_inet_addr(RANAP_RAB_AssignmentResponseIEs_t *ies, struct osmo_sockaddr *addr) +int ranap_rab_ass_resp_ies_replace_inet_addr(RANAP_RAB_AssignmentResponseIEs_t *ies, struct osmo_sockaddr *addr, uint8_t rab_id) { RANAP_IE_t *setup_or_modified_list_ie; RANAP_RAB_SetupOrModifiedItemIEs_t _rab_setup_or_modified_items_ies; @@ -367,14 +424,10 @@ struct osmo_sockaddr addr_old; bool uses_x213_nsap; int rc; + int index;
- setup_or_modified_list_ie = setup_or_modif_item_from_rab_ass_resp(ies); - if (!setup_or_modified_list_ie) - return -EINVAL; - - rc = ranap_decode_rab_setupormodifieditemies_fromlist(rab_setup_or_modified_items_ies, - &setup_or_modified_list_ie->value); - if (rc < 0) + index = decode_rab_smditms_from_resp_ies(rab_setup_or_modified_items_ies, ies, rab_id); + if (index < 0) return -EINVAL;
rab_setup_or_modified_item = &rab_setup_or_modified_items_ies->raB_SetupOrModifiedItem; @@ -402,6 +455,7 @@ rab_setup_or_modified_item->iuTransportAssociation = &temp_transport_layer_information->iuTransportAssociation;
/* Reencode modified setup or modified list */ + setup_or_modified_list_ie = setup_or_modif_item_from_rab_ass_resp(ies, index); rc = ANY_fromType_aper(&setup_or_modified_list_ie->value, &asn_DEF_RANAP_RAB_SetupOrModifiedItem, rab_setup_or_modified_items_ies); if (rc < 0) { diff --git a/tests/ranap_rab_ass/ranap_rab_ass_test.c b/tests/ranap_rab_ass/ranap_rab_ass_test.c index c67b5aa..d7bee09 100644 --- a/tests/ranap_rab_ass/ranap_rab_ass_test.c +++ b/tests/ranap_rab_ass/ranap_rab_ass_test.c @@ -121,7 +121,7 @@
rc = ranap_ran_rx_co_decode(talloc_asn1_ctx, &message, testvec, sizeof(testvec)); OSMO_ASSERT(rc == 0); - rc = ranap_rab_ass_req_ies_extract_inet_addr(&addr, &rab_id, &message.msg.raB_AssignmentRequestIEs); + rc = ranap_rab_ass_req_ies_extract_inet_addr(&addr, &rab_id, &message.msg.raB_AssignmentRequestIEs, 0); osmo_sockaddr_str_from_sockaddr(&addr_str, &addr.u.sas); printf("ranap_rab_ass_req_extract_inet_addr rc=%d\n", rc); printf("RESULT: addr=%s, port=%u, rab-id=%02x\n", addr_str.ip, addr_str.port, rab_id); @@ -145,7 +145,7 @@
rc = ranap_cn_rx_co_decode(talloc_asn1_ctx, &message, testvec, sizeof(testvec)); OSMO_ASSERT(rc == 0); - rc = ranap_rab_ass_resp_ies_extract_inet_addr(&addr, &message.msg.raB_AssignmentResponseIEs); + rc = ranap_rab_ass_resp_ies_extract_inet_addr(&addr, &message.msg.raB_AssignmentResponseIEs, 7); osmo_sockaddr_str_from_sockaddr(&addr_str, &addr.u.sas); printf("ranap_rab_ass_resp_extract_inet_addr rc=%d\n", rc); printf("RESULT: addr=%s, port=%u\n", addr_str.ip, addr_str.port); @@ -158,6 +158,7 @@ struct osmo_sockaddr addr; struct osmo_sockaddr_str addr_str; ranap_message message; + uint8_t rab_id; uint8_t testvec_in[] = { 0x00, 0x00, 0x00, 0x59, 0x00, 0x00, 0x01, 0x00, 0x36, 0x40, 0x52, 0x00, 0x00, 0x01, 0x00, 0x35, @@ -190,10 +191,10 @@ rc = ranap_ran_rx_co_decode(talloc_asn1_ctx, &message, testvec_in, sizeof(testvec_in)); OSMO_ASSERT(rc == 0);
- rc = ranap_rab_ass_req_ies_extract_inet_addr(&addr, NULL, &message.msg.raB_AssignmentRequestIEs); + rc = ranap_rab_ass_req_ies_extract_inet_addr(&addr, &rab_id, &message.msg.raB_AssignmentRequestIEs, 0); OSMO_ASSERT(rc == 0); osmo_sockaddr_str_from_sockaddr(&addr_str, &addr.u.sas); - printf("before: addr=%s, port=%u\n", addr_str.ip, addr_str.port); + printf("before: addr=%s, port=%u, rab_id=%u\n", addr_str.ip, addr_str.port, rab_id);
memset(&addr_str, 0, sizeof(addr_str)); addr_str.af = AF_INET; @@ -201,13 +202,13 @@ osmo_strlcpy(addr_str.ip, "1.2.3.4", sizeof(addr_str.ip)); osmo_sockaddr_str_to_sockaddr(&addr_str, &addr.u.sas);
- rc = ranap_rab_ass_req_ies_replace_inet_addr(&message.msg.raB_AssignmentRequestIEs, &addr); + rc = ranap_rab_ass_req_ies_replace_inet_addr(&message.msg.raB_AssignmentRequestIEs, &addr, rab_id); printf("ranap_rab_ass_req_replace_inet_addr rc=%d\n", rc);
- rc = ranap_rab_ass_req_ies_extract_inet_addr(&addr, NULL, &message.msg.raB_AssignmentRequestIEs); + rc = ranap_rab_ass_req_ies_extract_inet_addr(&addr, &rab_id, &message.msg.raB_AssignmentRequestIEs, 0); OSMO_ASSERT(rc == 0); osmo_sockaddr_str_from_sockaddr(&addr_str, &addr.u.sas); - printf("after: addr=%s, port=%u\n", addr_str.ip, addr_str.port); + printf("after: addr=%s, port=%u, rab_id=%u\n", addr_str.ip, addr_str.port, rab_id);
rc = ranap_rab_ass_req_encode(testvec_in, sizeof(testvec_in), &message.msg.raB_AssignmentRequestIEs); OSMO_ASSERT(rc == sizeof(testvec_in)); @@ -242,7 +243,7 @@ rc = ranap_cn_rx_co_decode(talloc_asn1_ctx, &message, testvec_in, sizeof(testvec_in)); OSMO_ASSERT(rc == 0);
- rc = ranap_rab_ass_resp_ies_extract_inet_addr(&addr, &message.msg.raB_AssignmentResponseIEs); + rc = ranap_rab_ass_resp_ies_extract_inet_addr(&addr, &message.msg.raB_AssignmentResponseIEs, 6); OSMO_ASSERT(rc == 0); osmo_sockaddr_str_from_sockaddr(&addr_str, &addr.u.sas); printf("before: addr=%s, port=%u\n", addr_str.ip, addr_str.port); @@ -253,10 +254,10 @@ osmo_strlcpy(addr_str.ip, "1.2.3.4", sizeof(addr_str.ip)); osmo_sockaddr_str_to_sockaddr(&addr_str, &addr.u.sas);
- rc = ranap_rab_ass_resp_ies_replace_inet_addr(&message.msg.raB_AssignmentResponseIEs, &addr); + rc = ranap_rab_ass_resp_ies_replace_inet_addr(&message.msg.raB_AssignmentResponseIEs, &addr, 6); printf("ranap_rab_ass_resp_replace_inet_addr rc=%d\n", rc);
- rc = ranap_rab_ass_resp_ies_extract_inet_addr(&addr, &message.msg.raB_AssignmentResponseIEs); + rc = ranap_rab_ass_resp_ies_extract_inet_addr(&addr, &message.msg.raB_AssignmentResponseIEs, 6); OSMO_ASSERT(rc == 0); osmo_sockaddr_str_from_sockaddr(&addr_str, &addr.u.sas); printf("after: addr=%s, port=%u\n", addr_str.ip, addr_str.port); diff --git a/tests/ranap_rab_ass/ranap_rab_ass_test.ok b/tests/ranap_rab_ass/ranap_rab_ass_test.ok index f7b4b67..97756cb 100644 --- a/tests/ranap_rab_ass/ranap_rab_ass_test.ok +++ b/tests/ranap_rab_ass/ranap_rab_ass_test.ok @@ -8,9 +8,9 @@ RESULT: addr=10.9.1.162, port=8054, rab-id=11 ranap_rab_ass_resp_extract_inet_addr rc=0 RESULT: addr=10.9.1.164, port=1034 -before: addr=10.9.1.162, port=8122 +before: addr=10.9.1.162, port=8122, rab_id=39 ranap_rab_ass_req_replace_inet_addr rc=0 -after: addr=1.2.3.4, port=1234 +after: addr=1.2.3.4, port=1234, rab_id=39 before: addr=10.9.1.164, port=1034 ranap_rab_ass_resp_replace_inet_addr rc=0 after: addr=1.2.3.4, port=1234