This is merely a historical archive of years 2008-2021, before the migration to mailman3.
A maintained and still updated list archive can be found at https://lists.osmocom.org/hyperkitty/list/gerrit-log@lists.osmocom.org/.
Vadim Yanitskiy gerrit-no-reply at lists.osmocom.orgVadim Yanitskiy has uploaded this change for review. ( https://gerrit.osmocom.org/11105 Change subject: (WIP) libosmogsm: introduce message definition and verification helpers ...................................................................... (WIP) libosmogsm: introduce message definition and verification helpers Change-Id: Idef83b0c53b17503a64d7ab7422184ca4b60be57 --- M include/Makefile.am A include/osmocom/gsm/tlv_msg_def.h M src/gsm/Makefile.am A src/gsm/tlv_msg_def.c M tests/Makefile.am M tests/testsuite.at A tests/tlv/tlv_msg_def_test.c A tests/tlv/tlv_msg_def_test.ok 8 files changed, 323 insertions(+), 2 deletions(-) git pull ssh://gerrit.osmocom.org:29418/libosmocore refs/changes/05/11105/1 diff --git a/include/Makefile.am b/include/Makefile.am index 19695d1..ec56054 100644 --- a/include/Makefile.am +++ b/include/Makefile.am @@ -121,6 +121,7 @@ osmocom/gsm/rxlev_stat.h \ osmocom/gsm/sysinfo.h \ osmocom/gsm/tlv.h \ + osmocom/gsm/tlv_msg_def.h \ osmocom/sim/class_tables.h \ osmocom/sim/sim.h diff --git a/include/osmocom/gsm/tlv_msg_def.h b/include/osmocom/gsm/tlv_msg_def.h new file mode 100644 index 0000000..b0c108e --- /dev/null +++ b/include/osmocom/gsm/tlv_msg_def.h @@ -0,0 +1,41 @@ +#pragma once + +#include <stdint.h> + +#include <osmocom/core/utils.h> +#include <osmocom/gsm/tlv.h> + +/*! \addtogroup tlv + * @{ + * \file tlv_msg_def.h */ + +/*! Marks IE as optional / conditional */ +#define TLV_IE_FLAG_OPTIONAL (1 << 0) +/*! Marks IE as exclusive (i.e. this IE shall not repeat within a message) */ +#define TLV_IE_FLAG_EXCLUSIVE (1 << 1) +/*! Marks IE as complex (i.e. this IE may contain TLV-based payload itself) */ +#define TLV_IE_FLAG_COMPLEX (1 << 2) + +/*! Definition of a single IE (Information Element) */ +struct tlv_ie_def { + /*! Unique IE identifier */ + uint8_t iei; + /*! TLV type (e.g. T, TV, TvLV) */ + struct tlv_def tlv_def; + /*! Meta info (see \ref TLV_IE_FLAG_*) */ + uint8_t flags; +}; + +/*! Definition of a message group */ +struct tlv_msg_group_def { + /*! Human-readable name of a message group definition */ + const char *name; + /*! The \ref value-string list of all possible message types */ + const struct value_string *msg_names; + /*! The \ref value-string list of all possible IEs */ + const struct value_string *iei_names; + /*! List of expected (mandatory and optional) IEs */ + const struct tlv_ie_def *ie_defs[256]; +}; + +/*! @} */ diff --git a/src/gsm/Makefile.am b/src/gsm/Makefile.am index 29299a6..25a7d5c 100644 --- a/src/gsm/Makefile.am +++ b/src/gsm/Makefile.am @@ -30,7 +30,8 @@ milenage/aes-internal.c milenage/aes-internal-enc.c \ milenage/milenage.c gan.c ipa.c gsm0341.c apn.c \ gsup.c gprs_gea.c gsm0503_conv.c oap.c gsm0808_utils.c \ - gsm23003.c mncc.c bts_features.c oap_client.c + gsm23003.c mncc.c bts_features.c oap_client.c \ + tlv_msg_def.c libgsmint_la_LDFLAGS = -no-undefined libgsmint_la_LIBADD = $(top_builddir)/src/libosmocore.la diff --git a/src/gsm/tlv_msg_def.c b/src/gsm/tlv_msg_def.c new file mode 100644 index 0000000..1eae99c --- /dev/null +++ b/src/gsm/tlv_msg_def.c @@ -0,0 +1,50 @@ +/*! \file tlv_msg_def.c + * Message definition and verification helpers */ +/* + * (C) 2018 by Vadim Yanitskiy <axilirator at gmail.com> + * + * All Rights Reserved + * + * SPDX-License-Identifier: GPL-2.0+ + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + */ + +#include <stdint.h> +#include <errno.h> + +#include <osmocom/core/utils.h> + +#include <osmocom/gsm/tlv_msg_def.h> +#include <osmocom/gsm/tlv.h> + +/*! \addtogroup tlv + * @{ + * Osmocom message definition and verification helpers + * + * In almost all of the TLV based protocols we deal with (OML, RSL, + * BSSAP, RR/CC/MM/...) the specification of the individual messages + * always includes a statement on which IEs are mandatory, which are + * conditional, and which are optional. + * + * This module provides the message definition helpers, which can be + * used to implicitly describe and verify the structure of TLV-based + * messages. + * + * \file tlv_msg_def.c */ + + + +/*! @} */ diff --git a/tests/Makefile.am b/tests/Makefile.am index 18d4bb4..201b2d4 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -26,6 +26,7 @@ codec/codec_ecu_fr_test timer/clk_override_test \ oap/oap_client_test \ logging/logging_vty_test \ + tlv/tlv_msg_def_test \ $(NULL) if ENABLE_MSGFILE @@ -179,6 +180,9 @@ tlv_tlv_test_SOURCES = tlv/tlv_test.c tlv_tlv_test_LDADD = $(LDADD) $(top_builddir)/src/gsm/libosmogsm.la +tlv_tlv_msg_def_test_SOURCES = tlv/tlv_msg_def_test.c +tlv_tlv_msg_def_test_LDADD = $(LDADD) $(top_builddir)/src/gsm/libosmogsm.la + gsup_gsup_test_SOURCES = gsup/gsup_test.c gsup_gsup_test_LDADD = $(LDADD) $(top_builddir)/src/gsm/libosmogsm.la @@ -274,7 +278,8 @@ sercomm/sercomm_test.ok prbs/prbs_test.ok \ gsm23003/gsm23003_test.ok \ timer/clk_override_test.ok \ - oap/oap_client_test.ok oap/oap_client_test.err + oap/oap_client_test.ok oap/oap_client_test.err \ + tlv/tlv_msg_def_test.ok DISTCLEANFILES = atconfig atlocal conv/gsm0503_test_vectors.c BUILT_SOURCES = conv/gsm0503_test_vectors.c diff --git a/tests/testsuite.at b/tests/testsuite.at index a1cf98a..1a5b96a 100644 --- a/tests/testsuite.at +++ b/tests/testsuite.at @@ -253,6 +253,12 @@ AT_CHECK([$abs_top_builddir/tests/tlv/tlv_test], [0], [expout], [ignore]) AT_CLEANUP +AT_SETUP([tlv_msg_def]) +AT_KEYWORDS([tlv_msg_def]) +cat $abs_srcdir/tlv/tlv_msg_def_test.ok > expout +AT_CHECK([$abs_top_builddir/tests/tlv/tlv_msg_def_test], [0], [expout], [ignore]) +AT_CLEANUP + AT_SETUP([gsup]) AT_KEYWORDS([gsup]) cat $abs_srcdir/gsup/gsup_test.ok > expout diff --git a/tests/tlv/tlv_msg_def_test.c b/tests/tlv/tlv_msg_def_test.c new file mode 100644 index 0000000..f16d1cd --- /dev/null +++ b/tests/tlv/tlv_msg_def_test.c @@ -0,0 +1,216 @@ +#include <stdint.h> +#include <stdio.h> + +#include <osmocom/core/utils.h> +#include <osmocom/gsm/tlv_msg_def.h> + +#define TEST_MSG_ITEM(msg) msg, sizeof(msg) +#define MSGT_IES_ITEM(msgt, ies) [msgt] = (ies) +#define TEST_MSGT_GEN(type, sub_type) ((type << 2) | sub_type) + +/* Inspired by 3GPP TS 29.002, chapter 12 */ +enum test_msg_type { + TEST_MSGT_MAP_SRI_FOR_SM_REQ = TEST_MSGT_GEN(0x01, 1), + TEST_MSGT_MAP_SRI_FOR_SM_RES = TEST_MSGT_GEN(0x01, 2), + TEST_MSGT_MAP_SRI_FOR_SM_ERR = TEST_MSGT_GEN(0x01, 3), +}; +static const struct value_string test_msgt_names[] = { + OSMO_VALUE_STRING(TEST_MSGT_MAP_SRI_FOR_SM_REQ), + OSMO_VALUE_STRING(TEST_MSGT_MAP_SRI_FOR_SM_RES), + OSMO_VALUE_STRING(TEST_MSGT_MAP_SRI_FOR_SM_ERR), + { 0, NULL } +}; + +enum test_msg_ies { + TEST_MSG_SMSC_ADDR_IE = 0x01, + TEST_MSG_NODE_ADDR_IE = 0x02, + TEST_MSG_SM_RP_RPI_IE = 0x03, + TEST_MSG_MSISDN_IE = 0x04, + TEST_MSG_IMSI_IE = 0x05, + TEST_MSG_CAUSE_IE = 0x06, +}; +static const struct value_string test_msg_iei_names[] = { + OSMO_VALUE_STRING(TEST_MSG_SMSC_ADDR_IE), + OSMO_VALUE_STRING(TEST_MSG_NODE_ADDR_IE), + OSMO_VALUE_STRING(TEST_MSG_SM_RP_RPI_IE), + OSMO_VALUE_STRING(TEST_MSG_MSISDN_IE), + OSMO_VALUE_STRING(TEST_MSG_IMSI_IE), + OSMO_VALUE_STRING(TEST_MSG_CAUSE_IE), + { 0, NULL } +}; + +/* IE definitions */ +static const struct tlv_ie_def map_sriForSM_req_ies[] = { + { + .iei = TEST_MSG_MSISDN_IE, + .tlv_def = { TLV_TYPE_TLV }, + .flags = TLV_IE_FLAG_EXCLUSIVE, + }, + { + .iei = TEST_MSG_SM_RP_RPI_IE, + .tlv_def = { TLV_TYPE_TV }, + .flags = TLV_IE_FLAG_EXCLUSIVE, + }, + { + .iei = TEST_MSG_SMSC_ADDR_IE, + .tlv_def = { TLV_TYPE_TLV }, + .flags = TLV_IE_FLAG_EXCLUSIVE, + }, + { + .iei = TEST_MSG_IMSI_IE, + .tlv_def = { TLV_TYPE_TLV }, + .flags = (TLV_IE_FLAG_EXCLUSIVE | TLV_IE_FLAG_OPTIONAL), + }, +}; + +static const struct tlv_ie_def map_sriForSM_res_ies[] = { + { + .iei = TEST_MSG_IMSI_IE, + .tlv_def = { TLV_TYPE_TLV }, + .flags = TLV_IE_FLAG_EXCLUSIVE, + }, + { + .iei = TEST_MSG_NODE_ADDR_IE, + .tlv_def = { TLV_TYPE_TLV }, + .flags = TLV_IE_FLAG_EXCLUSIVE, + }, +}; + +static const struct tlv_ie_def map_sriForSM_err_ies[] = { + { + .iei = TEST_MSG_CAUSE_IE, + .tlv_def = { TLV_TYPE_TLV }, + }, +}; + +/* "SRI-FOR-SM" message group (REQ, RES, ERR) definition */ +static const struct tlv_msg_group_def map_sriForSM_def = { + .name = "MAP-MO-ForwardSM", + .msg_names = test_msgt_names, + .iei_names = test_msg_iei_names, + + /* IEs according to section 12.1 */ + .ie_defs = { + MSGT_IES_ITEM(TEST_MSGT_MAP_SRI_FOR_SM_REQ, + map_sriForSM_req_ies), + MSGT_IES_ITEM(TEST_MSGT_MAP_SRI_FOR_SM_RES, + map_sriForSM_res_ies), + MSGT_IES_ITEM(TEST_MSGT_MAP_SRI_FOR_SM_ERR, + map_sriForSM_err_ies), + }, +}; + +/* A valid test set of hand-crafted messages */ +static const uint8_t map_sriForSM_enc_req_valid[] = { + TEST_MSGT_MAP_SRI_FOR_SM_REQ, + TEST_MSG_MSISDN_IE, 0x07, /* TLV, M */ + 0x91, 0x52, 0x65, 0x75, 0x03, 0x28, 0x25, + TEST_MSG_SMSC_ADDR_IE, 0x07, /* TLV, M */ + 0x91, 0x52, 0x75, 0x89, 0x00, 0x00, 0x10, + TEST_MSG_SM_RP_RPI_IE, 0x00, /* TV, M */ +}; +static const uint8_t map_sriForSM_enc_res_valid[] = { + TEST_MSGT_MAP_SRI_FOR_SM_RES, + TEST_MSG_IMSI_IE, 0x08, /* TLV, M */ + 0x46, 0x00, 0x44, 0x31, 0x60, 0x13, 0x03, 0xf5, + TEST_MSG_NODE_ADDR_IE, 0x07, /* TLV, M */ + 0x91, 0x52, 0x75, 0x15, 0x08, 0x00, 0x40, +}; +static const uint8_t map_sriForSM_enc_err_valid[] = { + TEST_MSGT_MAP_SRI_FOR_SM_ERR, + TEST_MSG_CAUSE_IE, 0x04, /* TLV, M */ + 0xde, 0xad, 0xbe, 0xef, +}; + +/* Unknown and optional IEs */ +static const uint8_t map_sriForSM_enc_req_valid_optional[] = { + TEST_MSGT_MAP_SRI_FOR_SM_REQ, + TEST_MSG_MSISDN_IE, 0x07, /* TLV, M */ + 0x91, 0x52, 0x65, 0x75, 0x03, 0x28, 0x25, + TEST_MSG_IMSI_IE, 0x08, /* TLV, O (optional) */ + 0x46, 0x00, 0x44, 0x31, 0x60, 0x13, 0x03, 0xf5, + TEST_MSG_SMSC_ADDR_IE, 0x07, /* TLV, M */ + 0x91, 0x52, 0x75, 0x89, 0x00, 0x00, 0x10, + TEST_MSG_SM_RP_RPI_IE, 0x00, /* TV, M */ +}; +static const uint8_t map_sriForSM_enc_res_valid_unknown[] = { + TEST_MSGT_MAP_SRI_FOR_SM_RES, + 0x99, 0x03, /* Unknown IE (considered as TLV) */ + 0xff, 0xff, 0xff, + TEST_MSG_IMSI_IE, 0x08, /* TLV, M */ + 0x46, 0x00, 0x44, 0x31, 0x60, 0x13, 0x03, 0xf5, + TEST_MSG_NODE_ADDR_IE, 0x07, /* TLV, M */ + 0x91, 0x52, 0x75, 0x15, 0x08, 0x00, 0x40, +}; + +/* Missing mandatory IE(s) */ +static const uint8_t map_sriForSM_enc_req_invalid_miss[] = { + TEST_MSGT_MAP_SRI_FOR_SM_REQ, + TEST_MSG_MSISDN_IE, 0x07, /* TLV, M */ + 0x91, 0x52, 0x65, 0x75, 0x03, 0x28, 0x25, + TEST_MSG_SMSC_ADDR_IE, 0x07, /* TLV, M */ + 0x91, 0x52, 0x75, 0x89, 0x00, 0x00, 0x10, +}; +static const uint8_t map_sriForSM_enc_res_invalid_miss[] = { + TEST_MSGT_MAP_SRI_FOR_SM_RES, + TEST_MSG_NODE_ADDR_IE, 0x07, /* TLV, M */ + 0x91, 0x52, 0x75, 0x15, 0x08, 0x00, 0x40, +}; + +/* TLV vs TV mismatch */ +static const uint8_t map_sriForSM_enc_req_invalid_tv_vs_tlv[] = { + TEST_MSGT_MAP_SRI_FOR_SM_REQ, + TEST_MSG_MSISDN_IE, 0x07, /* TLV, M */ + 0x91, 0x52, 0x65, 0x75, 0x03, 0x28, 0x25, + TEST_MSG_SMSC_ADDR_IE, 0x07, /* TLV, M */ + 0x91, 0x52, 0x75, 0x89, 0x00, 0x00, 0x10, + TEST_MSG_SM_RP_RPI_IE, 0x04, /* TLV, M (incorrect) */ + 0xde, 0xad, 0xbe, 0xef, +}; + +/* Complete test set of hand-crafted messages */ +static const struct test_msg_def { + const char *name; + const uint8_t *data; + size_t data_len; +} map_sriForSM_enc_test_set[] = { + { + "MAP-SRI-FOR-SM Request (valid, mandatory IEs only)", + TEST_MSG_ITEM(map_sriForSM_enc_req_valid), + }, + { + "MAP-SRI-FOR-SM Response (valid, mandatory IEs only)", + TEST_MSG_ITEM(map_sriForSM_enc_res_valid), + }, + { + "MAP-SRI-FOR-SM Error (valid, mandatory IEs only)", + TEST_MSG_ITEM(map_sriForSM_enc_err_valid), + }, + { + "MAP-SRI-FOR-SM Request (valid, optional IEs)", + TEST_MSG_ITEM(map_sriForSM_enc_req_valid_optional), + }, + { + "MAP-SRI-FOR-SM Response (valid, unknown IEs)", + TEST_MSG_ITEM(map_sriForSM_enc_res_valid_unknown), + }, + { + "MAP-SRI-FOR-SM Request (invalid, missing mandatory IEs)", + TEST_MSG_ITEM(map_sriForSM_enc_req_invalid_miss), + }, + { + "MAP-SRI-FOR-SM Response (invalid, missing mandatory IEs)", + TEST_MSG_ITEM(map_sriForSM_enc_res_invalid_miss), + }, + { + /* FIXME: how it supposed to be detected??? decoding failure? */ + "MAP-SRI-FOR-SM Request (invalid, TV vs TLV mismatch)", + TEST_MSG_ITEM(map_sriForSM_enc_req_invalid_tv_vs_tlv), + }, +}; + +int main(int argc, char **argv) +{ + printf("Done.\n"); + return 0; +} diff --git a/tests/tlv/tlv_msg_def_test.ok b/tests/tlv/tlv_msg_def_test.ok new file mode 100644 index 0000000..619c561 --- /dev/null +++ b/tests/tlv/tlv_msg_def_test.ok @@ -0,0 +1 @@ +Done. -- To view, visit https://gerrit.osmocom.org/11105 To unsubscribe, or for help writing mail filters, visit https://gerrit.osmocom.org/settings Gerrit-Project: libosmocore Gerrit-Branch: master Gerrit-MessageType: newchange Gerrit-Change-Id: Idef83b0c53b17503a64d7ab7422184ca4b60be57 Gerrit-Change-Number: 11105 Gerrit-PatchSet: 1 Gerrit-Owner: Vadim Yanitskiy <axilirator at gmail.com> -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.osmocom.org/pipermail/gerrit-log/attachments/20180926/7834757e/attachment.htm>