wbokslag has uploaded this change for review. (
https://gerrit.osmocom.org/c/osmo-tetra/+/28851 )
Change subject: Added basic link FCS validation in LLC
......................................................................
Added basic link FCS validation in LLC
tetra_llc_pdu.c now parses the FCS (Frame Check Sequence) for basic link pdus
that use it. Some changes were made to the tetra_resrc_decoded struct
definition. The have_fcs field designates the FCS was present, while the FCS
field holds the extracted FCS, and FCS_invalid designates an FCS was present
but differs from the computed value.
Change-Id: I81941110801d00ca06bdafdcc0a7afaf7b7617d3
---
M src/tetra_llc_pdu.c
M src/tetra_llc_pdu.h
2 files changed, 69 insertions(+), 11 deletions(-)
git pull ssh://gerrit.osmocom.org:29418/osmo-tetra refs/changes/51/28851/1
diff --git a/src/tetra_llc_pdu.c b/src/tetra_llc_pdu.c
index 9f7880c..65d37d9 100644
--- a/src/tetra_llc_pdu.c
+++ b/src/tetra_llc_pdu.c
@@ -82,42 +82,97 @@
return get_value_string(pdut_dec_names, pdut);
}
+static uint32_t tetra_llc_compute_fcs(const uint8_t *buf, int len) {
+ uint32_t crc = 0xFFFFFFFF;
+ if (len < 32) {
+ crc <<= (32 - len);
+ }
+
+ for(size_t i = 0; i < len; i++) {
+ uint8_t bit = (buf[i] ^ (crc >> 31)) & 1;
+ crc <<= 1;
+ if (bit) {
+ crc = crc ^ 0x04C11DB7;
+ }
+ }
+ return ~crc;
+}
+
+static int tetra_llc_check_fcs(struct tetra_llc_pdu *lpp, uint8_t *buf, int len) {
+ uint32_t computed_fcs = tetra_llc_compute_fcs(buf, len);
+ return lpp->fcs == computed_fcs;
+}
+
int tetra_llc_pdu_parse(struct tetra_llc_pdu *lpp, uint8_t *buf, int len)
{
uint8_t *cur = buf;
uint8_t pdu_type;
+ lpp->have_fcs = 0;
+ lpp->fcs = 0;
pdu_type = bits_to_uint(cur, 4);
cur += 4;
switch (pdu_type) {
- case TLLC_PDUT_BL_ADATA_FCS:
- /* FIXME */
- len -= 32;
+
case TLLC_PDUT_BL_ADATA:
+ case TLLC_PDUT_BL_ADATA_FCS:
lpp->nr = *cur++;
lpp->ns = *cur++;
lpp->tl_sdu = cur;
lpp->tl_sdu_len = len - (cur - buf);
lpp->pdu_type = TLLC_PDUT_DEC_BL_ADATA;
+
+ if (pdu_type == TLLC_PDUT_BL_ADATA_FCS) {
+ if (lpp->tl_sdu_len < 32) {
+ printf("\nWARNING frame too small for FCS (%d)\n", lpp->tl_sdu_len);
+ return cur-buf;
+ }
+ lpp->tl_sdu_len -= 32;
+ lpp->have_fcs = 1;
+ lpp->fcs = bits_to_uint(buf + len - 32, 32);
+ lpp->fcs_invalid = !tetra_llc_check_fcs(lpp, cur, lpp->tl_sdu_len);
+ }
break;
- case TLLC_PDUT_BL_DATA_FCS:
- /* FIXME */
- len -= 32;
+
+
case TLLC_PDUT_BL_DATA:
+ case TLLC_PDUT_BL_DATA_FCS:
lpp->ns = *cur++;
lpp->tl_sdu = cur;
lpp->tl_sdu_len = len - (cur - buf);
lpp->pdu_type = TLLC_PDUT_DEC_BL_DATA;
+
+ if (pdu_type == TLLC_PDUT_BL_DATA_FCS) {
+ if (lpp->tl_sdu_len < 32) {
+ printf("\nWARNING frame too small for FCS (%d)\n", lpp->tl_sdu_len);
+ return cur-buf;
+ }
+ lpp->tl_sdu_len -= 32;
+ lpp->have_fcs = 1;
+ lpp->fcs = bits_to_uint(buf + len - 32, 32);
+ lpp->fcs_invalid = !tetra_llc_check_fcs(lpp, cur, lpp->tl_sdu_len);
+ }
break;
- case TLLC_PDUT_BL_UDATA_FCS:
- /* FIXME */
- len -= 32;
+
case TLLC_PDUT_BL_UDATA:
+ case TLLC_PDUT_BL_UDATA_FCS:
lpp->tl_sdu = cur;
lpp->tl_sdu_len = len - (cur - buf);
lpp->pdu_type = TLLC_PDUT_DEC_BL_UDATA;
+
+ if (pdu_type == TLLC_PDUT_BL_UDATA_FCS) {
+ if (lpp->tl_sdu_len < 32) {
+ printf("\nWARNING frame too small for FCS (%d)\n", lpp->tl_sdu_len);
+ return cur-buf;
+ }
+ lpp->tl_sdu_len -= 32;
+ lpp->have_fcs = 1;
+ lpp->fcs = bits_to_uint(buf + len - 32, 32);
+ lpp->fcs_invalid = !tetra_llc_check_fcs(lpp, cur, lpp->tl_sdu_len);
+ }
break;
+
case TLLC_PDUT_AL_DATA_FINAL:
if (*cur++) {
/* FINAL */
diff --git a/src/tetra_llc_pdu.h b/src/tetra_llc_pdu.h
index e2ce6fd..9dc3592 100644
--- a/src/tetra_llc_pdu.h
+++ b/src/tetra_llc_pdu.h
@@ -72,8 +72,11 @@
uint8_t nr; /* N(R) PDU number (receive) */
uint8_t ns; /* N(S) PDU number (sent) */
uint8_t ss; /* S(S) Segment (sent) */
- uint32_t _fcs;
- uint32_t *fcs;
+
+ uint8_t have_fcs; /* 1 if LLC PDU defines FCS is present */
+ uint32_t fcs; /* FCS value extracted from pdu */
+ uint8_t fcs_invalid; /* 1 if extracted FCS does not match computed FCS */
+
uint8_t *tl_sdu; /* pointer to bitbuf */
uint8_t tl_sdu_len; /* in bits */
};
--
To view, visit
https://gerrit.osmocom.org/c/osmo-tetra/+/28851
To unsubscribe, or for help writing mail filters, visit
https://gerrit.osmocom.org/settings
Gerrit-Project: osmo-tetra
Gerrit-Branch: master
Gerrit-Change-Id: I81941110801d00ca06bdafdcc0a7afaf7b7617d3
Gerrit-Change-Number: 28851
Gerrit-PatchSet: 1
Gerrit-Owner: wbokslag <w.bokslag(a)midnightblue.nl>
Gerrit-MessageType: newchange