From 965ac648f040b3e58805d7617b27df258854e844 Mon Sep 17 00:00:00 2001 From: Pau Espin Pedrol Date: Mon, 16 Oct 2023 18:12:45 +0200 Subject: [PATCH] Introduce EPDG_Tests testsuite Relted: OS#6204 Change-Id: Iab6f3c7dbcbbf344b0beca9490597c9ab0907171 --- Makefile | 1 + epdg/EPDG_Tests.cfg | 19 ++ epdg/EPDG_Tests.default | 8 + epdg/EPDG_Tests.ttcn | 394 ++++++++++++++++++++++++++++++++ epdg/gen_links.sh | 52 +++++ epdg/regen_makefile.sh | 27 +++ library/DIAMETER_Templates.ttcn | 204 ++++++++++++++++- library/GSUP_Types.ttcn | 40 +++- 8 files changed, 736 insertions(+), 9 deletions(-) create mode 100644 epdg/EPDG_Tests.cfg create mode 100644 epdg/EPDG_Tests.default create mode 100644 epdg/EPDG_Tests.ttcn create mode 100755 epdg/gen_links.sh create mode 100755 epdg/regen_makefile.sh diff --git a/Makefile b/Makefile index 0ed632f5a..51e51edeb 100644 --- a/Makefile +++ b/Makefile @@ -22,6 +22,7 @@ SUBDIRS= \ dia2gsup \ fr \ fr-net \ + epdg \ gbproxy \ ggsn_tests \ hlr \ diff --git a/epdg/EPDG_Tests.cfg b/epdg/EPDG_Tests.cfg new file mode 100644 index 000000000..c16429371 --- /dev/null +++ b/epdg/EPDG_Tests.cfg @@ -0,0 +1,19 @@ +[ORDERED_INCLUDE] +# Common configuration, shared between test suites +"../Common.cfg" +# testsuite specific configuration, not expected to change +"./EPDG_Tests.default" + +# Local configuration below + +[LOGGING] + +[TESTPORT_PARAMETERS] + + +[MODULE_PARAMETERS] + +[MAIN_CONTROLLER] + +[EXECUTE] +EPDG_Tests.control diff --git a/epdg/EPDG_Tests.default b/epdg/EPDG_Tests.default new file mode 100644 index 000000000..95b42e94d --- /dev/null +++ b/epdg/EPDG_Tests.default @@ -0,0 +1,8 @@ +[LOGGING] +mtc.FileMask := LOG_ALL | TTCN_DEBUG | TTCN_MATCHING; // | DEBUG_ENCDEC; + +[TESTPORT_PARAMETERS] + +[MODULE_PARAMETERS] + +[EXECUTE] diff --git a/epdg/EPDG_Tests.ttcn b/epdg/EPDG_Tests.ttcn new file mode 100644 index 000000000..f93b77baa --- /dev/null +++ b/epdg/EPDG_Tests.ttcn @@ -0,0 +1,394 @@ +module EPDG_Tests { + +import from Misc_Helpers all; +import from General_Types all; +import from Osmocom_Types all; +import from L3_Common all; + +import from IPA_Emulation all; +import from GSUP_Emulation all; +import from GSUP_Types all; + +import from DIAMETER_Types all; +import from DIAMETER_Templates all; +import from DIAMETER_Emulation all; + +import from GTPv2_Emulation all; + +modulepar { + /* our emulated GSUP strongswan (CEAI iface) */ + charstring mp_gsup_local_ip := "127.0.0.100"; + integer mp_gsup_local_port := 0; + charstring mp_gsup_remote_ip := "127.0.0.1"; + integer mp_gsup_remote_port := 4222; + + /* our emulated HSS */ + charstring mp_swx_local_ip := "127.0.0.100"; + integer mp_swx_local_port := 3868; + + /* our emulated PGW (Diameter S6b) */ + charstring mp_s6b_local_ip := "127.0.0.100"; + integer mp_s6b_local_port := 3869; + + /* our emulated PGW (GTPv2C S2b) */ + charstring mp_s2b_local_ip := "127.0.0.100"; + integer mp_s2b_local_port := GTP2C_PORT; + charstring mp_s2b_remote_ip := "127.0.0.1"; + integer mp_s2b_remote_port := GTP2C_PORT; + + charstring mp_diam_realm := "localdomain"; +} + + +type component MTC_CT { + var DIAMETER_Emulation_CT vc_SWx; + port DIAMETER_PT SWx_UNIT; + port DIAMETEREM_PROC_PT SWx_PROC; + + var DIAMETER_Emulation_CT vc_S6b; + port DIAMETER_PT S6b_UNIT; + port DIAMETEREM_PROC_PT S6b_PROC; + + var GSUP_Emulation_CT vc_GSUP; + var IPA_Emulation_CT vc_GSUP_IPA; + port IPA_CTRL_PT GSUP_IPA_EVENT; + + var GTPv2_Emulation_CT vc_GTP2; + port GTP2EM_PT TEID0; + + timer g_Tguard; +}; + +private altstep as_Tguard() runs on MTC_CT { + [] g_Tguard.timeout { + Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail, "Tguard timeout"); + } +} + +type component DIAMETER_ConnHdlr_CT extends DIAMETER_ConnHdlr { + port DIAMETER_Conn_PT DIAMETER_CLIENT; + port DIAMETEREM_PROC_PT DIAMETER_PROC_CLIENT; +} + +function f_diam_connhldr_ct_main(hexstring imsi) runs on DIAMETER_ConnHdlr_CT { + var DIAMETER_ConnHdlr vc_conn_unused; + var PDU_DIAMETER msg; + var UINT32 ete_id; + + f_diameter_expect_imsi(imsi); + + + while (true) { + alt { + [] DIAMETER_CLIENT.receive(PDU_DIAMETER:?) -> value msg { + DIAMETER.send(msg); + } + [] DIAMETER.receive(PDU_DIAMETER:?) -> value msg { + DIAMETER_CLIENT.send(msg); + } + [] DIAMETER_PROC_CLIENT.getcall(DIAMETEREM_register_eteid:{?,?}) -> param(ete_id, vc_conn_unused) { + DIAMETER_PROC.call(DIAMETEREM_register_eteid:{ete_id, self}) { + [] DIAMETER_PROC.getreply(DIAMETEREM_register_eteid:{?,?}) {}; + } + DIAMETER_PROC_CLIENT.reply(DIAMETEREM_register_eteid:{ete_id, vc_conn_unused}); + } + } + } +} + +type component EPDG_ConnHdlr extends DIAMETER_ConnHdlr, GSUP_ConnHdlr, GTP2_ConnHdlr { + var EPDG_ConnHdlrPars g_pars; + + port DIAMETER_Conn_PT SWx; + port DIAMETEREM_PROC_PT SWx_PROC; + port DIAMETER_Conn_PT S6b; + port DIAMETEREM_PROC_PT S6b_PROC; +}; + + +type record EPDG_ConnHdlrPars { + hexstring imsi, + AuthVector vec optional +}; + +private function f_epdg_connhldr_SWx_expect_eteid(UINT32 ete_id) runs on EPDG_ConnHdlr { + SWx_PROC.call(DIAMETEREM_register_eteid:{ete_id, null}) { + [] SWx_PROC.getreply(DIAMETEREM_register_eteid:{?,?}) {}; + } +} +private function f_epdg_connhldr_S6b_expect_eteid(UINT32 ete_id) runs on EPDG_ConnHdlr { + S6b_PROC.call(DIAMETEREM_register_eteid:{ete_id, null}) { + [] S6b_PROC.getreply(DIAMETEREM_register_eteid:{?,?}) {}; + } +} + + +private function f_init_pars(integer imsi_suffix := 1) +runs on MTC_CT return EPDG_ConnHdlrPars { + var EPDG_ConnHdlrPars pars := { + imsi := f_gen_imsi(imsi_suffix), + vec := f_gen_auth_vec_3g() + }; + return pars; +} + +private function f_init_gsup(charstring id) runs on MTC_CT { + id := id & "-GSUP"; + var GsupOps ops := { + create_cb := refers(GSUP_Emulation.ExpectedCreateCallback) + }; + + vc_GSUP_IPA := IPA_Emulation_CT.create(id & "-IPA"); + vc_GSUP := GSUP_Emulation_CT.create(id); + + map(vc_GSUP_IPA:IPA_PORT, system:IPA_CODEC_PT); + connect(vc_GSUP:GSUP, vc_GSUP_IPA:IPA_GSUP_PORT); + /* we use this hack to get events like ASP_IPA_EVENT_UP */ + connect(vc_GSUP_IPA:IPA_CTRL_PORT, self:GSUP_IPA_EVENT); + + vc_GSUP.start(GSUP_Emulation.main(ops, id)); + vc_GSUP_IPA.start(IPA_Emulation.main_client(mp_gsup_remote_ip, mp_gsup_remote_port, + mp_gsup_local_ip, mp_gsup_local_port)); + + /* wait for incoming connection to GSUP port before proceeding */ + timer T := 10.0; + T.start; + alt { + [] GSUP_IPA_EVENT.receive(tr_ASP_IPA_EV(ASP_IPA_EVENT_UP)) { } + [] T.timeout { + Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail, "No connection to GSUP Port"); + } + } +} + +private function DiameterForwardUnitdataCallback(PDU_DIAMETER msg) +runs on DIAMETER_Emulation_CT return template PDU_DIAMETER { + DIAMETER_UNIT.send(msg); + return omit; +} + +private function f_init_diameter(charstring id) runs on MTC_CT { + var DIAMETEROps ops := { + create_cb := refers(DIAMETER_Emulation.ExpectedCreateCallback), + unitdata_cb := refers(DiameterForwardUnitdataCallback), + raw := false /* handler mode (IMSI based routing) */ + }; + var DIAMETER_conn_parameters pars; + + /* SWx setup: */ + pars := { + remote_ip := "", + remote_sctp_port := -1, /* server mode */ + local_ip := mp_swx_local_ip, + local_sctp_port := mp_swx_local_port, + origin_host := "hss." & mp_diam_realm, + origin_realm := mp_diam_realm, + auth_app_id := omit, + vendor_app_id := c_DIAMETER_3GPP_SWx_AID + }; + vc_SWx := DIAMETER_Emulation_CT.create(id); + map(vc_SWx:DIAMETER, system:DIAMETER_CODEC_PT); + connect(vc_SWx:DIAMETER_UNIT, self:SWx_UNIT); + connect(vc_SWx:DIAMETER_PROC, self:SWx_PROC); + vc_SWx.start(DIAMETER_Emulation.main(ops, pars, id)); + + /* S6b setup: */ + pars := { + remote_ip := "", + remote_sctp_port := -1, /* server mode */ + local_ip := mp_s6b_local_ip, + local_sctp_port := mp_s6b_local_port, + origin_host := "hss." & mp_diam_realm, + origin_realm := mp_diam_realm, + auth_app_id := omit, + vendor_app_id := c_DIAMETER_3GPP_S6_AID + }; + vc_S6b := DIAMETER_Emulation_CT.create(id); + map(vc_S6b:DIAMETER, system:DIAMETER_CODEC_PT); + connect(vc_S6b:DIAMETER_UNIT, self:S6b_UNIT); + connect(vc_S6b:DIAMETER_PROC, self:S6b_PROC); + vc_S6b.start(DIAMETER_Emulation.main(ops, pars, id)); + + f_diameter_wait_capability(SWx_UNIT); + // FIXME: osmo-epdg doesn't connect to S6b yet. + //f_diameter_wait_capability(S6b_UNIT); + + /* Give some time for our emulation to get out of SUSPECT list of SUT (3 watchdog ping-pongs): + * RFC6733 sec 5.1 + * RFC3539 sec 3.4.1 [5] + * https://github.com/freeDiameter/freeDiameter/blob/master/libfdcore/p_psm.c#L49 + */ + f_sleep(1.0); +} + +private function f_init_gtp(charstring id) runs on MTC_CT { + var Gtp2EmulationCfg cfg := { + gtpc_bind_ip := mp_s2b_local_ip, + gtpc_bind_port := mp_s2b_local_port, + gtpc_remote_ip := mp_s2b_remote_ip, + gtpc_remote_port := mp_s2b_remote_port, + sgw_role := false, + use_gtpu_daemon := false /* TODO: maybe use, set to true */ + }; + + vc_GTP2 := GTPv2_Emulation_CT.create("GTP2_EM"); + map(vc_GTP2:GTP2C, system:GTP2C); + connect(vc_GTP2:TEID0, self:TEID0); + vc_GTP2.start(GTPv2_Emulation.main(cfg)); +} + +private function f_init(float t_guard := 40.0) runs on MTC_CT { + + g_Tguard.start(t_guard); + activate(as_Tguard()); + + f_init_gsup(testcasename()); + f_init_diameter(testcasename()); + f_init_gtp(testcasename()); +} + +private type function void_fn(charstring id) runs on EPDG_ConnHdlr; + +private function f_init_handler(void_fn fn, charstring id, EPDG_ConnHdlrPars pars) runs on EPDG_ConnHdlr { + g_pars := pars; + + /* tell GSUP dispatcher to send this IMSI to us */ + f_create_gsup_expect(hex2str(g_pars.imsi)); + + fn.apply(id); +} + +private function f_start_handler(void_fn fn, EPDG_ConnHdlrPars pars) +runs on MTC_CT return EPDG_ConnHdlr { + var EPDG_ConnHdlr vc_conn; + var charstring id := testcasename(); + var DIAMETER_ConnHdlr_CT vc_conn_swx, vc_conn_s6b; + + vc_conn := EPDG_ConnHdlr.create(id); + + connect(vc_conn:GSUP, vc_GSUP:GSUP_CLIENT); + connect(vc_conn:GSUP_PROC, vc_GSUP:GSUP_PROC); + + /* SWx */ + vc_conn_swx := DIAMETER_ConnHdlr_CT.create(id); + connect(vc_conn_swx:DIAMETER, vc_SWx:DIAMETER_CLIENT); + connect(vc_conn_swx:DIAMETER_PROC, vc_SWx:DIAMETER_PROC); + connect(vc_conn:SWx, vc_conn_swx:DIAMETER_CLIENT); + connect(vc_conn:SWx_PROC, vc_conn_swx:DIAMETER_PROC_CLIENT); + vc_conn_swx.start(f_diam_connhldr_ct_main(pars.imsi)); + + /* S6b */ + vc_conn_s6b := DIAMETER_ConnHdlr_CT.create(id); + connect(vc_conn_s6b:DIAMETER, vc_S6b:DIAMETER_CLIENT); + connect(vc_conn_s6b:DIAMETER_PROC, vc_S6b:DIAMETER_PROC); + connect(vc_conn:S6b, vc_conn_s6b:DIAMETER_CLIENT); + connect(vc_conn:S6b_PROC, vc_conn_s6b:DIAMETER_PROC_CLIENT); + vc_conn_s6b.start(f_diam_connhldr_ct_main(pars.imsi)); + + vc_conn.start(f_init_handler(fn, id, pars)); + return vc_conn; +} + +/* Diameter SWx MAR + MAA. */ +private altstep as_DIA_SWx_MA_success() runs on EPDG_ConnHdlr { + var PDU_DIAMETER rx_dia; + var template (omit) AVP avp; + var octetstring sess_id; + var template (value) GenericAVP sip_auth_data_item; + [] SWx.receive(tr_DIA_SWx_MAR(g_pars.imsi)) -> value rx_dia { + avp := f_DIAMETER_get_avp(rx_dia, c_AVP_Code_BASE_NONE_Session_Id); + sess_id := valueof(avp.avp_data.avp_BASE_NONE_Session_Id); + sip_auth_data_item := ts_AVP_3GPP_SIPAuthDataItem(0, + g_pars.vec.rand, + g_pars.vec.ik, + g_pars.vec.ck, + g_pars.vec.autn, + g_pars.vec.auts); + /* Send MAA to translator; expect it to show up on GSUP side */ + SWx.send(ts_DIA_SWx_MAA(g_pars.imsi, sip_auth_data_item, + sess_id := sess_id, + hbh_id := rx_dia.hop_by_hop_id, + ete_id := rx_dia.end_to_end_id)); + setverdict(pass); + } + [] SWx.receive(PDU_DIAMETER:?) -> value rx_dia { + Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail, log2str("Unexpected Diameter msg rx: ", rx_dia)); + } +} + +/* Diameter SWx SAR + SAA. */ +private altstep as_DIA_SWx_SA_success() runs on EPDG_ConnHdlr { + var PDU_DIAMETER rx_dia; + var template (omit) AVP avp; + var octetstring sess_id; + [] SWx.receive(tr_DIA_SWx_SAR(g_pars.imsi)) -> value rx_dia { + avp := f_DIAMETER_get_avp(rx_dia, c_AVP_Code_BASE_NONE_Session_Id); + sess_id := valueof(avp.avp_data.avp_BASE_NONE_Session_Id); + /* Send SAA to translator; expect it to show up on GSUP side */ + SWx.send(ts_DIA_SWx_SAA(g_pars.imsi, + sess_id := sess_id, + hbh_id := rx_dia.hop_by_hop_id, + ete_id := rx_dia.end_to_end_id)); + setverdict(pass); + } + [] SWx.receive(PDU_DIAMETER:?) -> value rx_dia { + Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail, log2str("Unexpected Diameter msg rx: ", rx_dia)); + } +} + +/* GSUP AuthInfo Req + Resp, triggers SWx MAR + MAA. */ +private function f_GSUP_AI_success() runs on EPDG_ConnHdlr { + var GSUP_PDU rx_gsup; + var template (present) GSUP_IE auth_tuple_ie := tr_GSUP_IE_AuthTuple3G(g_pars.vec.rand, + g_pars.vec.ik, + g_pars.vec.ck, + g_pars.vec.autn, + g_pars.vec.rand & g_pars.vec.auts); + + GSUP.send(ts_GSUP_SAI_REQ(g_pars.imsi)); + as_DIA_SWx_MA_success(); + /* Expect a positive response back to the translator; expect AIA */ + alt { + [] GSUP.receive(tr_GSUP_SAI_RES(g_pars.imsi, auth_tuple_ie)); + [] GSUP.receive(GSUP_PDU:?) -> value rx_gsup { + Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail, log2str("Unexpected GSUP msg rx: ", rx_gsup)); + } + } + setverdict(pass); +} + +/* GSUP LU Req + Resp, triggers SWx SAR + SAA (Server Assignment). */ +private function f_GSUP_LU_success() runs on EPDG_ConnHdlr { + var GSUP_PDU rx_gsup; + var template octetstring destination_name := *; + GSUP.send(ts_GSUP_UL_REQ(g_pars.imsi)); + as_DIA_SWx_SA_success(); + /* Expect a positive response back to the translator; expect AIA */ + alt { + [] GSUP.receive(tr_GSUP_UL_RES(g_pars.imsi, destination_name)); + [] GSUP.receive(GSUP_PDU:?) -> value rx_gsup { + Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail, log2str("Unexpected GSUP msg rx: ", rx_gsup)); + } + } + setverdict(pass); +} + +private function f_TC_authinfo_normal(charstring id) runs on EPDG_ConnHdlr { + f_GSUP_AI_success(); + f_GSUP_LU_success(); +} + +testcase TC_authinfo_normal() runs on MTC_CT { + var EPDG_ConnHdlrPars pars := f_init_pars(); + var EPDG_ConnHdlr vc_conn; + f_init(); + vc_conn := f_start_handler(refers(f_TC_authinfo_normal), pars); + vc_conn.done; + setverdict(pass); +} + +control { + execute ( TC_authinfo_normal() ); +} + +} diff --git a/epdg/gen_links.sh b/epdg/gen_links.sh new file mode 100755 index 000000000..326d82e5f --- /dev/null +++ b/epdg/gen_links.sh @@ -0,0 +1,52 @@ +#!/bin/bash + +BASEDIR=../deps + +. ../gen_links.sh.inc + +DIR=$BASEDIR/titan.Libraries.TCCUsefulFunctions/src +FILES="TCCInterface_Functions.ttcn TCCConversion_Functions.ttcn TCCConversion.cc TCCInterface.cc TCCInterface_ip.h" +FILES+=" TCCEncoding_Functions.ttcn TCCEncoding.cc " # GSM 7-bit coding +gen_links $DIR $FILES + +DIR=$BASEDIR/titan.TestPorts.Common_Components.Socket-API/src +FILES="Socket_API_Definitions.ttcn" +gen_links $DIR $FILES + +DIR=$BASEDIR/titan.TestPorts.IPL4asp/src +FILES="IPL4asp_Functions.ttcn IPL4asp_PT.cc IPL4asp_PT.hh IPL4asp_PortType.ttcn IPL4asp_Types.ttcn IPL4asp_discovery.cc IPL4asp_protocol_L234.hh" +gen_links $DIR $FILES + +DIR=$BASEDIR/titan.TestPorts.TELNETasp/src +FILES="TELNETasp_PT.cc TELNETasp_PT.hh TELNETasp_PortType.ttcn" +gen_links $DIR $FILES + +DIR=$BASEDIR/titan.ProtocolModules.DIAMETER_ProtocolModule_Generator/src +FILES="DIAMETER_EncDec.cc" +gen_links $DIR $FILES + +DIR=$BASEDIR/titan.ProtocolModules.MobileL3_v13.4.0/src +FILES="MobileL3_CommonIE_Types.ttcn MobileL3_GMM_SM_Types.ttcn MobileL3_MM_Types.ttcn " +gen_links $DIR $FILES + +DIR=$BASEDIR/osmo-uecups/ttcn3 +FILES="UECUPS_CodecPort.ttcn UECUPS_CodecPort_CtrlFunct.ttcn UECUPS_CodecPort_CtrlFunctDef.cc UECUPS_Types.ttcn " +gen_links $DIR $FILES + +DIR=$BASEDIR/titan.ProtocolModules.GTPv2_v13.7.0/src +FILES="GTPv2_Types.ttcn" +gen_links $DIR $FILES + +DIR=../library +FILES="Misc_Helpers.ttcn General_Types.ttcn GSM_Types.ttcn Osmocom_Types.ttcn Native_Functions.ttcn Native_FunctionDefs.cc " +FILES+="Osmocom_CTRL_Types.ttcn " +FILES+="L3_Common.ttcn " +FILES+="DIAMETER_Types.ttcn DIAMETER_CodecPort.ttcn DIAMETER_CodecPort_CtrlFunct.ttcn DIAMETER_CodecPort_CtrlFunctDef.cc DIAMETER_Emulation.ttcn DIAMETER_Templates.ttcn " +FILES+="IPA_Types.ttcn IPA_CodecPort.ttcn IPA_CodecPort_CtrlFunct.ttcn IPA_CodecPort_CtrlFunctDef.cc +IPA_Emulation.ttcnpp " +FILES+="GSUP_Types.ttcn GSUP_Emulation.ttcn " +FILES+="GTPv2_PrivateExtensions.ttcn GTPv2_Templates.ttcn " +FILES+="GTPv2_CodecPort.ttcn GTPv2_CodecPort_CtrlFunctDef.cc GTPv2_CodecPort_CtrlFunct.ttcn GTPv2_Emulation.ttcn " +gen_links $DIR $FILES + +ignore_pp_results diff --git a/epdg/regen_makefile.sh b/epdg/regen_makefile.sh new file mode 100755 index 000000000..8be3bde8c --- /dev/null +++ b/epdg/regen_makefile.sh @@ -0,0 +1,27 @@ +#!/bin/sh + +NAME=EPDG_Tests + +FILES=" + *.ttcn + *.ttcnpp + IPA_CodecPort_CtrlFunctDef.cc + IPL4asp_PT.cc + IPL4asp_discovery.cc + Native_FunctionDefs.cc + TCCConversion.cc + TCCEncoding.cc + TCCInterface.cc + TELNETasp_PT.cc + DIAMETER_EncDec.cc + DIAMETER_CodecPort_CtrlFunctDef.cc + UECUPS_CodecPort_CtrlFunctDef.cc + GTPv2_CodecPort_CtrlFunctDef.cc +" + +export CPPFLAGS_TTCN3=" + -DIPA_EMULATION_CTRL + -DIPA_EMULATION_GSUP +" + +../regen-makefile.sh EPDG_Tests.ttcn $FILES diff --git a/library/DIAMETER_Templates.ttcn b/library/DIAMETER_Templates.ttcn index bbf3cff59..f909b5fcb 100644 --- a/library/DIAMETER_Templates.ttcn +++ b/library/DIAMETER_Templates.ttcn @@ -9,6 +9,7 @@ module DIAMETER_Templates { * SPDX-License-Identifier: GPL-2.0-or-later */ +import from General_Types all; import from DIAMETER_Types all; import from Osmocom_Types all; import from Misc_Helpers all; @@ -124,11 +125,13 @@ const uint32_t c_DIAMETER_3GPP_Gx_AID := 16777238; const uint32_t c_DIAMETER_3GPP_S6_AID := 16777251; const uint32_t c_DIAMETER_3GPP_S13_AID := 16777252; const uint32_t c_DIAMETER_3GPP_S7_AID := 16777308; +/* 3GPP TS 29.273 Section 8.2 */ +const uint32_t c_DIAMETER_3GPP_SWx_AID := 16777265; const octetstring c_def_sess_id := char2oct("ttcn3.session"); template (value) PDU_DIAMETER -ts_DIAMETER(template (value) BIT8 flags, +ts_DIAMETER(template (value) DIAMETER_Types.BIT8 flags, template (value) Command_Code cmd_code, template (value) OCTET4 app_id := '00000000'O, template (value) UINT32 hbh_id := '00000000'O, @@ -145,7 +148,7 @@ ts_DIAMETER(template (value) BIT8 flags, avps := avps } template (present) PDU_DIAMETER -tr_DIAMETER(template (present) BIT8 flags := ?, +tr_DIAMETER(template (present) DIAMETER_Types.BIT8 flags := ?, template (present) Command_Code cmd_code := ?, template (present) OCTET4 app_id := ?, template (present) UINT32 hbh_id := ?, @@ -180,7 +183,7 @@ tr_DIAMETER_R( template (value) AVP_Header ts_DIA_Hdr(template (value) AVP_Code avp_code, - template (value) BIT8 flags := '01000000'B) := { + template (value) DIAMETER_Types.BIT8 flags := '01000000'B) := { avp_code := avp_code, VMPxxxxx := flags, avp_length := 0, /* overwritten */ @@ -188,7 +191,7 @@ ts_DIA_Hdr(template (value) AVP_Code avp_code, } template (present) AVP_Header tr_DIA_Hdr(template (present) AVP_Code avp_code, - template (present) BIT8 flags := '0???????'B) := { + template (present) DIAMETER_Types.BIT8 flags := '0???????'B) := { avp_code := avp_code, VMPxxxxx := flags, avp_length := ?, /* overwritten */ @@ -197,7 +200,7 @@ tr_DIA_Hdr(template (present) AVP_Code avp_code, template (value) AVP_Header ts_DIA_Hdr_3GPP(template (value) AVP_Code avp_code, - template (value) BIT8 flags := '11000000'B) := { + template (value) DIAMETER_Types.BIT8 flags := '11000000'B) := { avp_code := avp_code, VMPxxxxx := flags, avp_length := 0, /* overwritten */ @@ -205,7 +208,7 @@ ts_DIA_Hdr_3GPP(template (value) AVP_Code avp_code, } template (present) AVP_Header tr_DIA_Hdr_3GPP(template (present) AVP_Code avp_code, - template (present) BIT8 flags := '1???????'B) := { + template (present) DIAMETER_Types.BIT8 flags := '1???????'B) := { avp_code := avp_code, VMPxxxxx := flags, avp_length := ?, /* overwritten */ @@ -1028,7 +1031,7 @@ template (value) GenericAVP ts_AVP_3GPP_ApnConfig(uint32_t ctx, AAA_3GPP_PDN_Typ } } -/* TS 29.272 7.3.36 Service-Selection (refers to RFC 5778) */ +/* Service-Selection, TS 29.272 7.3.36, TS 29.273 5.2.3.5, (RFC 5778) */ template (present) GenericAVP tr_AVP_ServiceSelection(template (present) charstring apn := ?) := { avp := { avp_header := tr_DIA_Hdr(c_AVP_Code_MIPv6_NONE_Service_Selection), @@ -2255,4 +2258,191 @@ template (value) GenericAVP ts_AVP_3GPP_IntegrityKey(template (value) CxDx_3GPP_ } } +/* Server-Assignment-Type, 3GPP TS 29.273 8.2.3.12, 3GPP TS 29.229 6.3.15 */ +template (present) GenericAVP tr_AVP_3GPP_ServerAssignmentType(template (present) CxDx_3GPP_Server_Assignment_Type t := ?) := { + avp := { + avp_header := tr_DIA_Hdr_3GPP(c_AVP_Code_CxDx_3GPP_Server_Assignment_Type), + avp_data := { + avp_CxDx_3GPP_Server_Assignment_Type := t + } + } +} +template (value) GenericAVP ts_AVP_3GPP_ServerAssignmentType(template (value) CxDx_3GPP_Server_Assignment_Type t) := { + avp := { + avp_header := ts_DIA_Hdr_3GPP(c_AVP_Code_CxDx_3GPP_Server_Assignment_Type), + avp_data := { + avp_CxDx_3GPP_Server_Assignment_Type := t + } + } +} + +/***************************** + * SWx 3GPP TS 29.273 + *****************************/ + +/* SIP-Auth-Data-Item , 3GPP TS 29.273 8.2.3.9 */ +template (present) GenericAVP tr_AVP_3GPP_SIPAuthDataItem(template (present) uint32_t num := ?) := { + avp := { + avp_header := tr_DIA_Hdr_3GPP(c_AVP_Code_CxDx_3GPP_SIP_Auth_Data_Item), + avp_data := { + avp_CxDx_3GPP_SIP_Auth_Data_Item := superset( + //tr_AVP_3GPP_SIPItemNumber(num), /* Optional */ + tr_AVP_3GPP_SIPAuthScheme(?)//, /* Optional */ + //tr_AVP_3GPP_SIPAuthenticate(?), /* Optional */ + //tr_AVP_3GPP_SIPAuthorization(?), /* Optional */ + //tr_AVP_3GPP_SIPAuthContext(?), /* Optional */ + //tr_AVP_3GPP_ConfidentialityKey(?), /* Optional */ + //tr_AVP_3GPP_IntegrityKey(?) /* Optional */ + /* TODO: + [ SIP-Digest-Authenticate ] + [ Framed-IP-Address ] + [ Framed-IPv6-Prefix ] + [ Framed-Interface-Id ] + [ Line-Identifier ] + *[AVP] + */ + ) + } + } +} +template (value) GenericAVP ts_AVP_3GPP_SIPAuthDataItem(uint32_t num, OCT16 rand, OCT16 ik, OCT16 ck, OCT16 autn, OCT14 auts) := { + avp := { + avp_header := ts_DIA_Hdr_3GPP(c_AVP_Code_CxDx_3GPP_SIP_Auth_Data_Item), + avp_data := { + avp_CxDx_3GPP_SIP_Auth_Data_Item := { + ts_AVP_3GPP_SIPItemNumber(num), + ts_AVP_3GPP_SIPAuthScheme(char2oct("Digest-AKAv1-MD5")), + ts_AVP_3GPP_SIPAuthenticate(rand & autn), + ts_AVP_3GPP_SIPAuthorization(rand & auts), + ts_AVP_3GPP_SIPAuthContext(char2oct("foobar")), + ts_AVP_3GPP_ConfidentialityKey(ck), + ts_AVP_3GPP_IntegrityKey(ik) + /* TODO: + [ SIP-Digest-Authenticate ] + [ Framed-IP-Address ] + [ Framed-IPv6-Prefix ] + [ Framed-Interface-Id ] + [ Line-Identifier ] + *[AVP] + */ + } + } + } +} + +/* Multimedia-Auth-Request, 3GPP TS 29.273 8.2.2.1 Authentication Procedure */ +template (present) PDU_DIAMETER +tr_DIA_SWx_MAR(template (present) hexstring imsi := ?, + template (present) octetstring sess_id := ?, + template (present) charstring orig_host := ?, + template (present) charstring orig_realm := ?, + template (present) charstring dest_realm := ?, + template (present) UINT32 hbh_id := ?, + template (present) UINT32 ete_id := ?) := + tr_DIAMETER(flags := '1???????'B, + cmd_code := Multimedia_Auth, + app_id := int2oct(c_DIAMETER_3GPP_SWx_AID, 4), + hbh_id := hbh_id, ete_id := ete_id, + avps := superset( + tr_AVP_SessionId(sess_id), + tr_AVP_VendorSpecAppId(?, ?), + tr_AVP_AuthSessionState(NO_STATE_MAINTAINED), + tr_AVP_OriginHost(orig_host), + tr_AVP_OriginRealm(orig_realm), + tr_AVP_DestinationRealm(dest_realm), + tr_AVP_UserNameImsi(imsi), + tr_AVP_3GPP_SIPAuthDataItem(?), + tr_AVP_3GPP_SIPNumAuthDataItems(?) + )); + +/* Multimedia-Auth-Answer, 3GPP TS 29.273 8.2.2.1 Authentication Procedure */ +template (value) PDU_DIAMETER +ts_DIA_SWx_MAA(template (value) hexstring imsi, + template (value) GenericAVP sip_auth_data_item, + template (value) uint32_t vendor_app_id := c_DIAMETER_3GPP_SWx_AID, + template (value) octetstring sess_id := c_def_sess_id, + template (value) charstring orig_host := "hss.localdomain", + template (value) charstring orig_realm := "localdomain", + template (value) UINT32 hbh_id := '00000000'O, + template (value) UINT32 ete_id := '00000000'O) := + ts_DIAMETER(flags := '01000000'B, + cmd_code := Multimedia_Auth, + app_id := int2oct(c_DIAMETER_3GPP_SWx_AID, 4), + hbh_id := hbh_id, + ete_id := ete_id, + avps := { + ts_AVP_SessionId(sess_id), + ts_AVP_VendorSpecAppId(vendor_id_3GPP, valueof(vendor_app_id)), + ts_AVP_ResultCode(DIAMETER_SUCCESS), + ts_AVP_AuthSessionState(NO_STATE_MAINTAINED), + ts_AVP_OriginHost(orig_host), + ts_AVP_OriginRealm(orig_realm), + ts_AVP_UserNameImsi(valueof(imsi)), + sip_auth_data_item, + ts_AVP_3GPP_SIPNumAuthDataItems(1) + }); + +/* Server-Assignment-Request, + * 3GPP TS 29.273 8.1.2.2.2 UE/PDN Registration/DeRegistration Notification + * 3GPP TS 29.273 8.2.2.3 Non-3GPP IP Access Registration Procedure */ +template (present) PDU_DIAMETER +tr_DIA_SWx_SAR(template (present) hexstring imsi := ?, + template (present) octetstring sess_id := ?, + template (present) charstring orig_host := ?, + template (present) charstring orig_realm := ?, + template (present) charstring dest_realm := ?, + template (present) UINT32 hbh_id := ?, + template (present) UINT32 ete_id := ?, + template (present) CxDx_3GPP_Server_Assignment_Type server_ass_type := ?, + template (present) charstring service_selection := ?) := + tr_DIAMETER(flags := '1???????'B, + cmd_code := Server_Assignment, + app_id := int2oct(c_DIAMETER_3GPP_SWx_AID, 4), + hbh_id := hbh_id, ete_id := ete_id, + avps := superset( + tr_AVP_SessionId(sess_id), + tr_AVP_VendorSpecAppId(?, ?), + tr_AVP_AuthSessionState(NO_STATE_MAINTAINED), + tr_AVP_OriginHost(orig_host), + tr_AVP_OriginRealm(orig_realm), + tr_AVP_DestinationRealm(dest_realm), + tr_AVP_UserNameImsi(imsi), + tr_AVP_3GPP_ServerAssignmentType(server_ass_type), + tr_AVP_ServiceSelection(service_selection) + )); + +/* Server-Assignment-Answer, + * 3GPP TS 29.273 8.1.2.2.2 UE/PDN Registration/DeRegistration Notification + * 3GPP TS 29.273 8.2.2.3 Non-3GPP IP Access Registration Procedure */ +template (value) PDU_DIAMETER +ts_DIA_SWx_SAA(template (value) hexstring imsi, + template (value) uint32_t vendor_app_id := c_DIAMETER_3GPP_SWx_AID, + template (value) octetstring sess_id := c_def_sess_id, + template (value) charstring orig_host := "hss.localdomain", + template (value) charstring orig_realm := "localdomain", + template (value) UINT32 hbh_id := '00000000'O, + template (value) UINT32 ete_id := '00000000'O) := + ts_DIAMETER(flags := '01000000'B, + cmd_code := Server_Assignment, + app_id := int2oct(c_DIAMETER_3GPP_SWx_AID, 4), + hbh_id := hbh_id, + ete_id := ete_id, + avps := { + ts_AVP_SessionId(sess_id), + ts_AVP_VendorSpecAppId(vendor_id_3GPP, valueof(vendor_app_id)), + ts_AVP_ResultCode(DIAMETER_SUCCESS), + ts_AVP_AuthSessionState(NO_STATE_MAINTAINED), + ts_AVP_OriginHost(orig_host), + ts_AVP_OriginRealm(orig_realm), + ts_AVP_UserNameImsi(valueof(imsi)) + /* TODO: + * [ Non-3GPP-User-Data ] + * [ 3GPP-AAA-Server-Name ] + * [ OC-Supported-Features ] + * [ OC-OLR ] ] + * *[ Load ] + * *[ Supported-Features ] + */ + }); + } diff --git a/library/GSUP_Types.ttcn b/library/GSUP_Types.ttcn index d87486212..ef98175dd 100644 --- a/library/GSUP_Types.ttcn +++ b/library/GSUP_Types.ttcn @@ -379,6 +379,41 @@ template GSUP_IE ts_GSUP_IE_AuthTuple2G(octetstring rand, octetstring sres, } } +template GSUP_IE tr_GSUP_IE_AuthTuple3G( + template (present) octetstring rand := ?, + template (present) octetstring ik := ?, + template (present) octetstring ck := ?, + template (present) octetstring autn := ?, + template (present) octetstring res := ?) := { + tag := OSMO_GSUP_AUTH_TUPLE_IE, + len := ?, + val := { + auth_tuple := { + tr_GSUP_IE_RAND(rand), + tr_GSUP_IE_IK(ik), + tr_GSUP_IE_CK(ck), + tr_GSUP_IE_AUTN(autn), + tr_GSUP_IE_RES(res) + } + } +} + +template GSUP_IE ts_GSUP_IE_AuthTuple3G(octetstring rand, octetstring ik, + octetstring ck, octetstring autn, + octetstring res) := { + tag := OSMO_GSUP_AUTH_TUPLE_IE, + len := 0, /* overwritten */ + val := { + auth_tuple := { + valueof(ts_GSUP_IE_RAND(rand)), + valueof(ts_GSUP_IE_IK(ik)), + valueof(ts_GSUP_IE_CK(ck)), + valueof(ts_GSUP_IE_AUTN(autn)), + valueof(ts_GSUP_IE_RES(res)) + } + } +} + template GSUP_IE tr_GSUP_IE_AuthTuple2G3G( template (present) octetstring rand := ?, template (present) octetstring sres := ?, @@ -535,9 +570,10 @@ template (value) GSUP_PDU ts_GSUP_SAI_ERR(hexstring imsi, integer cause) := valueof(ts_GSUP_IE_IMSI(imsi)), valueof(ts_GSUP_IE_Cause(cause)) }); -template GSUP_PDU tr_GSUP_SAI_RES(template hexstring imsi) := +template GSUP_PDU tr_GSUP_SAI_RES(template (present) hexstring imsi, + template (present) GSUP_IE auth_tuple_ie := tr_GSUP_IE(OSMO_GSUP_AUTH_TUPLE_IE)) := tr_GSUP(OSMO_GSUP_MSGT_SEND_AUTH_INFO_RESULT, { - tr_GSUP_IE_IMSI(imsi), *, tr_GSUP_IE(OSMO_GSUP_AUTH_TUPLE_IE), * }); + tr_GSUP_IE_IMSI(imsi), *, auth_tuple_ie, * }); template GSUP_PDU ts_GSUP_UL_REQ(hexstring imsi, GSUP_CnDomain dom := OSMO_GSUP_CN_DOMAIN_PS, template octetstring source_name := omit) :=