From 1284c3e96170b1622106097e944e07354549bb2e Mon Sep 17 00:00:00 2001 From: Harald Welte Date: Tue, 1 May 2018 18:11:02 +0200 Subject: lapdm: Implement SABM related constraints * MO SAPI0 establishment *must always* have L3 payload for contention resolution * SAPI3 establishment *must never* use contention resolution * MT establish must never use contention resolution Change-Id: I8c2c103cdc7f9a45d7b2080c572f559fc3db58e4 Closes: OS#2370 --- src/gsm/lapdm.c | 45 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 45 insertions(+) diff --git a/src/gsm/lapdm.c b/src/gsm/lapdm.c index ae21ccdf..1e81bff7 100644 --- a/src/gsm/lapdm.c +++ b/src/gsm/lapdm.c @@ -48,6 +48,8 @@ #include #include +#define LAPD_U_SABM 0x7 + /* TS 04.06 Figure 4 / Section 3.2 */ #define LAPDm_LPD_NORMAL 0 #define LAPDm_LPD_SMSCB 1 @@ -537,6 +539,42 @@ static int update_pending_frames(struct lapd_msg_ctx *lctx) return rc; } +/* determine if receiving a given LAPDm message is not permitted */ +static int lapdm_rx_not_permitted(const struct lapdm_entity *le, + const struct lapd_msg_ctx *lctx) +{ + /* we currently only implement SABM related checks here */ + if (lctx->format != LAPD_FORM_U || lctx->s_u != LAPD_U_SABM) + return 0; + + if (le->mode == LAPDM_MODE_BTS) { + if (le == &le->lapdm_ch->lapdm_acch) { + /* no contention resolution on SACCH */ + if (lctx->length > 0) + return RLL_CAUSE_SABM_INFO_NOTALL; + } else { + switch (lctx->sapi) { + case 0: + /* SAPI0 must use contention resolution, i.e. L3 payload must exist */ + if (lctx->length == 0) + return RLL_CAUSE_UFRM_INC_PARAM; + break; + case 3: + /* SAPI3 doesn't support contention resolution */ + if (lctx->length > 0) + return RLL_CAUSE_SABM_INFO_NOTALL; + break; + } + } + } else if (le->mode == LAPDM_MODE_MS) { + /* contention resolution (L3 present) is only sent by MS, but + * never received by it */ + if (lctx->length > 0) + return RLL_CAUSE_SABM_INFO_NOTALL; + } + return 0; +} + /* input into layer2 (from layer 1) */ static int l2_ph_data_ind(struct msgb *msg, struct lapdm_entity *le, uint8_t chan_nr, uint8_t link_id) @@ -674,6 +712,13 @@ static int l2_ph_data_ind(struct msgb *msg, struct lapdm_entity *le, } /* store context for messages from lapd */ memcpy(&mctx.dl->mctx, &mctx, sizeof(mctx.dl->mctx)); + rc =lapdm_rx_not_permitted(le, &lctx); + if (rc > 0) { + LOGP(DLLAPD, LOGL_NOTICE, "received message not permitted"); + msgb_free(msg); + rsl_rll_error(rc, &mctx); + return -EINVAL; + } /* send to LAPD */ rc = lapd_ph_data_ind(msg, &lctx); break; -- cgit v1.2.3