From: Sergey Kostanbaev Sergey.Kostanbaev@gmail.com
--- src/gsm/gsm0480.c | 6 ------ 1 file changed, 6 deletions(-)
diff --git a/src/gsm/gsm0480.c b/src/gsm/gsm0480.c index 8963b78..55bddd5 100644 --- a/src/gsm/gsm0480.c +++ b/src/gsm/gsm0480.c @@ -248,12 +248,6 @@ int gsm0480_decode_ss_request(const struct gsm48_hdr *hdr, uint16_t len, struct ss_request *req) { int rc = 0; - - if (len < sizeof(*hdr) + 2) { - LOGP(0, LOGL_DEBUG, "SS Request is too short.\n"); - return 0; - } - if (gsm48_hdr_pdisc(hdr) == GSM48_PDISC_NC_SS) { req->transaction_id = hdr->proto_discr & 0x70; rc = parse_ss(hdr, len, req);
From: Sergey Kostanbaev Sergey.Kostanbaev@gmail.com
--- src/gsm/gsm0480.c | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-)
diff --git a/src/gsm/gsm0480.c b/src/gsm/gsm0480.c index 55bddd5..9fc77a0 100644 --- a/src/gsm/gsm0480.c +++ b/src/gsm/gsm0480.c @@ -196,6 +196,8 @@ static int parse_ss(const struct gsm48_hdr *hdr, uint16_t len, struct ss_request *req); static int parse_ss_info_elements(const uint8_t *ussd_ie, uint16_t len, struct ss_request *req); +static int parse_ss_facility(const uint8_t *ss_facility, uint16_t len, + struct ss_request *req); static int parse_facility_ie(const uint8_t *facility_ie, uint16_t length, struct ss_request *req); static int parse_ss_invoke(const uint8_t *invoke_data, uint16_t length, @@ -271,9 +273,11 @@ static int parse_ss(const struct gsm48_hdr *hdr, uint16_t len, struct ss_request req->ussd_text[0] = 0xFF; break; case GSM0480_MTYPE_REGISTER: - case GSM0480_MTYPE_FACILITY: rc &= parse_ss_info_elements(&hdr->data[0], len - sizeof(*hdr), req); break; + case GSM0480_MTYPE_FACILITY: + rc &= parse_ss_facility(&hdr->data[0], len - sizeof(*hdr), req); + break; default: LOGP(0, LOGL_DEBUG, "Unknown GSM 04.80 message-type field 0x%02x\n", hdr->msg_type); @@ -284,6 +288,18 @@ static int parse_ss(const struct gsm48_hdr *hdr, uint16_t len, struct ss_request return rc; }
+static int parse_ss_facility(const uint8_t *ss_facility, uint16_t len, + struct ss_request *req) +{ + uint8_t facility_length; + + facility_length = ss_facility[0]; + if (len - 1 < facility_length) + return 0; + + return parse_facility_ie(ss_facility + 1, facility_length, req); +} + static int parse_ss_info_elements(const uint8_t *ss_ie, uint16_t len, struct ss_request *req) {
On 22 Apr 2016, at 14:41, Sergey Kostanbaev sergey.kostanbaev@gmail.com wrote:
- case GSM0480_MTYPE_FACILITY:
rc &= parse_ss_facility(&hdr->data[0], len - sizeof(*hdr), req); default: LOGP(0, LOGL_DEBUG, "Unknown GSM 04.80 message-type field 0x%02x\n", hdr->msg_type);break;@@ -284,6 +288,18 @@ static int parse_ss(const struct gsm48_hdr *hdr, uint16_t len, struct ss_request return rc; }
+static int parse_ss_facility(const uint8_t *ss_facility, uint16_t len,
struct ss_request *req)+{
- uint8_t facility_length;
- facility_length = ss_facility[0];
- if (len - 1 < facility_length)
return 0;- return parse_facility_ie(ss_facility + 1, facility_length, req);
+}
static int parse_ss_info_elements(const uint8_t *ss_ie, uint16_t len, struct ss_request *req)
same as with the previous commit. There is no guarantee that original_len - sizeof(*hdr) > 1 (as that was removed). So len - 1 can be UINT16_MAX here?
From: Sergey Kostanbaev Sergey.Kostanbaev@gmail.com
Add ss_header structure to store L3 specific data and modify ss_request to store GSM0480 MAP payload. Do not decode strings inside ss_request, leave it for upper level to support other languages. Parse Return Result accordingly. --- include/osmocom/gsm/gsm0480.h | 34 ++++++-- src/gsm/gsm0480.c | 186 ++++++++++++++++++++++++++++++++++-------- src/gsm/libosmogsm.map | 1 + tests/ussd/ussd_test.c | 23 +++++- 4 files changed, 198 insertions(+), 46 deletions(-)
diff --git a/include/osmocom/gsm/gsm0480.h b/include/osmocom/gsm/gsm0480.h index deac322..7cacc84 100644 --- a/include/osmocom/gsm/gsm0480.h +++ b/include/osmocom/gsm/gsm0480.h @@ -5,7 +5,8 @@ #include <osmocom/gsm/protocol/gsm_04_08.h> #include <osmocom/gsm/protocol/gsm_04_80.h>
-#define MAX_LEN_USSD_STRING 31 +#define MAX_LEN_USSD_STRING 182 +#define MAX_ASN1_LEN_USSD_STRING 160
/* deprecated */ struct ussd_request { @@ -18,16 +19,35 @@ struct ussd_request { int gsm0480_decode_ussd_request(const struct gsm48_hdr *hdr, uint16_t len, struct ussd_request *request) OSMO_DEPRECATED("Use gsm0480_decode_ss_request() instead");
+struct ss_header { + uint8_t transaction_id; /**< L3 transaction ID */ + uint8_t message_type; /**< Message type 2.2 */ + + uint8_t component_offset; /**< Component offset in L3 */ + uint8_t component_length; /**< Component length in L3 */ +}; + struct ss_request { - uint8_t opcode; - uint8_t ss_code; - uint8_t ussd_text[MAX_LEN_USSD_STRING + 1]; - uint8_t transaction_id; - uint8_t invoke_id; + uint8_t component_type; /**< Component type 3.6.2 */ + uint8_t invoke_id; /**< Invoke id 3.6.3 */ + + union { + uint8_t opcode; /**< Operational code 3.6.4 */ + uint8_t error_code; /**< Error code 3.6.6 */ + uint8_t problem_code; /**< Problem code 3.6.7 */ + }; + + uint8_t ussd_text_len; + uint8_t ussd_text_language; + uint8_t ussd_text[MAX_ASN1_LEN_USSD_STRING + 1]; + + uint8_t ss_code; /**< parameters of a Interrogate/Activate/DeactivateSS Request */ };
+int gsm0480_parse_ss_facility(const uint8_t* data, uint8_t len, struct ss_request *out); + int gsm0480_decode_ss_request(const struct gsm48_hdr *hdr, uint16_t len, - struct ss_request *request); + struct ss_header *request);
struct msgb *gsm0480_create_ussd_resp(uint8_t invoke_id, uint8_t trans_id, const char *text); struct msgb *gsm0480_create_unstructuredSS_Notify(int alertPattern, const char *text); diff --git a/src/gsm/gsm0480.c b/src/gsm/gsm0480.c index 9fc77a0..e073602 100644 --- a/src/gsm/gsm0480.c +++ b/src/gsm/gsm0480.c @@ -193,25 +193,44 @@ struct msgb *gsm0480_create_notifySS(const char *text)
/* Forward declarations */ static int parse_ss(const struct gsm48_hdr *hdr, - uint16_t len, struct ss_request *req); + uint16_t len, struct ss_header *req); static int parse_ss_info_elements(const uint8_t *ussd_ie, uint16_t len, - struct ss_request *req); + struct ss_header *req); static int parse_ss_facility(const uint8_t *ss_facility, uint16_t len, - struct ss_request *req); + struct ss_header *req); + static int parse_facility_ie(const uint8_t *facility_ie, uint16_t length, struct ss_request *req); static int parse_ss_invoke(const uint8_t *invoke_data, uint16_t length, struct ss_request *req); +static int parse_ss_return_result(const uint8_t *rr_data, uint16_t length, + struct ss_request *req); static int parse_process_uss_req(const uint8_t *uss_req_data, uint16_t length, struct ss_request *req); static int parse_ss_for_bs_req(const uint8_t *ss_req_data, uint16_t length, struct ss_request *req);
+static const uint8_t *parse_asn1_small_len(const uint8_t *codedlen, uint16_t available, + uint8_t *out_len) +{ + uint8_t lenb = codedlen[0]; + if (lenb < 0x80 && available > 0) { + *out_len = lenb; + return &codedlen[1]; + } else if (lenb == 0x81 && available > 1) { + *out_len = codedlen[1]; + return &codedlen[2]; + } + + return NULL; +} + /* Decode a mobile-originated USSD-request message */ int gsm0480_decode_ussd_request(const struct gsm48_hdr *hdr, uint16_t len, struct ussd_request *req) { + struct ss_header sshdr; struct ss_request ss; int rc = 0;
@@ -225,16 +244,31 @@ int gsm0480_decode_ussd_request(const struct gsm48_hdr *hdr, uint16_t len, if (gsm48_hdr_pdisc(hdr) == GSM48_PDISC_NC_SS) { req->transaction_id = hdr->proto_discr & 0x70;
- ss.transaction_id = req->transaction_id; - rc = parse_ss(hdr, len, &ss); + sshdr.transaction_id = req->transaction_id; + rc = parse_ss(hdr, len, &sshdr); + if (rc) { + /* this if block was inside parse_ss() */ + if (sshdr.message_type == GSM0480_MTYPE_RELEASE_COMPLETE) { + /* could also parse out the optional Cause/Facility data */ + ss.ussd_text[0] = 0xFF; + } + rc = gsm0480_parse_ss_facility(hdr->data + sshdr.component_offset, + sshdr.component_length, + &ss); + }
/* convert from ss_request to legacy ussd_request */ - req->transaction_id = ss.transaction_id; + req->transaction_id = sshdr.transaction_id; req->invoke_id = ss.invoke_id; - if (ss.ussd_text[0] == 0xFF) + if (ss.ussd_text_language != 0x0f || + ss.opcode != GSM0480_OP_CODE_PROCESS_USS_REQ) { + req->text[0] = '\0'; - else { - memcpy(req->text, ss.ussd_text, sizeof(req->text)); + } else { + gsm_7bit_decode_n_ussd(req->text, + sizeof(req->text), + ss.ussd_text, ss.ussd_text_len); + req->text[sizeof(req->text)-1] = '\0'; } } @@ -247,7 +281,7 @@ int gsm0480_decode_ussd_request(const struct gsm48_hdr *hdr, uint16_t len,
/* Decode a mobile-originated SS request message */ int gsm0480_decode_ss_request(const struct gsm48_hdr *hdr, uint16_t len, - struct ss_request *req) + struct ss_header *req) { int rc = 0; if (gsm48_hdr_pdisc(hdr) == GSM48_PDISC_NC_SS) { @@ -261,16 +295,17 @@ int gsm0480_decode_ss_request(const struct gsm48_hdr *hdr, uint16_t len, return rc; }
-static int parse_ss(const struct gsm48_hdr *hdr, uint16_t len, struct ss_request *req) +static int parse_ss(const struct gsm48_hdr *hdr, uint16_t len, struct ss_header *req) { int rc = 1; uint8_t msg_type = hdr->msg_type & 0xBF; /* message-type - section 3.4 */
+ req->message_type = msg_type; + req->component_offset = 0; + switch (msg_type) { case GSM0480_MTYPE_RELEASE_COMPLETE: LOGP(0, LOGL_DEBUG, "SS Release Complete\n"); - /* could also parse out the optional Cause/Facility data */ - req->ussd_text[0] = 0xFF; break; case GSM0480_MTYPE_REGISTER: rc &= parse_ss_info_elements(&hdr->data[0], len - sizeof(*hdr), req); @@ -289,7 +324,7 @@ static int parse_ss(const struct gsm48_hdr *hdr, uint16_t len, struct ss_request }
static int parse_ss_facility(const uint8_t *ss_facility, uint16_t len, - struct ss_request *req) + struct ss_header *req) { uint8_t facility_length;
@@ -297,13 +332,15 @@ static int parse_ss_facility(const uint8_t *ss_facility, uint16_t len, if (len - 1 < facility_length) return 0;
- return parse_facility_ie(ss_facility + 1, facility_length, req); + req->component_offset += 1; + req->component_length = facility_length; + return 1; }
static int parse_ss_info_elements(const uint8_t *ss_ie, uint16_t len, - struct ss_request *req) + struct ss_header *req) { - int rc = -1; + int rc = 1; /* Information Element Identifier - table 3.2 & GSM 04.08 section 10.5 */ uint8_t iei; uint8_t iei_length; @@ -319,7 +356,8 @@ static int parse_ss_info_elements(const uint8_t *ss_ie, uint16_t len, case GSM48_IE_CAUSE: break; case GSM0480_IE_FACILITY: - rc = parse_facility_ie(ss_ie + 2, iei_length, req); + req->component_offset += 2; + req->component_length = iei_length; break; case GSM0480_IE_SS_VERSION: break; @@ -333,6 +371,11 @@ static int parse_ss_info_elements(const uint8_t *ss_ie, uint16_t len, return rc; }
+int gsm0480_parse_ss_facility(const uint8_t* data, uint8_t len, struct ss_request *out) +{ + return parse_facility_ie(data, len, out); +} + static int parse_facility_ie(const uint8_t *facility_ie, uint16_t length, struct ss_request *req) { @@ -342,25 +385,38 @@ static int parse_facility_ie(const uint8_t *facility_ie, uint16_t length, while (offset + 2 <= length) { /* Component Type tag - table 3.7 */ uint8_t component_type = facility_ie[offset]; - uint8_t component_length = facility_ie[offset+1]; + uint8_t component_length = 0;
+ const uint8_t *nxt = parse_asn1_small_len(facility_ie + offset + 1, + length - offset - 1, + &component_length); /* size check */ - if (offset + 2 + component_length > length) { + offset = nxt - facility_ie; + if (nxt == NULL || offset + component_length > length) { LOGP(0, LOGL_ERROR, "Component does not fit.\n"); return 0; }
+ req->component_type = component_type; + switch (component_type) { case GSM0480_CTYPE_INVOKE: - rc &= parse_ss_invoke(facility_ie+2, + rc &= parse_ss_invoke(nxt, component_length, req); break; case GSM0480_CTYPE_RETURN_RESULT: + rc &= parse_ss_return_result(nxt, + component_length, + req); break; case GSM0480_CTYPE_RETURN_ERROR: + /* TODO Error codes */ + LOGP(0, LOGL_DEBUG, "Ignored GSM0480_CTYPE_RETURN_ERROR"); break; case GSM0480_CTYPE_REJECT: + /* TODO rejects */ + LOGP(0, LOGL_DEBUG, "Ignored GSM0480_CTYPE_REJECT"); break; default: LOGP(0, LOGL_DEBUG, "Unknown GSM 04.80 Facility " @@ -368,12 +424,58 @@ static int parse_facility_ie(const uint8_t *facility_ie, uint16_t length, rc = 0; break; } - offset += (component_length+2); + offset += component_length; };
return rc; }
+/* Parse an Return Result component - see table 3.4 */ +static int parse_ss_return_result(const uint8_t *rr_data, uint16_t length, + struct ss_request *req) +{ + int rc = 1; + uint8_t offset; + + if (length < 3) + return 0; + + /* mandatory part */ + if (rr_data[0] != GSM0480_COMPIDTAG_INVOKE_ID) { + LOGP(0, LOGL_DEBUG, "Unexpected GSM 04.80 Component-ID tag " + "0x%02x (expecting Invoke ID tag)\n", rr_data[0]); + } + + offset = rr_data[1] + 2; + req->invoke_id = rr_data[2]; + + if (offset < length) { + if (rr_data[offset] != GSM_0480_SEQUENCE_TAG) + return 0; + if (offset + 2 > length) + return 0; + offset += 2; + + uint8_t operation_code = rr_data[offset+2]; + req->opcode = operation_code; + switch (operation_code) { + case GSM0480_OP_CODE_USS_NOTIFY: + case GSM0480_OP_CODE_USS_REQUEST: + case GSM0480_OP_CODE_PROCESS_USS_REQ: + rc = parse_process_uss_req(rr_data + offset + 3, + length - offset - 3, + req); + break; + default: + LOGP(0, LOGL_DEBUG, "GSM 04.80 operation code 0x%02x " + "is not yet handled\n", operation_code); + rc = 0; + break; + } + } + return rc; +} + /* Parse an Invoke component - see table 3.3 */ static int parse_ss_invoke(const uint8_t *invoke_data, uint16_t length, struct ss_request *req) @@ -408,6 +510,8 @@ static int parse_ss_invoke(const uint8_t *invoke_data, uint16_t length, uint8_t operation_code = invoke_data[offset+2]; req->opcode = operation_code; switch (operation_code) { + case GSM0480_OP_CODE_USS_NOTIFY: + case GSM0480_OP_CODE_USS_REQUEST: case GSM0480_OP_CODE_PROCESS_USS_REQ: rc = parse_process_uss_req(invoke_data + offset + 3, length - offset - 3, @@ -441,27 +545,37 @@ static int parse_process_uss_req(const uint8_t *uss_req_data, uint16_t length, struct ss_request *req) { int rc = 0; - int num_chars; - uint8_t dcs; - - + uint8_t dcs, seq_block_len, num_chars; + const uint8_t *next_ptr; /* we need at least that much */ if (length < 8) return 0;
if (uss_req_data[0] == GSM_0480_SEQUENCE_TAG) { - if (uss_req_data[2] == ASN1_OCTET_STRING_TAG) { - dcs = uss_req_data[4]; - if ((dcs == 0x0F) && - (uss_req_data[5] == ASN1_OCTET_STRING_TAG)) { - num_chars = (uss_req_data[6] * 8) / 7; + next_ptr = parse_asn1_small_len(&uss_req_data[1], length - 1, &seq_block_len); + if (next_ptr == NULL || seq_block_len < 6) + return 0; + + if (next_ptr[0] == ASN1_OCTET_STRING_TAG) { + if (next_ptr[1] != 1) + return 0; + + dcs = next_ptr[2]; + + if (next_ptr[3] == ASN1_OCTET_STRING_TAG) { + next_ptr = parse_asn1_small_len(&next_ptr[4], + seq_block_len - 4, &num_chars); + if (next_ptr == NULL) + return 0; + /* Prevent a mobile-originated buffer-overrun! */ - if (num_chars > MAX_LEN_USSD_STRING) - num_chars = MAX_LEN_USSD_STRING; - gsm_7bit_decode_n_ussd((char *)req->ussd_text, - sizeof(req->ussd_text), - &(uss_req_data[7]), num_chars); + if (num_chars > MAX_ASN1_LEN_USSD_STRING) + num_chars = MAX_ASN1_LEN_USSD_STRING; + + req->ussd_text_language = dcs; + req->ussd_text_len = num_chars; + memcpy(req->ussd_text, next_ptr, num_chars); rc = 1; } } diff --git a/src/gsm/libosmogsm.map b/src/gsm/libosmogsm.map index 6886a6c..04cc6c4 100644 --- a/src/gsm/libosmogsm.map +++ b/src/gsm/libosmogsm.map @@ -50,6 +50,7 @@ gsm0480_create_unstructuredSS_Notify; gsm0480_create_ussd_resp; gsm0480_decode_ussd_request; gsm0480_decode_ss_request; +gsm0480_parse_ss_facility; gsm0480_wrap_facility; gsm0480_wrap_invoke;
diff --git a/tests/ussd/ussd_test.c b/tests/ussd/ussd_test.c index f798e37..ac35baa 100644 --- a/tests/ussd/ussd_test.c +++ b/tests/ussd/ussd_test.c @@ -39,12 +39,18 @@ static int parse_ussd(const uint8_t *_data, int len) uint8_t *data; int rc; struct ss_request req; + struct ss_header reqhdr; struct gsm48_hdr *hdr;
data = malloc(len); memcpy(data, _data, len); hdr = (struct gsm48_hdr *) &data[0]; - rc = gsm0480_decode_ss_request(hdr, len, &req); + rc = gsm0480_decode_ss_request(hdr, len, &reqhdr); + if (rc) { + rc = gsm0480_parse_ss_facility(hdr->data + reqhdr.component_offset, + reqhdr.component_length, + &req); + } free(data);
return rc; @@ -55,13 +61,20 @@ static int parse_mangle_ussd(const uint8_t *_data, int len) uint8_t *data; int rc; struct ss_request req; + struct ss_header reqhdr; struct gsm48_hdr *hdr;
data = malloc(len); memcpy(data, _data, len); hdr = (struct gsm48_hdr *) &data[0]; hdr->data[1] = len - sizeof(*hdr) - 2; - rc = gsm0480_decode_ss_request(hdr, len, &req); + rc = gsm0480_decode_ss_request(hdr, len, &reqhdr); + if (rc) { + rc = gsm0480_parse_ss_facility(hdr->data + reqhdr.component_offset, + reqhdr.component_length, + &req); + } + free(data);
return rc; @@ -114,13 +127,17 @@ static void test_7bit_ussd(const char *text, const char *encoded_hex, const char int main(int argc, char **argv) { struct ss_request req; + struct ss_header reqhdr; const int size = sizeof(ussd_request); int i; struct msgb *msg;
osmo_init_logging(&info);
- gsm0480_decode_ss_request((struct gsm48_hdr *) ussd_request, size, &req); + gsm0480_decode_ss_request((struct gsm48_hdr *) ussd_request, size, &reqhdr); + gsm0480_parse_ss_facility(ussd_request + reqhdr.component_offset, + reqhdr.component_length, + &req); printf("Tested if it still works. Text was: %s\n", req.ussd_text);
From: "Sergey.Kostanbaev" Sergey.Kostanbaev@gmail.com
--- src/gsm/gsm0480.c | 2 ++ 1 file changed, 2 insertions(+)
diff --git a/src/gsm/gsm0480.c b/src/gsm/gsm0480.c index e073602..f11bdfe 100644 --- a/src/gsm/gsm0480.c +++ b/src/gsm/gsm0480.c @@ -517,6 +517,8 @@ static int parse_ss_invoke(const uint8_t *invoke_data, uint16_t length, length - offset - 3, req); break; + case GSM0480_OP_CODE_REGISTER_SS: + case GSM0480_OP_CODE_ERASE_SS: case GSM0480_OP_CODE_ACTIVATE_SS: case GSM0480_OP_CODE_DEACTIVATE_SS: case GSM0480_OP_CODE_INTERROGATE_SS:
On 22 Apr 2016, at 14:41, Sergey Kostanbaev sergey.kostanbaev@gmail.com wrote:
From: Sergey Kostanbaev Sergey.Kostanbaev@gmail.com
src/gsm/gsm0480.c | 6 ------ 1 file changed, 6 deletions(-)
diff --git a/src/gsm/gsm0480.c b/src/gsm/gsm0480.c index 8963b78..55bddd5 100644 --- a/src/gsm/gsm0480.c +++ b/src/gsm/gsm0480.c @@ -248,12 +248,6 @@ int gsm0480_decode_ss_request(const struct gsm48_hdr *hdr, uint16_t len, struct ss_request *req) { int rc = 0;
- if (len < sizeof(*hdr) + 2) {
LOGP(0, LOGL_DEBUG, "SS Request is too short.\n");return 0;- }
- if (gsm48_hdr_pdisc(hdr) == GSM48_PDISC_NC_SS) { req->transaction_id = hdr->proto_discr & 0x70; rc = parse_ss(hdr, len, req);
static int parse_ss_info_elements(const uint8_t *ss_ie, uint16_t len, struct ss_request *req) { int rc = -1; /* Information Element Identifier - table 3.2 & GSM 04.08 section 10.5 */ uint8_t iei; uint8_t iei_length;
iei = ss_ie[0]; iei_length = ss_ie[1];
/* If the data does not fit, report an error */ if (len - 2 < iei_length) return 0;
so this code works with uint16_t and assumes there is at least two bytes after the header. I don't know best practices for integer underflow/overflow (shall we use ssize_t)?
First we need a testcase Second we need to remove the assumptions about at least two bytes in payload.
holger
On Fri, Apr 22, 2016 at 02:41:12PM +0200, Sergey Kostanbaev wrote:
From: Sergey Kostanbaev Sergey.Kostanbaev@gmail.com
src/gsm/gsm0480.c | 6 ------ 1 file changed, 6 deletions(-)
diff --git a/src/gsm/gsm0480.c b/src/gsm/gsm0480.c index 8963b78..55bddd5 100644 --- a/src/gsm/gsm0480.c +++ b/src/gsm/gsm0480.c @@ -248,12 +248,6 @@ int gsm0480_decode_ss_request(const struct gsm48_hdr *hdr, uint16_t len, struct ss_request *req) { int rc = 0;
- if (len < sizeof(*hdr) + 2) {
LOGP(0, LOGL_DEBUG, "SS Request is too short.\n");return 0;- }
- if (gsm48_hdr_pdisc(hdr) == GSM48_PDISC_NC_SS) {
I believe this should only remove the "+ 2" and still check for
if (len < sizeof(*hdr)) { return 0; }
since the code continues to dereference hdr, or is this the explicit responsibility of the caller?
~Neels