mirror of https://gerrit.osmocom.org/libosmocore
gsm: add osmo_mobile_identity_decode_from_l3_buf()
We have osmo_mobile_identity_decode_from_l3(), which takes a msgb as argument, and decodes msg->l3h. Not all callers have their data in this form. Offer a more flexible API for the same decoding. For example, before the new function, osmo-hnbgw, which extracts a NAS PDU from asn.1 packed data for CN pooling, would allocate a new msgb and copy the NAS data just to pass a data pointer as argument. Related: SYS#6412 Change-Id: I9bd99ccd01f0eedc091fe51687ff92ae1fdff60b
This commit is contained in:
parent
e4b84738b5
commit
e25786ab6a
|
@ -96,6 +96,8 @@ char *osmo_mobile_identity_to_str_c(void *ctx, const struct osmo_mobile_identity
|
|||
int osmo_mobile_identity_cmp(const struct osmo_mobile_identity *a, const struct osmo_mobile_identity *b);
|
||||
int osmo_mobile_identity_decode(struct osmo_mobile_identity *mi, const uint8_t *mi_data, uint8_t mi_len,
|
||||
bool allow_hex);
|
||||
int osmo_mobile_identity_decode_from_l3_buf(struct osmo_mobile_identity *mi, const uint8_t *l3_data, size_t l3_len,
|
||||
bool allow_hex);
|
||||
int osmo_mobile_identity_decode_from_l3(struct osmo_mobile_identity *mi, struct msgb *msg, bool allow_hex);
|
||||
int osmo_mobile_identity_encoded_len(const struct osmo_mobile_identity *mi, int *mi_digits);
|
||||
int osmo_mobile_identity_encode_buf(uint8_t *buf, size_t buflen, const struct osmo_mobile_identity *mi, bool allow_hex);
|
||||
|
|
|
@ -863,11 +863,13 @@ int osmo_mobile_identity_encode_msgb(struct msgb *msg, const struct osmo_mobile_
|
|||
* osmo_mobile_identity.
|
||||
*
|
||||
* \param[out] mi Return buffer for decoded Mobile Identity.
|
||||
* \param[in] msg The Complete Layer 3 message to extract from (LU, CM Service Req or Paging Resp).
|
||||
* \param[in] l3_data The Complete Layer 3 message to extract from (LU, CM Service Req or Paging Resp).
|
||||
* \param[in] l3_len Length of l3_data in bytes.
|
||||
* \returns 0 on success, negative on error: return codes as defined in osmo_mobile_identity_decode(), or
|
||||
* -ENOTSUP = not a Complete Layer 3 message,
|
||||
*/
|
||||
int osmo_mobile_identity_decode_from_l3(struct osmo_mobile_identity *mi, struct msgb *msg, bool allow_hex)
|
||||
int osmo_mobile_identity_decode_from_l3_buf(struct osmo_mobile_identity *mi, const uint8_t *l3_data, size_t l3_len,
|
||||
bool allow_hex)
|
||||
{
|
||||
const struct gsm48_hdr *gh;
|
||||
int8_t pdisc = 0;
|
||||
|
@ -886,10 +888,10 @@ int osmo_mobile_identity_decode_from_l3(struct osmo_mobile_identity *mi, struct
|
|||
.tmsi = GSM_RESERVED_TMSI,
|
||||
};
|
||||
|
||||
if (msgb_l3len(msg) < sizeof(*gh))
|
||||
if (l3_len < sizeof(*gh))
|
||||
return -EBADMSG;
|
||||
|
||||
gh = msgb_l3(msg);
|
||||
gh = (void *)l3_data;
|
||||
pdisc = gsm48_hdr_pdisc(gh);
|
||||
mtype = gsm48_hdr_msg_type(gh);
|
||||
|
||||
|
@ -899,12 +901,12 @@ int osmo_mobile_identity_decode_from_l3(struct osmo_mobile_identity *mi, struct
|
|||
switch (mtype) {
|
||||
case GSM48_MT_MM_LOC_UPD_REQUEST:
|
||||
/* First make sure that lu-> can be dereferenced */
|
||||
if (msgb_l3len(msg) < sizeof(*gh) + sizeof(*lu))
|
||||
if (l3_len < sizeof(*gh) + sizeof(*lu))
|
||||
return -EBADMSG;
|
||||
|
||||
/* Now we know there is enough msgb data to read a lu->mi_len, so also check that */
|
||||
lu = (struct gsm48_loc_upd_req*)gh->data;
|
||||
if (msgb_l3len(msg) < sizeof(*gh) + sizeof(*lu) + lu->mi_len)
|
||||
if (l3_len < sizeof(*gh) + sizeof(*lu) + lu->mi_len)
|
||||
return -EBADMSG;
|
||||
mi_data = lu->mi;
|
||||
mi_len = lu->mi_len;
|
||||
|
@ -914,7 +916,7 @@ int osmo_mobile_identity_decode_from_l3(struct osmo_mobile_identity *mi, struct
|
|||
case GSM48_MT_MM_CM_REEST_REQ:
|
||||
/* Unfortunately in Phase1 the Classmark2 length is variable, so we cannot
|
||||
* just use gsm48_service_request struct, and need to parse it manually. */
|
||||
if (msgb_l3len(msg) < sizeof(*gh) + 2)
|
||||
if (l3_len < sizeof(*gh) + 2)
|
||||
return -EBADMSG;
|
||||
|
||||
cm2_len = gh->data[1];
|
||||
|
@ -922,7 +924,7 @@ int osmo_mobile_identity_decode_from_l3(struct osmo_mobile_identity *mi, struct
|
|||
goto got_cm2;
|
||||
|
||||
case GSM48_MT_MM_IMSI_DETACH_IND:
|
||||
if (msgb_l3len(msg) < sizeof(*gh) + sizeof(*idi))
|
||||
if (l3_len < sizeof(*gh) + sizeof(*idi))
|
||||
return -EBADMSG;
|
||||
idi = (struct gsm48_imsi_detach_ind*) gh->data;
|
||||
mi_data = idi->mi;
|
||||
|
@ -930,7 +932,7 @@ int osmo_mobile_identity_decode_from_l3(struct osmo_mobile_identity *mi, struct
|
|||
goto got_mi;
|
||||
|
||||
case GSM48_MT_MM_ID_RESP:
|
||||
if (msgb_l3len(msg) < sizeof(*gh) + 2)
|
||||
if (l3_len < sizeof(*gh) + 2)
|
||||
return -EBADMSG;
|
||||
mi_data = gh->data+1;
|
||||
mi_len = gh->data[0];
|
||||
|
@ -945,7 +947,7 @@ int osmo_mobile_identity_decode_from_l3(struct osmo_mobile_identity *mi, struct
|
|||
|
||||
switch (mtype) {
|
||||
case GSM48_MT_RR_PAG_RESP:
|
||||
if (msgb_l3len(msg) < sizeof(*gh) + sizeof(*paging_response))
|
||||
if (l3_len < sizeof(*gh) + sizeof(*paging_response))
|
||||
return -EBADMSG;
|
||||
paging_response = (struct gsm48_pag_resp*)gh->data;
|
||||
cm2_len = paging_response->cm2_len;
|
||||
|
@ -964,7 +966,7 @@ got_cm2:
|
|||
/* MI (Mobile Identity) LV follows the Classmark2 */
|
||||
|
||||
/* There must be at least a mi_len byte after the CM2 */
|
||||
if (cm2_buf + cm2_len + 1 > msg->tail)
|
||||
if (cm2_buf + cm2_len + 1 > l3_data + l3_len)
|
||||
return -EBADMSG;
|
||||
|
||||
mi_start = cm2_buf + cm2_len;
|
||||
|
@ -973,12 +975,27 @@ got_cm2:
|
|||
|
||||
got_mi:
|
||||
/* mi_data points at the start of the Mobile Identity coding of mi_len bytes */
|
||||
if (mi_data + mi_len > msg->tail)
|
||||
if (mi_data + mi_len > l3_data + l3_len)
|
||||
return -EBADMSG;
|
||||
|
||||
return osmo_mobile_identity_decode(mi, mi_data, mi_len, allow_hex);
|
||||
}
|
||||
|
||||
/*! Extract Mobile Identity from a Complete Layer 3 message.
|
||||
*
|
||||
* Determine the Mobile Identity data and call osmo_mobile_identity_decode() to return a decoded struct
|
||||
* osmo_mobile_identity.
|
||||
*
|
||||
* \param[out] mi Return buffer for decoded Mobile Identity.
|
||||
* \param[in] msg The Complete Layer 3 message to extract from (LU, CM Service Req or Paging Resp).
|
||||
* \returns 0 on success, negative on error: return codes as defined in osmo_mobile_identity_decode(), or
|
||||
* -ENOTSUP = not a Complete Layer 3 message,
|
||||
*/
|
||||
int osmo_mobile_identity_decode_from_l3(struct osmo_mobile_identity *mi, struct msgb *msg, bool allow_hex)
|
||||
{
|
||||
return osmo_mobile_identity_decode_from_l3_buf(mi, msgb_l3(msg), msgb_l3len(msg), allow_hex);
|
||||
}
|
||||
|
||||
/*! Return a human readable representation of a struct osmo_mobile_identity.
|
||||
* Write a string like "IMSI-1234567", "TMSI-0x1234ABCD" or "NONE", "NULL".
|
||||
* \param[out] buf String buffer to write to.
|
||||
|
|
|
@ -391,6 +391,7 @@ osmo_mobile_identity_to_str_buf;
|
|||
osmo_mobile_identity_to_str_c;
|
||||
osmo_mobile_identity_cmp;
|
||||
osmo_mobile_identity_decode;
|
||||
osmo_mobile_identity_decode_from_l3_buf;
|
||||
osmo_mobile_identity_decode_from_l3;
|
||||
osmo_mobile_identity_encoded_len;
|
||||
osmo_mobile_identity_encode_buf;
|
||||
|
|
Loading…
Reference in New Issue