osmo_epdg: add PDP Info on SAI GSUP messages

The SAI GSUP message now requires to have PDP Info filled with
APN and PDP type which should be already knows at this state.
Hardcoding PDP type for now.
This commit is contained in:
Alexander Couzens 2024-02-09 18:27:12 +01:00
parent 09f36edddb
commit 7006cc0c46
4 changed files with 50 additions and 7 deletions

View File

@ -27,6 +27,7 @@
#include <threading/condvar.h>
#include <osmocom/core/msgb.h>
#include <osmocom/gsm/apn.h>
#include <osmocom/gsm/gsup.h>
#include <osmocom/gsm/protocol/ipaccess.h>
@ -198,7 +199,6 @@ METHOD(osmo_epdg_gsup_client_t, tunnel_request, osmo_epdg_gsup_response_t*,
private_osmo_epdg_gsup_client_t *this, char *imsi)
{
struct osmo_gsup_message gsup_msg = {0};
struct osmo_gsup_pdp_info *pdp;
struct msgb *msg;
bool timedout;
@ -236,11 +236,15 @@ METHOD(osmo_epdg_gsup_client_t, tunnel_request, osmo_epdg_gsup_response_t*,
}
METHOD(osmo_epdg_gsup_client_t, send_auth_request, osmo_epdg_gsup_response_t*,
private_osmo_epdg_gsup_client_t *this, char *imsi, uint8_t cn_domain, chunk_t *auts, chunk_t *auts_rand)
private_osmo_epdg_gsup_client_t *this, char *imsi, uint8_t cn_domain,
chunk_t *auts, chunk_t *auts_rand, char *apn, uint8_t pdp_type)
{
struct osmo_gsup_message gsup_msg = {0};
struct msgb *msg;
bool timedout;
char apn_enc[APN_MAXLEN];
size_t apn_enc_len = 0;
int ret;
DBG1(DBG_NET, "Send Auth Request for %s", imsi);
gsup_msg.message_type = OSMO_GSUP_MSGT_SEND_AUTH_INFO_REQUEST;
@ -255,6 +259,12 @@ METHOD(osmo_epdg_gsup_client_t, send_auth_request, osmo_epdg_gsup_response_t*,
}
strncpy(gsup_msg.imsi, imsi, sizeof(gsup_msg.imsi));
if (!apn || strlen(apn) == 0)
{
/* TODO: inval apn! */
return NULL;
}
switch (cn_domain)
{
case 0:
@ -292,6 +302,21 @@ METHOD(osmo_epdg_gsup_client_t, send_auth_request, osmo_epdg_gsup_response_t*,
gsup_msg.rand = auts_rand->ptr;
}
gsup_msg.pdp_infos[0].context_id = 0;
gsup_msg.pdp_infos[0].pdp_type_nr = pdp_type;
gsup_msg.pdp_infos[0].pdp_type_org = PDP_TYPE_ORG_IETF;
ret = osmo_apn_from_str(apn_enc, APN_MAXLEN, apn);
if (ret < 0)
{
DBG1(DBG_NET, "Couldn't encode APN %s!", apn);
return NULL;
}
apn_enc_len = ret;
gsup_msg.pdp_infos[0].apn_enc = apn_enc;
gsup_msg.pdp_infos[0].apn_enc_len = apn_enc_len;
gsup_msg.num_pdp_infos = 1;
msg = encode_to_msgb(&gsup_msg);
if (!msg)
{

View File

@ -50,7 +50,8 @@ struct osmo_epdg_gsup_client_t {
* @return NULL or the osmo_epdg_gsup_response_t
*/
osmo_epdg_gsup_response_t *(*send_auth_request)(osmo_epdg_gsup_client_t *this,
char *imsi, uint8_t cn_domain, chunk_t *auts, chunk_t *auts_rand);
char *imsi, uint8_t cn_domain, chunk_t *auts, chunk_t *auts_rand,
char *apn, uint8_t pdp_type);
/**
* Update Location Request

View File

@ -22,6 +22,8 @@
#include <daemon.h>
#include <credentials/keys/shared_key.h>
#include <osmocom/gsm/apn.h>
#include <osmocom/gsm/protocol/gsm_04_08_gprs.h>
#define AKA_SQN_LEN 6
#define AKA_K_LEN 16
@ -71,16 +73,31 @@ METHOD(simaka_provider_t, get_quintuplet, bool,
char rand[AKA_RAND_LEN], char xres[AKA_RES_MAX], int *xres_len,
char ck[AKA_CK_LEN], char ik[AKA_IK_LEN], char autn[AKA_AUTN_LEN])
{
char apn[APN_MAXLEN];
char imsi[17] = {0};
ike_sa_t *ike_sa;
if (get_imsi(id, imsi, sizeof(imsi) - 1))
{
DBG1(DBG_NET, "epdg: get_quintuplet: Can't find IMSI in EAP identity.");
return FALSE;
}
/* TODO: check before if this is a null terminated string */
ike_sa = charon->bus->get_sa(charon->bus);
if (!ike_sa)
{
DBG1(DBG_NET, "epdg: get_quintuplet: Can't get ike_sa.");
return FALSE;
}
if (get_apn(ike_sa, apn, APN_MAXLEN))
{
DBG1(DBG_NET, "epdg: get_quintuplet: Can't get APN.");
return FALSE;
}
osmo_epdg_gsup_response_t *resp = this->gsup->send_auth_request(
this->gsup, imsi, OSMO_GSUP_CN_DOMAIN_PS, NULL, NULL);
this->gsup, imsi, OSMO_GSUP_CN_DOMAIN_PS, NULL, NULL, apn, PDP_TYPE_N_IETF_IPv4);
if (!resp)
{
return FALSE;

View File

@ -84,5 +84,5 @@ int get_apn(ike_sa_t *sa, char *apn, size_t apn_len)
memcpy(apn, apn_chunk.ptr, apn_chunk.len);
apn[apn_chunk.len] = 0;
return -1;
return 0;
}