diff options
Diffstat (limited to 'openbsc/src/nat')
-rw-r--r-- | openbsc/src/nat/bsc_nat.c | 10 | ||||
-rw-r--r-- | openbsc/src/nat/bsc_nat_utils.c | 26 |
2 files changed, 28 insertions, 8 deletions
diff --git a/openbsc/src/nat/bsc_nat.c b/openbsc/src/nat/bsc_nat.c index b8a6cfc7b..b82c4ef25 100644 --- a/openbsc/src/nat/bsc_nat.c +++ b/openbsc/src/nat/bsc_nat.c @@ -784,6 +784,7 @@ static void handle_con_stats(struct sccp_connections *con) static int forward_sccp_to_msc(struct bsc_connection *bsc, struct msgb *msg) { int con_filter = 0; + char *imsi = NULL; struct bsc_msc_connection *con_msc = NULL; struct bsc_connection *con_bsc = NULL; int con_type; @@ -818,7 +819,7 @@ static int forward_sccp_to_msc(struct bsc_connection *bsc, struct msgb *msg) struct sccp_connections *con; switch (parsed->sccp_type) { case SCCP_MSG_TYPE_CR: - filter = bsc_nat_filter_sccp_cr(bsc, msg, parsed, &con_type); + filter = bsc_nat_filter_sccp_cr(bsc, msg, parsed, &con_type, &imsi); if (filter < 0) { bsc_stat_reject(filter, bsc, 0); goto exit3; @@ -831,6 +832,9 @@ static int forward_sccp_to_msc(struct bsc_connection *bsc, struct msgb *msg) con_msc = con->msc_con; con->con_type = con_type; con->imsi_checked = filter; + if (imsi) + con->imsi = talloc_steal(con, imsi); + imsi = NULL; con_bsc = con->bsc; handle_con_stats(con); break; @@ -927,12 +931,16 @@ exit: } exit2: + if (imsi) + talloc_free(imsi); talloc_free(parsed); msgb_free(msg); return -1; exit3: /* send a SCCP Connection Refused */ + if (imsi) + talloc_free(imsi); bsc_send_con_refuse(bsc, parsed, con_type); talloc_free(parsed); msgb_free(msg); diff --git a/openbsc/src/nat/bsc_nat_utils.c b/openbsc/src/nat/bsc_nat_utils.c index 9e4ccc6e2..674de4184 100644 --- a/openbsc/src/nat/bsc_nat_utils.c +++ b/openbsc/src/nat/bsc_nat_utils.c @@ -360,7 +360,9 @@ static int auth_imsi(struct bsc_connection *bsc, const char *mi_string) return 1; } -static int _cr_check_loc_upd(struct bsc_connection *bsc, uint8_t *data, unsigned int length) +static int _cr_check_loc_upd(struct bsc_connection *bsc, + uint8_t *data, unsigned int length, + char **imsi) { uint8_t mi_type; struct gsm48_loc_upd_req *lu; @@ -383,10 +385,13 @@ static int _cr_check_loc_upd(struct bsc_connection *bsc, uint8_t *data, unsigned return 0; gsm48_mi_to_string(mi_string, sizeof(mi_string), lu->mi, lu->mi_len); + *imsi = talloc_strdup(bsc, mi_string); return auth_imsi(bsc, mi_string); } -static int _cr_check_cm_serv_req(struct bsc_connection *bsc, uint8_t *data, unsigned int length) +static int _cr_check_cm_serv_req(struct bsc_connection *bsc, + uint8_t *data, unsigned int length, + char **imsi) { static const uint32_t classmark_offset = offsetof(struct gsm48_service_request, classmark); @@ -416,10 +421,13 @@ static int _cr_check_cm_serv_req(struct bsc_connection *bsc, uint8_t *data, unsi if (mi_type != GSM_MI_TYPE_IMSI) return 0; + *imsi = talloc_strdup(bsc, mi_string); return auth_imsi(bsc, mi_string); } -static int _cr_check_pag_resp(struct bsc_connection *bsc, uint8_t *data, unsigned int length) +static int _cr_check_pag_resp(struct bsc_connection *bsc, + uint8_t *data, unsigned int length, + char **imsi) { struct gsm48_pag_resp *resp; char mi_string[GSM48_MI_SIZE]; @@ -440,6 +448,7 @@ static int _cr_check_pag_resp(struct bsc_connection *bsc, uint8_t *data, unsigne if (mi_type != GSM_MI_TYPE_IMSI) return 0; + *imsi = talloc_strdup(bsc, mi_string); return auth_imsi(bsc, mi_string); } @@ -474,7 +483,9 @@ static int _dt_check_id_resp(struct bsc_connection *bsc, } /* Filter out CR data... */ -int bsc_nat_filter_sccp_cr(struct bsc_connection *bsc, struct msgb *msg, struct bsc_nat_parsed *parsed, int *con_type) +int bsc_nat_filter_sccp_cr(struct bsc_connection *bsc, struct msgb *msg, + struct bsc_nat_parsed *parsed, int *con_type, + char **imsi) { struct tlv_parsed tp; struct gsm48_hdr *hdr48; @@ -483,6 +494,7 @@ int bsc_nat_filter_sccp_cr(struct bsc_connection *bsc, struct msgb *msg, struct uint8_t msg_type; *con_type = NAT_CON_TYPE_NONE; + *imsi = NULL; if (parsed->gsm_type != BSS_MAP_MSG_COMPLETE_LAYER_3) { LOGP(DNAT, LOGL_ERROR, @@ -521,15 +533,15 @@ int bsc_nat_filter_sccp_cr(struct bsc_connection *bsc, struct msgb *msg, struct if (hdr48->proto_discr == GSM48_PDISC_MM && msg_type == GSM48_MT_MM_LOC_UPD_REQUEST) { *con_type = NAT_CON_TYPE_LU; - return _cr_check_loc_upd(bsc, &hdr48->data[0], hdr48_len - sizeof(*hdr48)); + return _cr_check_loc_upd(bsc, &hdr48->data[0], hdr48_len - sizeof(*hdr48), imsi); } else if (hdr48->proto_discr == GSM48_PDISC_MM && msg_type == GSM48_MT_MM_CM_SERV_REQ) { *con_type = NAT_CON_TYPE_CM_SERV_REQ; - return _cr_check_cm_serv_req(bsc, &hdr48->data[0], hdr48_len - sizeof(*hdr48)); + return _cr_check_cm_serv_req(bsc, &hdr48->data[0], hdr48_len - sizeof(*hdr48), imsi); } else if (hdr48->proto_discr == GSM48_PDISC_RR && msg_type == GSM48_MT_RR_PAG_RESP) { *con_type = NAT_CON_TYPE_PAG_RESP; - return _cr_check_pag_resp(bsc, &hdr48->data[0], hdr48_len - sizeof(*hdr48)); + return _cr_check_pag_resp(bsc, &hdr48->data[0], hdr48_len - sizeof(*hdr48), imsi); } else { /* We only want to filter the above, let other things pass */ *con_type = NAT_CON_TYPE_OTHER; |