nat: Parse the id response, extract the IMSI, compare it
Add a test case and also add a basic check that we got some size checks correct. The next step is to act on the result.
This commit is contained in:
parent
d880f54f4b
commit
3268540fc3
|
@ -369,6 +369,35 @@ static int _cr_check_pag_resp(struct bsc_connection *bsc, uint8_t *data, unsigne
|
|||
return auth_imsi(bsc, mi_string);
|
||||
}
|
||||
|
||||
static int _dt_check_id_resp(struct bsc_connection *bsc,
|
||||
uint8_t *data, unsigned int length,
|
||||
struct sccp_connections *con)
|
||||
{
|
||||
char mi_string[GSM48_MI_SIZE];
|
||||
uint8_t mi_type;
|
||||
int ret;
|
||||
|
||||
if (length < 2) {
|
||||
LOGP(DNAT, LOGL_ERROR, "mi does not fit.\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (data[0] < length - 1) {
|
||||
LOGP(DNAT, LOGL_ERROR, "mi length too big.\n");
|
||||
return -2;
|
||||
}
|
||||
|
||||
mi_type = data[1] & GSM_MI_TYPE_MASK;
|
||||
gsm48_mi_to_string(mi_string, sizeof(mi_string), &data[1], data[0]);
|
||||
|
||||
if (mi_type != GSM_MI_TYPE_IMSI)
|
||||
return 0;
|
||||
|
||||
ret = auth_imsi(bsc, mi_string);
|
||||
con->imsi_checked = 1;
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* 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)
|
||||
{
|
||||
|
@ -434,10 +463,38 @@ int bsc_nat_filter_sccp_cr(struct bsc_connection *bsc, struct msgb *msg, struct
|
|||
int bsc_nat_filter_dt(struct bsc_connection *bsc, struct msgb *msg,
|
||||
struct sccp_connections *con, struct bsc_nat_parsed *parsed)
|
||||
{
|
||||
uint32_t len;
|
||||
struct gsm48_hdr *hdr48;
|
||||
|
||||
if (con->imsi_checked)
|
||||
return 0;
|
||||
|
||||
return 0;
|
||||
/* only care about DTAP messages */
|
||||
if (parsed->bssap != BSSAP_MSG_DTAP)
|
||||
return 0;
|
||||
|
||||
/* gsm_type is actually the size of the dtap */
|
||||
len = parsed->gsm_type;
|
||||
if (len < msgb_l3len(msg) - 3) {
|
||||
LOGP(DNAT, LOGL_ERROR, "Not enough space for DTAP.\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (len < sizeof(*hdr48)) {
|
||||
LOGP(DNAT, LOGL_ERROR, "GSM48 header does not fit.\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
msg->l4h = &msg->l3h[3];
|
||||
hdr48 = (struct gsm48_hdr *) msg->l4h;
|
||||
|
||||
if (hdr48->proto_discr == GSM48_PDISC_MM &&
|
||||
(hdr48->msg_type & 0xbf) == GSM48_MT_MM_ID_RESP) {
|
||||
return _dt_check_id_resp(bsc, &hdr48->data[0], len - sizeof(*hdr48), con);
|
||||
} else {
|
||||
printf("%d %x\n", hdr48->proto_discr, hdr48->msg_type);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
void bsc_parse_reg(void *ctx, regex_t *reg, char **imsi, int argc, const char **argv)
|
||||
|
|
|
@ -88,6 +88,14 @@ static const uint8_t ass_cmd[] = {
|
|||
0x01, 0x0b, 0x03, 0x01, 0x0a, 0x11, 0x01, 0x00,
|
||||
0x15 };
|
||||
|
||||
/* identity response */
|
||||
static const uint8_t id_resp[] = {
|
||||
0x00, 0x15, 0xfd, 0x06, 0x01, 0x1c, 0xdc,
|
||||
0x00, 0x01, 0x0e, 0x01, 0x00, 0x0b, 0x05, 0x59,
|
||||
0x08, 0x29, 0x40, 0x21, 0x03, 0x07, 0x48, 0x66,
|
||||
0x31
|
||||
};
|
||||
|
||||
/*
|
||||
* MGCP messages
|
||||
*/
|
||||
|
|
|
@ -31,6 +31,7 @@
|
|||
#include <osmocore/talloc.h>
|
||||
|
||||
#include <osmocom/sccp/sccp.h>
|
||||
#include <osmocore/protocol/gsm_08_08.h>
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
|
@ -696,6 +697,58 @@ static void test_cr_filter()
|
|||
msgb_free(msg);
|
||||
}
|
||||
|
||||
static void test_dt_filter()
|
||||
{
|
||||
int i;
|
||||
struct msgb *msg = msgb_alloc(4096, "test_dt_filter");
|
||||
struct bsc_nat_parsed *parsed;
|
||||
|
||||
struct bsc_nat *nat = bsc_nat_alloc();
|
||||
struct bsc_connection *bsc = bsc_connection_alloc(nat);
|
||||
struct sccp_connections *con = talloc_zero(0, struct sccp_connections);
|
||||
|
||||
bsc->cfg = bsc_config_alloc(nat, "foo", 23);
|
||||
con->bsc = bsc;
|
||||
|
||||
msgb_reset(msg);
|
||||
copy_to_msg(msg, id_resp, ARRAY_SIZE(id_resp));
|
||||
|
||||
parsed = bsc_nat_parse(msg);
|
||||
if (!parsed) {
|
||||
fprintf(stderr, "FAIL: Could not parse ID resp\n");
|
||||
abort();
|
||||
}
|
||||
|
||||
if (parsed->bssap != BSSAP_MSG_DTAP) {
|
||||
fprintf(stderr, "FAIL: It should be dtap\n");
|
||||
abort();
|
||||
}
|
||||
|
||||
/* gsm_type is actually the size of the dtap */
|
||||
if (parsed->gsm_type < msgb_l3len(msg) - 3) {
|
||||
fprintf(stderr, "FAIL: Not enough space for the content\n");
|
||||
abort();
|
||||
}
|
||||
|
||||
if (bsc_nat_filter_dt(bsc, msg, con, parsed) != 1) {
|
||||
fprintf(stderr, "FAIL: Should have passed..\n");
|
||||
abort();
|
||||
}
|
||||
|
||||
/* just some basic length checking... */
|
||||
for (i = ARRAY_SIZE(id_resp); i >= 0; --i) {
|
||||
msgb_reset(msg);
|
||||
copy_to_msg(msg, id_resp, ARRAY_SIZE(id_resp));
|
||||
|
||||
parsed = bsc_nat_parse(msg);
|
||||
if (!parsed)
|
||||
continue;
|
||||
|
||||
con->imsi_checked = 0;
|
||||
bsc_nat_filter_dt(bsc, msg, con, parsed);
|
||||
}
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
struct log_target *stderr_target;
|
||||
|
@ -714,6 +767,7 @@ int main(int argc, char **argv)
|
|||
test_mgcp_rewrite();
|
||||
test_mgcp_parse();
|
||||
test_cr_filter();
|
||||
test_dt_filter();
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue