diff options
author | Holger Hans Peter Freyther <holger@moiji-mobile.com> | 2015-06-02 15:52:06 +0200 |
---|---|---|
committer | Holger Hans Peter Freyther <holger@moiji-mobile.com> | 2015-06-02 15:52:06 +0200 |
commit | f558ed4bb9c0f00997b8f97c2b251a574c1a64c4 (patch) | |
tree | 16524d63b63a4c5496a9bc6412c3a9862367cc36 /src/gsm/ipa.c | |
parent | 91ff17c9ef7dd4a29bb13d6b9995100ffc65b72a (diff) |
ipa: Properly parse LV stream of a ID_GET request
For some reason the structure is closer to be a LV (length
and value). The value is actually a tag but it is counted
inside the length. Introduce an overload of the parse function
to provide an offset for the length. This will be taken from
the returned length.
Diffstat (limited to 'src/gsm/ipa.c')
-rw-r--r-- | src/gsm/ipa.c | 16 |
1 files changed, 13 insertions, 3 deletions
diff --git a/src/gsm/ipa.c b/src/gsm/ipa.c index 7cff1e81..dac20122 100644 --- a/src/gsm/ipa.c +++ b/src/gsm/ipa.c @@ -89,6 +89,11 @@ const char *ipa_ccm_idtag_name(uint8_t tag) int ipa_ccm_idtag_parse(struct tlv_parsed *dec, unsigned char *buf, int len) { + return ipa_ccm_idtag_parse_off(dec, buf, len, 0); +} + +int ipa_ccm_idtag_parse_off(struct tlv_parsed *dec, unsigned char *buf, int len, const int len_offset) +{ uint8_t t_len; uint8_t t_tag; uint8_t *cur = buf; @@ -100,6 +105,11 @@ int ipa_ccm_idtag_parse(struct tlv_parsed *dec, unsigned char *buf, int len) t_len = *cur++; t_tag = *cur++; + if (t_len < len_offset) { + LOGP(DLMI, LOGL_ERROR, "minimal offset not included: %d\n", t_len); + return -EINVAL; + } + if (t_len > len + 1) { LOGP(DLMI, LOGL_ERROR, "The tag does not fit: %d\n", t_len); return -EINVAL; @@ -107,11 +117,11 @@ int ipa_ccm_idtag_parse(struct tlv_parsed *dec, unsigned char *buf, int len) DEBUGPC(DLMI, "%s='%s' ", ipa_ccm_idtag_name(t_tag), cur); - dec->lv[t_tag].len = t_len; + dec->lv[t_tag].len = t_len - len_offset; dec->lv[t_tag].val = cur; - cur += t_len; - len -= t_len; + cur += t_len - len_offset; + len -= t_len - len_offset; } return 0; } |