From 246242822ca35a028b41a349eabf3ee5b6fe5a6c Mon Sep 17 00:00:00 2001 From: Harald Welte Date: Sun, 16 Oct 2022 18:24:48 +0200 Subject: [PATCH] add lots of Q.931 decoder error logging --- src/q931_decode.c | 83 ++++++++++++++++++++++++++++++++--------------- 1 file changed, 56 insertions(+), 27 deletions(-) diff --git a/src/q931_decode.c b/src/q931_decode.c index 49ae3af..1cefc74 100644 --- a/src/q931_decode.c +++ b/src/q931_decode.c @@ -4,6 +4,7 @@ #include #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; }