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:
Holger Hans Peter Freyther 2010-09-15 05:20:40 +08:00
parent d880f54f4b
commit 3268540fc3
3 changed files with 120 additions and 1 deletions

View File

@ -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)

View File

@ -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
*/

View File

@ -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;
}