add lots of Q.931 decoder error logging

This commit is contained in:
Harald Welte 2022-10-16 18:24:48 +02:00
parent 01a0539eb6
commit 246242822c
1 changed files with 56 additions and 27 deletions

View File

@ -4,6 +4,7 @@
#include <osmocom/gsm/tlv.h>
#include "q931.h"
#include "log.h"
/* Table 4-3/Q.931 */
const struct tlv_definition q931_tlv_def = {
@ -60,22 +61,31 @@ int q931_msg_parse(struct q931_msg_parsed *out, const uint8_t *buf, size_t len)
memset(out, 0, sizeof(*out));
/* at least protocol discriminator + length of call-ref must be present */
if (len < 2)
if (len < 2) {
LOGP(DQ931, LOGL_ERROR, "short Q.931 message: %s\n", osmo_hexdump(buf, len));
return -EMSGSIZE;
}
/* check protocol discriminator */
if (buf[0] != 0x08)
if (buf[0] != 0x08) {
LOGP(DQ931, LOGL_ERROR, "unknoqn Q.931 protocol discrimnator 0x%02x: %s", buf[0],
osmo_hexdump(buf, len));
return -EINVAL;
}
/* parse [variable length] call reference */
cref_len = buf[1] & 0x0F;
if (len < 2U + cref_len)
if (len < 2U + cref_len) {
LOGP(DQ931, LOGL_ERROR, "short Q.931 message: %s\n", osmo_hexdump(buf, len));
return -EMSGSIZE;
}
out->call_ref = q931_decode_callref(buf+1, len-1);
/* parse message type */
if (len < 2U + cref_len + 1U)
if (len < 2U + cref_len + 1U) {
LOGP(DQ931, LOGL_ERROR, "short Q.931 message: %s\n", osmo_hexdump(buf, len));
return -EMSGSIZE;
}
out->msg_type = buf[2+cref_len] & 0x7f;
/* parse 'other IEs' */
@ -83,8 +93,10 @@ int q931_msg_parse(struct q931_msg_parsed *out, const uint8_t *buf, size_t len)
other_ie_len = len - (2 + cref_len + 1);
if (other_ie_len) {
rc = tlv_parse(&out->ies, &q931_tlv_def, other_ie, other_ie_len, 0, 0);
if (rc < 0)
if (rc < 0) {
LOGP(DQ931, LOGL_ERROR, "Can't TLV-parse Q.931 message: %s\n", osmo_hexdump(buf, len));
return rc;
}
}
return 0;
@ -98,17 +110,17 @@ uint32_t q931_decode_callref(const uint8_t *data, uint8_t len)
bool flag;
if (len < 1)
return 0;
goto err;
len_of_callref = data[0] & 0x0f;
if (len_of_callref == 0)
return 0;
goto err;
if (len_of_callref > 4)
return 0;
goto err;
if (len - 1 < len_of_callref)
return 0;
goto err;
/* first octet contains flag, needs special handling */
if (data[1] & 0x80)
@ -123,6 +135,10 @@ uint32_t q931_decode_callref(const uint8_t *data, uint8_t len)
callref |= 0x80000000;
return callref;
err:
LOGP(DQ931, LOGL_ERROR, "Unable to decode Q.931 call reference: %s\n",
osmo_hexdump(data, len));
return 0;
}
/* Decode a (subset of) Q.931 channel identification IE from binary to struct representation */
@ -133,19 +149,19 @@ int q931_decode_channel_id(struct q931_channel_id *out, const uint8_t *data, uin
memset(out, 0, sizeof(*out));
if (len < 1)
return -1;
goto err;
if (! (data[0] & 0x80))
return -1;
goto err;
if (data[0] & 0x40) {
out->interface_id_present = true;
cur++;
if (len < 1 + (cur - data))
return -1;
goto err;
/* we only support single-octet interface ID */
if (!(*cur & 0x80))
return -1;
goto err;
out->interface_id = *cur & 0x7f;
}
@ -169,23 +185,23 @@ int q931_decode_channel_id(struct q931_channel_id *out, const uint8_t *data, uin
/* Octet 3.2 */
cur++;
if (len < 1 + (cur - data))
return -1;
goto err;
if (!(*cur & 0x80))
return -1;
goto err;
/* do we care about the coding standard? */
/* we only support single channel numbers */
if (*cur & 0x10)
return -1;
goto err;
/* we only support B-channels */
if ((*cur & 0x0f) != 0x03)
return -1;
goto err;
/* Octet 3.3 */
cur++;
if (len < 1 + (cur - data))
return -1;
goto err;
/* we only support single channel numbers */
if (!(*cur & 0x80))
return -1;
goto err;
out->b_channel = *cur & 0x7f;
}
break;
@ -193,7 +209,7 @@ int q931_decode_channel_id(struct q931_channel_id *out, const uint8_t *data, uin
if (out->interface_type_pri == false)
out->b_channel = 2;
else
return -1;
goto err;
break;
case 3:
out->info_chan_type = Q931_INFO_CHAN_T_ANY;
@ -202,6 +218,11 @@ int q931_decode_channel_id(struct q931_channel_id *out, const uint8_t *data, uin
}
return 0;
err:
LOGP(DQ931, LOGL_ERROR, "Unable to decode Q.931 channel id: %s\n",
osmo_hexdump(data, len));
return -1;
}
/* Q.931 Section 4.5.8 */
@ -210,20 +231,24 @@ int q931_decode_called_party(struct q931_party_number *out, const uint8_t *buf,
memset(out, 0, sizeof(*out));
if (len < 1)
return -1;
goto err;
/* Octet 3 */
if (!(*buf & 0x80))
return -1;
goto err;
out->type_of_number = (*buf >> 4) & 0x7;
out->numbering_plan_id = *buf & 0xf;
for (unsigned int i = 0; i < len - 1; i++) {
if (i >= sizeof(out->digits))
return -1;
goto err;
out->digits[i] = buf[1+i] & 0x7f;
}
return 0;
err:
LOGP(DQ931, LOGL_ERROR, "Unable to decode Q.931 called party: %s\n",
osmo_hexdump(buf, len));
return -1;
}
/* Q.931 Section 4.5.10 */
@ -234,7 +259,7 @@ int q931_decode_calling_party(struct q931_party_number *out, const uint8_t *buf,
memset(out, 0, sizeof(*out));
if (len < 1)
return -1;
goto err;
/* Octet 3 */
out->type_of_number = (*cur >> 4) & 0x7;
@ -243,9 +268,9 @@ int q931_decode_calling_party(struct q931_party_number *out, const uint8_t *buf,
/* Octet 3a */
cur++;
if (len < 2)
return -1;
goto err;
if (!(*cur & 0x80))
return -1;
goto err;
out->presentation_ind = (*cur >> 5) & 0x3;
out->screening_ind = *cur & 0x3;
}
@ -253,8 +278,12 @@ int q931_decode_calling_party(struct q931_party_number *out, const uint8_t *buf,
for (unsigned int i = 0; i < len - (cur - buf); i++) {
if (i >= sizeof(out->digits))
return -1;
goto err;
out->digits[i] = cur[i] & 0x7f;
}
return 0;
err:
LOGP(DQ931, LOGL_ERROR, "Unable to decode Q.931 calling party: %s\n",
osmo_hexdump(buf, len));
return -1;
}