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/.
pespin gerrit-no-reply at lists.osmocom.orgpespin has submitted this change. ( https://gerrit.osmocom.org/c/osmo-hnodeb/+/26002 ) Change subject: Move protocol related code in main.c to related proto files ...................................................................... Move protocol related code in main.c to related proto files Change-Id: I771b3d3f61207137477eed2b316a5f670fb79ef2 --- M include/osmocom/hnodeb/Makefile.am M include/osmocom/hnodeb/hnodeb.h A include/osmocom/hnodeb/nas.h M include/osmocom/hnodeb/ranap.h M include/osmocom/hnodeb/rua.h M src/osmo-hnodeb/Makefile.am M src/osmo-hnodeb/main.c A src/osmo-hnodeb/nas.c M src/osmo-hnodeb/ranap.c M src/osmo-hnodeb/rua.c M src/osmo-hnodeb/vty.c 11 files changed, 389 insertions(+), 339 deletions(-) Approvals: pespin: Looks good to me, approved; Verified fixeria: Looks good to me, but someone else must approve laforge: Looks good to me, but someone else must approve diff --git a/include/osmocom/hnodeb/Makefile.am b/include/osmocom/hnodeb/Makefile.am index f6c91b4..197568c 100644 --- a/include/osmocom/hnodeb/Makefile.am +++ b/include/osmocom/hnodeb/Makefile.am @@ -1,6 +1,7 @@ noinst_HEADERS = \ hnbap.h \ hnodeb.h \ + nas.h \ ranap.h \ rua.h \ vty.h \ diff --git a/include/osmocom/hnodeb/hnodeb.h b/include/osmocom/hnodeb/hnodeb.h index 261fc3a..50432d1 100644 --- a/include/osmocom/hnodeb/hnodeb.h +++ b/include/osmocom/hnodeb/hnodeb.h @@ -100,12 +100,5 @@ struct hnb *hnb_alloc(void *tall_ctx); int hnb_connect(struct hnb *hnb); -void hnb_rx_iu_release(struct hnb *hnb); -void hnb_rx_paging(struct hnb *hnb, const char *imsi); -void hnb_nas_rx_dtap(struct hnb *hnb, void *data, int len); -void hnb_rx_secmode_cmd(struct hnb *hnb, long ip_alg); - -struct msgb *gen_initue_lu(int is_ps, uint32_t conn_id, const char *imsi); - extern void *tall_hnb_ctx; extern struct hnb *g_hnb; diff --git a/include/osmocom/hnodeb/nas.h b/include/osmocom/hnodeb/nas.h new file mode 100644 index 0000000..f6a7976 --- /dev/null +++ b/include/osmocom/hnodeb/nas.h @@ -0,0 +1,24 @@ +/* (C) 2015 by Daniel Willmann <dwillmann at sysmocom.de> + * (C) 2021 by sysmocom - s.f.m.c. GmbH <info at sysmocom.de> + * Author: Pau Espin Pedrol <pespin at sysmocom.de> + * All Rights Reserved + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation; either version 3 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 Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/lienses/>. + * + */ + +#pragma once + +struct hnb; +void hnb_nas_rx_dtap(struct hnb *hnb, void *data, int len); diff --git a/include/osmocom/hnodeb/ranap.h b/include/osmocom/hnodeb/ranap.h index f68006f..df756b1 100644 --- a/include/osmocom/hnodeb/ranap.h +++ b/include/osmocom/hnodeb/ranap.h @@ -19,8 +19,15 @@ */ #pragma once +struct hnb; struct ranap_message_s; #include <osmocom/hnodeb/hnodeb.h> +void hnb_rx_iu_release(struct hnb *hnb); +void hnb_rx_paging(struct hnb *hnb, const char *imsi); +void hnb_rx_secmode_cmd(struct hnb *hnb, long ip_alg); + void hnb_rua_dt_handle_ranap(struct hnb *hnb, struct ranap_message_s *ranap_msg); void hnb_rua_cl_handle_ranap(struct hnb *hnb, struct ranap_message_s *ranap_msg); +void hnb_tx_iu_release_req(struct hnb *hnb); +struct msgb *gen_initue_lu(int is_ps, uint32_t conn_id, const char *imsi); diff --git a/include/osmocom/hnodeb/rua.h b/include/osmocom/hnodeb/rua.h index 9d7cc12..52221be 100644 --- a/include/osmocom/hnodeb/rua.h +++ b/include/osmocom/hnodeb/rua.h @@ -22,5 +22,7 @@ #include <asn1c/ANY.h> struct hnb; +struct msgb; int hnb_rua_rx(struct hnb *hnb, struct msgb *msg); +int hnb_tx_dt(struct hnb *hnb, struct msgb *txm); diff --git a/src/osmo-hnodeb/Makefile.am b/src/osmo-hnodeb/Makefile.am index 7353cd8..139b6b0 100644 --- a/src/osmo-hnodeb/Makefile.am +++ b/src/osmo-hnodeb/Makefile.am @@ -33,6 +33,7 @@ debug.c \ hnbap.c \ hnb.c \ + nas.c \ ranap.c \ rua.c \ vty.c \ diff --git a/src/osmo-hnodeb/main.c b/src/osmo-hnodeb/main.c index dc662aa..9c7a548 100644 --- a/src/osmo-hnodeb/main.c +++ b/src/osmo-hnodeb/main.c @@ -33,28 +33,12 @@ #include <osmocom/core/select.h> #include <osmocom/core/logging.h> #include <osmocom/core/msgb.h> -#include <osmocom/gsm/tlv.h> -#include <osmocom/gsm/gsm48.h> #include <osmocom/vty/telnet_interface.h> #include <osmocom/vty/logging.h> #include <osmocom/vty/command.h> -#include <osmocom/crypt/auth.h> - -#include <osmocom/rua/rua_msg_factory.h> -#include <osmocom/ranap/iu_helpers.h> - -#include <osmocom/ranap/ranap_msg_factory.h> - -#include <osmocom/rua/RUA_RUA-PDU.h> - -#include <osmocom/gsm/protocol/gsm_04_08.h> - -#include <osmocom/ranap/RANAP_ProcedureCode.h> -#include <osmocom/ranap/RANAP_Criticality.h> -#include <osmocom/ranap/RANAP_DirectTransfer.h> -#include <osmocom/ranap/ranap_common.h> +#include <osmocom/ranap/ranap_common.h> /* ranap_set_log_area() */ #include <osmocom/hnodeb/hnbap.h> #include <osmocom/hnodeb/rua.h> @@ -65,326 +49,11 @@ void *tall_hnb_ctx; struct hnb *g_hnb; -struct msgb *rua_new_udt(struct msgb *inmsg); - -static struct msgb *gen_nas_id_resp() -{ - uint8_t id_resp[] = { - GSM48_PDISC_MM, - GSM48_MT_MM_ID_RESP, - /* IMEISV */ - 0x09, /* len */ - 0x03, /* first digit (0000) + even (0) + id IMEISV (011) */ - 0x31, 0x91, 0x06, 0x00, 0x28, 0x47, 0x11, /* digits */ - 0xf2, /* filler (1111) + last digit (0010) */ - }; - - return ranap_new_msg_dt(0, id_resp, sizeof(id_resp)); -} - -static struct msgb *gen_nas_tmsi_realloc_compl() -{ - uint8_t id_resp[] = { - GSM48_PDISC_MM, - GSM48_MT_MM_TMSI_REALL_COMPL, - }; - - return ranap_new_msg_dt(0, id_resp, sizeof(id_resp)); -} - -static struct msgb *gen_nas_auth_resp(uint8_t *sres) -{ - uint8_t id_resp[] = { - GSM48_PDISC_MM, - 0x80 | GSM48_MT_MM_AUTH_RESP, /* simulate sequence nr 2 */ - 0x61, 0xb5, 0x69, 0xf5 /* hardcoded SRES */ - }; - - memcpy(id_resp + 2, sres, 4); - - return ranap_new_msg_dt(0, id_resp, sizeof(id_resp)); -} - -static int hnb_tx_dt(struct hnb *hnb, struct msgb *txm) -{ - struct hnb_chan *chan; - struct msgb *rua; - - chan = hnb->cs.chan; - if (!chan) { - printf("hnb_nas_tx_tmsi_realloc_compl(): No CS channel established yet.\n"); - return -1; - } - - rua = rua_new_dt(chan->is_ps, chan->conn_id, txm); - osmo_wqueue_enqueue(&hnb->wqueue, rua); - return 0; -} - -static struct tlv_parsed *parse_mm(struct gsm48_hdr *gh, int len) -{ - static struct tlv_parsed tp; - int parse_res; - - len -= (const char *)&gh->data[0] - (const char *)gh; - - OSMO_ASSERT(gsm48_hdr_pdisc(gh) == GSM48_PDISC_MM); - - parse_res = tlv_parse(&tp, &gsm48_mm_att_tlvdef, &gh->data[0], len, 0, 0); - if (parse_res <= 0) { - uint8_t msg_type = gsm48_hdr_msg_type(gh); - printf("Error parsing MM message 0x%hhx: %d\n", msg_type, parse_res); - return NULL; - } - - return &tp; -} - -int hnb_nas_rx_lu_accept(struct gsm48_hdr *gh, int len, int *sent_tmsi) -{ - printf(" :D Location Update Accept :D\n"); - struct gsm48_loc_area_id *lai; - - lai = (struct gsm48_loc_area_id *)&gh->data[0]; - - struct osmo_location_area_id laid; - gsm48_decode_lai2(lai, &laid); - printf("LU: mcc %s mnc %s lac %hd\n", - osmo_mcc_name(laid.plmn.mcc), osmo_mnc_name(laid.plmn.mnc, laid.plmn.mnc_3_digits), - laid.lac); - - struct tlv_parsed tp; - int parse_res; - - len -= (const char *)&gh->data[0] - (const char *)gh; - parse_res = tlv_parse(&tp, &gsm48_mm_att_tlvdef, &gh->data[0], len, 0, 0); - if (parse_res <= 0) { - printf("Error parsing Location Update Accept message: %d\n", parse_res); - return -1; - } - - if (TLVP_PRESENT(&tp, GSM48_IE_MOBILE_ID)) { - uint8_t type = TLVP_VAL(&tp, GSM48_IE_NAME_SHORT)[0] & 0x0f; - if (type == GSM_MI_TYPE_TMSI) - *sent_tmsi = 1; - else *sent_tmsi = 0; - } - return 0; -} - -void hnb_nas_rx_mm_info(struct gsm48_hdr *gh, int len) -{ - printf(" :) MM Info :)\n"); - struct tlv_parsed *tp = parse_mm(gh, len); - if (!tp) - return; - - if (TLVP_PRESENT(tp, GSM48_IE_NAME_SHORT)) { - char name[128] = {0}; - gsm_7bit_decode_n(name, 127, - TLVP_VAL(tp, GSM48_IE_NAME_SHORT)+1, - (TLVP_LEN(tp, GSM48_IE_NAME_SHORT)-1)*8/7); - printf("Info: Short Network Name: %s\n", name); - } - - if (TLVP_PRESENT(tp, GSM48_IE_NAME_LONG)) { - char name[128] = {0}; - gsm_7bit_decode_n(name, 127, - TLVP_VAL(tp, GSM48_IE_NAME_LONG)+1, - (TLVP_LEN(tp, GSM48_IE_NAME_LONG)-1)*8/7); - printf("Info: Long Network Name: %s\n", name); - } -} - -static int hnb_nas_rx_auth_req(struct hnb *hnb, struct gsm48_hdr *gh, - int len) -{ - struct gsm48_auth_req *ar; - - len -= (const char *)&gh->data[0] - (const char *)gh; - - if (len < sizeof(*ar)) { - printf("GSM48 Auth Req does not fit.\n"); - return -1; - } - - printf(" :) Authentication Request :)\n"); - - ar = (struct gsm48_auth_req*) &gh->data[0]; - int seq = ar->key_seq; - - /* Generate SRES from *HARDCODED* Ki for Iuh testing */ - struct osmo_auth_vector vec; - /* Ki 000102030405060708090a0b0c0d0e0f */ - struct osmo_sub_auth_data auth = { - .type = OSMO_AUTH_TYPE_GSM, - .algo = OSMO_AUTH_ALG_COMP128v1, - .u.gsm.ki = { - 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, - 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, - 0x0e, 0x0f - }, - }; - - memset(&vec, 0, sizeof(vec)); - osmo_auth_gen_vec(&vec, &auth, ar->rand); - - printf("seq %d rand %s", - seq, osmo_hexdump(ar->rand, sizeof(ar->rand))); - printf(" --> sres %s\n", - osmo_hexdump(vec.sres, 4)); - - return hnb_tx_dt(hnb, gen_nas_auth_resp(vec.sres)); -} - -void hnb_tx_iu_release_req(struct hnb *hnb) -{ - RANAP_Cause_t cause = { - .present = RANAP_Cause_PR_radioNetwork, - .choice.transmissionNetwork = RANAP_CauseRadioNetwork_release_due_to_UE_generated_signalling_connection_release, - }; - hnb_tx_dt(hnb, ranap_new_msg_iu_rel_req(&cause)); -} - -void hnb_tx_iu_release_compl(struct hnb *hnb) -{ - hnb_tx_dt(hnb, ranap_new_msg_iu_rel_compl()); -} - -static int hnb_nas_rx_mm(struct hnb *hnb, struct gsm48_hdr *gh, int len) -{ - struct hnb_chan *chan; - - chan = hnb->cs.chan; - if (!chan) { - printf("hnb_nas_rx_mm(): No CS channel established yet.\n"); - return -1; - } - - OSMO_ASSERT(!chan->is_ps); - - uint8_t msg_type = gsm48_hdr_msg_type(gh); - int sent_tmsi; - - switch (msg_type) { - case GSM48_MT_MM_ID_REQ: - return hnb_tx_dt(hnb, gen_nas_id_resp()); - - case GSM48_MT_MM_LOC_UPD_ACCEPT: - if (hnb_nas_rx_lu_accept(gh, len, &sent_tmsi)) - return -1; - if (sent_tmsi) - return hnb_tx_dt(hnb, gen_nas_tmsi_realloc_compl()); - else - return 0; - - case GSM48_MT_MM_LOC_UPD_REJECT: - printf("Received Location Update Reject\n"); - return 0; - - case GSM48_MT_MM_INFO: - hnb_nas_rx_mm_info(gh, len); - hnb_tx_iu_release_req(hnb); - return 0; - - case GSM48_MT_MM_AUTH_REQ: - return hnb_nas_rx_auth_req(hnb, gh, len); - - default: - printf("04.08 message type not handled by hnb-test: 0x%x\n", - msg_type); - return 0; - } - -} - -void hnb_nas_rx_dtap(struct hnb *hnb, void *data, int len) -{ - int rc; - printf("got %d bytes: %s\n", len, osmo_hexdump(data, len)); - - // nas_pdu == '05 08 12' ==> IMEI Identity request - // '05 04 0d' ==> LU reject - - struct gsm48_hdr *gh = data; - if (len < sizeof(*gh)) { - printf("hnb_nas_rx_dtap(): NAS PDU is too short: %d. Ignoring.\n", - len); - return; - } - uint8_t pdisc = gsm48_hdr_pdisc(gh); - - switch (pdisc) { - case GSM48_PDISC_MM: - rc = hnb_nas_rx_mm(hnb, gh, len); - if (rc != 0) - printf("Error receiving MM message: %d\n", rc); - return; - default: - printf("04.08 discriminator not handled by hnb-test: %d\n", - pdisc); - return; - } -} - -void hnb_rx_secmode_cmd(struct hnb *hnb, long ip_alg) -{ - printf(" :) Security Mode Command :)\n"); - /* not caring about encryption yet, just pass 0 for No Encryption. */ - hnb_tx_dt(hnb, ranap_new_msg_sec_mod_compl(ip_alg, 0)); -} - -void hnb_rx_iu_release(struct hnb *hnb) -{ - hnb_tx_iu_release_compl(hnb); -} - -void hnb_rx_paging(struct hnb *hnb, const char *imsi) -{ - printf(" :) Paging Request for %s :)\n", imsi); - /* TODO reply */ -} - -extern void direct_transfer_nas_pdu_print(ANY_t *in); - static struct vty_app_info vty_info = { .name = "OsmohNodeB", .version = "0", }; - -struct msgb *gen_initue_lu(int is_ps, uint32_t conn_id, const char *imsi) -{ - uint8_t lu[] = { GSM48_PDISC_MM, GSM48_MT_MM_LOC_UPD_REQUEST, - 0x70, 0x62, 0xf2, 0x30, 0xff, 0xf3, 0x57, - /* len, IMSI/type, IMSI-------------------------------- */ - 0x08, 0x29, 0x26, 0x24, 0x10, 0x32, 0x54, 0x76, 0x98, - 0x33, 0x03, 0x57, 0x18 , 0xb2 }; - uint8_t plmn_id[] = { 0x09, 0x01, 0x99 }; - RANAP_GlobalRNC_ID_t rnc_id = { - .rNC_ID = 23, - .pLMNidentity.buf = plmn_id, - .pLMNidentity.size = sizeof(plmn_id), - }; - - /* FIXME: patch imsi */ - /* Note: the Mobile Identitiy IE's IMSI data has the identity type and - * an even/odd indicator bit encoded in the first octet. So the first - * octet looks like this: - * - * 8 7 6 5 | 4 | 3 2 1 - * IMSI-digit | even/odd | type - * - * followed by the remaining IMSI digits. - * If digit count is even (bit 4 == 0), that first high-nibble is 0xf. - * (derived from Iu pcap Location Update Request msg and TS 25.413) - * - * TODO I'm only 90% sure about this - */ - - return ranap_new_msg_initial_ue(conn_id, is_ps, &rnc_id, lu, sizeof(lu)); -} - static void handle_options(int argc, char **argv) { while (1) { diff --git a/src/osmo-hnodeb/nas.c b/src/osmo-hnodeb/nas.c new file mode 100644 index 0000000..163f458 --- /dev/null +++ b/src/osmo-hnodeb/nas.c @@ -0,0 +1,268 @@ +/* (C) 2015 by Daniel Willmann <dwillmann at sysmocom.de> + * (C) 2021 by sysmocom - s.f.m.c. GmbH <info at sysmocom.de> + * Author: Pau Espin Pedrol <pespin at sysmocom.de> + * All Rights Reserved + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation; either version 3 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 Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/lienses/>. + * + */ + +#include "config.h" + +#include <stdlib.h> +#include <unistd.h> +#include <stdio.h> + +#include <osmocom/core/msgb.h> +#include <osmocom/gsm/tlv.h> +#include <osmocom/gsm/protocol/gsm_04_08.h> +#include <osmocom/gsm/gsm48.h> +#include <osmocom/crypt/auth.h> + +#include <osmocom/ranap/ranap_msg_factory.h> + +#include <osmocom/hnodeb/rua.h> +#include <osmocom/hnodeb/ranap.h> +#include <osmocom/hnodeb/nas.h> +#include <osmocom/hnodeb/hnodeb.h> + +static struct msgb *gen_nas_id_resp() +{ + uint8_t id_resp[] = { + GSM48_PDISC_MM, + GSM48_MT_MM_ID_RESP, + /* IMEISV */ + 0x09, /* len */ + 0x03, /* first digit (0000) + even (0) + id IMEISV (011) */ + 0x31, 0x91, 0x06, 0x00, 0x28, 0x47, 0x11, /* digits */ + 0xf2, /* filler (1111) + last digit (0010) */ + }; + + return ranap_new_msg_dt(0, id_resp, sizeof(id_resp)); +} + +static struct msgb *gen_nas_tmsi_realloc_compl() +{ + uint8_t id_resp[] = { + GSM48_PDISC_MM, + GSM48_MT_MM_TMSI_REALL_COMPL, + }; + + return ranap_new_msg_dt(0, id_resp, sizeof(id_resp)); +} + +static struct msgb *gen_nas_auth_resp(uint8_t *sres) +{ + uint8_t id_resp[] = { + GSM48_PDISC_MM, + 0x80 | GSM48_MT_MM_AUTH_RESP, /* simulate sequence nr 2 */ + 0x61, 0xb5, 0x69, 0xf5 /* hardcoded SRES */ + }; + + memcpy(id_resp + 2, sres, 4); + + return ranap_new_msg_dt(0, id_resp, sizeof(id_resp)); +} + +static struct tlv_parsed *parse_mm(struct gsm48_hdr *gh, int len) +{ + static struct tlv_parsed tp; + int parse_res; + + len -= (const char *)&gh->data[0] - (const char *)gh; + + OSMO_ASSERT(gsm48_hdr_pdisc(gh) == GSM48_PDISC_MM); + + parse_res = tlv_parse(&tp, &gsm48_mm_att_tlvdef, &gh->data[0], len, 0, 0); + if (parse_res <= 0) { + uint8_t msg_type = gsm48_hdr_msg_type(gh); + printf("Error parsing MM message 0x%hhx: %d\n", msg_type, parse_res); + return NULL; + } + + return &tp; +} + +int hnb_nas_rx_lu_accept(struct gsm48_hdr *gh, int len, int *sent_tmsi) +{ + printf(" :D Location Update Accept :D\n"); + struct gsm48_loc_area_id *lai; + + lai = (struct gsm48_loc_area_id *)&gh->data[0]; + + struct osmo_location_area_id laid; + gsm48_decode_lai2(lai, &laid); + printf("LU: mcc %s mnc %s lac %hd\n", + osmo_mcc_name(laid.plmn.mcc), osmo_mnc_name(laid.plmn.mnc, laid.plmn.mnc_3_digits), + laid.lac); + + struct tlv_parsed tp; + int parse_res; + + len -= (const char *)&gh->data[0] - (const char *)gh; + parse_res = tlv_parse(&tp, &gsm48_mm_att_tlvdef, &gh->data[0], len, 0, 0); + if (parse_res <= 0) { + printf("Error parsing Location Update Accept message: %d\n", parse_res); + return -1; + } + + if (TLVP_PRESENT(&tp, GSM48_IE_MOBILE_ID)) { + uint8_t type = TLVP_VAL(&tp, GSM48_IE_NAME_SHORT)[0] & 0x0f; + if (type == GSM_MI_TYPE_TMSI) + *sent_tmsi = 1; + else *sent_tmsi = 0; + } + return 0; +} + +void hnb_nas_rx_mm_info(struct gsm48_hdr *gh, int len) +{ + printf(" :) MM Info :)\n"); + struct tlv_parsed *tp = parse_mm(gh, len); + if (!tp) + return; + + if (TLVP_PRESENT(tp, GSM48_IE_NAME_SHORT)) { + char name[128] = {0}; + gsm_7bit_decode_n(name, 127, + TLVP_VAL(tp, GSM48_IE_NAME_SHORT)+1, + (TLVP_LEN(tp, GSM48_IE_NAME_SHORT)-1)*8/7); + printf("Info: Short Network Name: %s\n", name); + } + + if (TLVP_PRESENT(tp, GSM48_IE_NAME_LONG)) { + char name[128] = {0}; + gsm_7bit_decode_n(name, 127, + TLVP_VAL(tp, GSM48_IE_NAME_LONG)+1, + (TLVP_LEN(tp, GSM48_IE_NAME_LONG)-1)*8/7); + printf("Info: Long Network Name: %s\n", name); + } +} + +static int hnb_nas_rx_auth_req(struct hnb *hnb, struct gsm48_hdr *gh, + int len) +{ + struct gsm48_auth_req *ar; + + len -= (const char *)&gh->data[0] - (const char *)gh; + + if (len < sizeof(*ar)) { + printf("GSM48 Auth Req does not fit.\n"); + return -1; + } + + printf(" :) Authentication Request :)\n"); + + ar = (struct gsm48_auth_req*) &gh->data[0]; + int seq = ar->key_seq; + + /* Generate SRES from *HARDCODED* Ki for Iuh testing */ + struct osmo_auth_vector vec; + /* Ki 000102030405060708090a0b0c0d0e0f */ + struct osmo_sub_auth_data auth = { + .type = OSMO_AUTH_TYPE_GSM, + .algo = OSMO_AUTH_ALG_COMP128v1, + .u.gsm.ki = { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, + 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, + 0x0e, 0x0f + }, + }; + + memset(&vec, 0, sizeof(vec)); + osmo_auth_gen_vec(&vec, &auth, ar->rand); + + printf("seq %d rand %s", + seq, osmo_hexdump(ar->rand, sizeof(ar->rand))); + printf(" --> sres %s\n", + osmo_hexdump(vec.sres, 4)); + + return hnb_tx_dt(hnb, gen_nas_auth_resp(vec.sres)); +} + +static int hnb_nas_rx_mm(struct hnb *hnb, struct gsm48_hdr *gh, int len) +{ + struct hnb_chan *chan; + + chan = hnb->cs.chan; + if (!chan) { + printf("hnb_nas_rx_mm(): No CS channel established yet.\n"); + return -1; + } + + OSMO_ASSERT(!chan->is_ps); + + uint8_t msg_type = gsm48_hdr_msg_type(gh); + int sent_tmsi; + + switch (msg_type) { + case GSM48_MT_MM_ID_REQ: + return hnb_tx_dt(hnb, gen_nas_id_resp()); + + case GSM48_MT_MM_LOC_UPD_ACCEPT: + if (hnb_nas_rx_lu_accept(gh, len, &sent_tmsi)) + return -1; + if (sent_tmsi) + return hnb_tx_dt(hnb, gen_nas_tmsi_realloc_compl()); + else + return 0; + + case GSM48_MT_MM_LOC_UPD_REJECT: + printf("Received Location Update Reject\n"); + return 0; + + case GSM48_MT_MM_INFO: + hnb_nas_rx_mm_info(gh, len); + hnb_tx_iu_release_req(hnb); + return 0; + + case GSM48_MT_MM_AUTH_REQ: + return hnb_nas_rx_auth_req(hnb, gh, len); + + default: + printf("04.08 message type not handled by hnb-test: 0x%x\n", + msg_type); + return 0; + } + +} + +void hnb_nas_rx_dtap(struct hnb *hnb, void *data, int len) +{ + int rc; + printf("got %d bytes: %s\n", len, osmo_hexdump(data, len)); + + // nas_pdu == '05 08 12' ==> IMEI Identity request + // '05 04 0d' ==> LU reject + + struct gsm48_hdr *gh = data; + if (len < sizeof(*gh)) { + printf("hnb_nas_rx_dtap(): NAS PDU is too short: %d. Ignoring.\n", + len); + return; + } + uint8_t pdisc = gsm48_hdr_pdisc(gh); + + switch (pdisc) { + case GSM48_PDISC_MM: + rc = hnb_nas_rx_mm(hnb, gh, len); + if (rc != 0) + printf("Error receiving MM message: %d\n", rc); + return; + default: + printf("04.08 discriminator not handled by hnb-test: %d\n", + pdisc); + return; + } +} diff --git a/src/osmo-hnodeb/ranap.c b/src/osmo-hnodeb/ranap.c index a6a92cc..8f1b9c0 100644 --- a/src/osmo-hnodeb/ranap.c +++ b/src/osmo-hnodeb/ranap.c @@ -18,11 +18,15 @@ * */ #include <osmocom/core/msgb.h> +#include <osmocom/gsm/protocol/gsm_04_08.h> #include <osmocom/ranap/ranap_common_cn.h> #include <osmocom/ranap/ranap_ies_defs.h> #include <osmocom/ranap/iu_helpers.h> +#include <osmocom/ranap/ranap_msg_factory.h> +#include <osmocom/hnodeb/nas.h> +#include <osmocom/hnodeb/rua.h> #include <osmocom/hnodeb/ranap.h> static const char *printstr(OCTET_STRING_t *s) @@ -105,3 +109,67 @@ return; } } + +struct msgb *gen_initue_lu(int is_ps, uint32_t conn_id, const char *imsi) +{ + uint8_t lu[] = { GSM48_PDISC_MM, GSM48_MT_MM_LOC_UPD_REQUEST, + 0x70, 0x62, 0xf2, 0x30, 0xff, 0xf3, 0x57, + /* len, IMSI/type, IMSI-------------------------------- */ + 0x08, 0x29, 0x26, 0x24, 0x10, 0x32, 0x54, 0x76, 0x98, + 0x33, 0x03, 0x57, 0x18 , 0xb2 }; + uint8_t plmn_id[] = { 0x09, 0x01, 0x99 }; + RANAP_GlobalRNC_ID_t rnc_id = { + .rNC_ID = 23, + .pLMNidentity.buf = plmn_id, + .pLMNidentity.size = sizeof(plmn_id), + }; + + /* FIXME: patch imsi */ + /* Note: the Mobile Identitiy IE's IMSI data has the identity type and + * an even/odd indicator bit encoded in the first octet. So the first + * octet looks like this: + * + * 8 7 6 5 | 4 | 3 2 1 + * IMSI-digit | even/odd | type + * + * followed by the remaining IMSI digits. + * If digit count is even (bit 4 == 0), that first high-nibble is 0xf. + * (derived from Iu pcap Location Update Request msg and TS 25.413) + * + * TODO I'm only 90% sure about this + */ + + return ranap_new_msg_initial_ue(conn_id, is_ps, &rnc_id, lu, sizeof(lu)); +} + +void hnb_tx_iu_release_req(struct hnb *hnb) +{ + RANAP_Cause_t cause = { + .present = RANAP_Cause_PR_radioNetwork, + .choice.transmissionNetwork = RANAP_CauseRadioNetwork_release_due_to_UE_generated_signalling_connection_release, + }; + hnb_tx_dt(hnb, ranap_new_msg_iu_rel_req(&cause)); +} + +void hnb_tx_iu_release_compl(struct hnb *hnb) +{ + hnb_tx_dt(hnb, ranap_new_msg_iu_rel_compl()); +} + +void hnb_rx_secmode_cmd(struct hnb *hnb, long ip_alg) +{ + printf(" :) Security Mode Command :)\n"); + /* not caring about encryption yet, just pass 0 for No Encryption. */ + hnb_tx_dt(hnb, ranap_new_msg_sec_mod_compl(ip_alg, 0)); +} + +void hnb_rx_iu_release(struct hnb *hnb) +{ + hnb_tx_iu_release_compl(hnb); +} + +void hnb_rx_paging(struct hnb *hnb, const char *imsi) +{ + printf(" :) Paging Request for %s :)\n", imsi); + /* TODO reply */ +} diff --git a/src/osmo-hnodeb/rua.c b/src/osmo-hnodeb/rua.c index 0839c0d..229df30 100644 --- a/src/osmo-hnodeb/rua.c +++ b/src/osmo-hnodeb/rua.c @@ -24,10 +24,26 @@ #include <osmocom/rua/rua_ies_defs.h> #include <osmocom/ranap/ranap_common_cn.h> +#include <osmocom/rua/rua_msg_factory.h> #include <osmocom/hnodeb/rua.h> #include <osmocom/hnodeb/ranap.h> +int hnb_tx_dt(struct hnb *hnb, struct msgb *txm) +{ + struct hnb_chan *chan; + struct msgb *rua; + + chan = hnb->cs.chan; + if (!chan) { + printf("hnb_nas_tx_tmsi_realloc_compl(): No CS channel established yet.\n"); + return -1; + } + + rua = rua_new_dt(chan->is_ps, chan->conn_id, txm); + osmo_wqueue_enqueue(&hnb->wqueue, rua); + return 0; +} static void hnb_rua_dt_handle(struct hnb *hnb, ANY_t *in) { diff --git a/src/osmo-hnodeb/vty.c b/src/osmo-hnodeb/vty.c index b8dc7da..114f1c0 100644 --- a/src/osmo-hnodeb/vty.c +++ b/src/osmo-hnodeb/vty.c @@ -33,6 +33,7 @@ #include <osmocom/ranap/ranap_msg_factory.h> #include <osmocom/hnodeb/hnbap.h> +#include <osmocom/hnodeb/ranap.h> #include <osmocom/hnodeb/vty.h> #include <osmocom/hnodeb/hnodeb.h> -- To view, visit https://gerrit.osmocom.org/c/osmo-hnodeb/+/26002 To unsubscribe, or for help writing mail filters, visit https://gerrit.osmocom.org/settings Gerrit-Project: osmo-hnodeb Gerrit-Branch: master Gerrit-Change-Id: I771b3d3f61207137477eed2b316a5f670fb79ef2 Gerrit-Change-Number: 26002 Gerrit-PatchSet: 2 Gerrit-Owner: pespin <pespin at sysmocom.de> Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: fixeria <vyanitskiy at sysmocom.de> Gerrit-Reviewer: laforge <laforge at osmocom.org> Gerrit-Reviewer: pespin <pespin at sysmocom.de> Gerrit-MessageType: merged -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.osmocom.org/pipermail/gerrit-log/attachments/20211102/e9f8d9f4/attachment.htm>