nat: Add a test case for the connection tracking
This test case tests connectiont tracking by sending a CR, getting a CC, sending a DTAP, receiving a DTAP, receiving a RLSD, sending a RLC. It verifies that the messages are properly patched specially the references at the BSC.
This commit is contained in:
parent
64622e42ed
commit
38f7c75739
|
@ -1,7 +1,12 @@
|
|||
INCLUDES = $(all_includes) -I$(top_srcdir)/include
|
||||
AM_CFLAGS=-Wall -ggdb3
|
||||
AM_CFLAGS=-Wall -ggdb3 $(LIBOSMOCORE_CFLAGS)
|
||||
|
||||
EXTRA_DIST = bsc_data.c
|
||||
|
||||
noinst_PROGRAMS = bsc_nat_test
|
||||
|
||||
bsc_nat_test_SOURCES = bsc_nat_test.c $(top_srcdir)/src/nat/bsc_filter.c
|
||||
bsc_nat_test_LDADD = $(top_builddir)/src/libbsc.a $(top_builddir)/src/libsccp.a
|
||||
bsc_nat_test_SOURCES = bsc_nat_test.c \
|
||||
$(top_srcdir)/src/nat/bsc_filter.c \
|
||||
$(top_srcdir)/src/nat/bsc_sccp.c \
|
||||
$(top_srcdir)/src/nat/bsc_nat_utils.c
|
||||
bsc_nat_test_LDADD = $(top_builddir)/src/libbsc.a $(top_builddir)/src/libsccp.a $(LIBOSMOCORE_LIBS)
|
||||
|
|
|
@ -0,0 +1,72 @@
|
|||
/* test data */
|
||||
|
||||
/* BSC -> MSC, CR */
|
||||
static const u_int8_t bsc_cr[] = {
|
||||
0x00, 0x2e, 0xfd,
|
||||
0x01, 0x00, 0x00, 0x15, 0x02, 0x02, 0x04, 0x02,
|
||||
0x42, 0xfe, 0x0f, 0x21, 0x00, 0x1f, 0x57, 0x05,
|
||||
0x08, 0x00, 0x72, 0xf4, 0x80, 0x20, 0x1c, 0xc3,
|
||||
0x51, 0x17, 0x12, 0x05, 0x08, 0x20, 0x72, 0xf4,
|
||||
0x90, 0x20, 0x1d, 0x50, 0x08, 0x29, 0x47, 0x80,
|
||||
0x00, 0x00, 0x00, 0x00, 0x80, 0x00 };
|
||||
|
||||
static const u_int8_t bsc_cr_patched[] = {
|
||||
0x00, 0x2e, 0xfd,
|
||||
0x01, 0x00, 0x00, 0x05, 0x02, 0x02, 0x04, 0x02,
|
||||
0x42, 0xfe, 0x0f, 0x21, 0x00, 0x1f, 0x57, 0x05,
|
||||
0x08, 0x00, 0x72, 0xf4, 0x80, 0x20, 0x1c, 0xc3,
|
||||
0x51, 0x17, 0x12, 0x05, 0x08, 0x20, 0x72, 0xf4,
|
||||
0x90, 0x20, 0x1d, 0x50, 0x08, 0x29, 0x47, 0x80,
|
||||
0x00, 0x00, 0x00, 0x00, 0x80, 0x00 };
|
||||
|
||||
/* CC, MSC -> BSC */
|
||||
static const u_int8_t msc_cc[] = {
|
||||
0x00, 0x0a, 0xfd,
|
||||
0x02, 0x00, 0x00, 0x05, 0x01, 0x1f, 0xe4, 0x02,
|
||||
0x01, 0x00 };
|
||||
static const u_int8_t msc_cc_patched[] = {
|
||||
0x00, 0x0a, 0xfd,
|
||||
0x02, 0x00, 0x00, 0x15, 0x01, 0x1f, 0xe4, 0x02,
|
||||
0x01, 0x00 };
|
||||
|
||||
/* Classmark, BSC -> MSC */
|
||||
static const u_int8_t bsc_dtap[] = {
|
||||
0x00, 0x17, 0xfd,
|
||||
0x06, 0x01, 0x1f, 0xe4, 0x00, 0x01, 0x10, 0x00,
|
||||
0x0e, 0x54, 0x12, 0x03, 0x50, 0x18, 0x93, 0x13,
|
||||
0x06, 0x60, 0x14, 0x45, 0x00, 0x81, 0x00 };
|
||||
|
||||
static const u_int8_t bsc_dtap_patched[] = {
|
||||
0x00, 0x17, 0xfd,
|
||||
0x06, 0x01, 0x1f, 0xe4, 0x00, 0x01, 0x10, 0x00,
|
||||
0x0e, 0x54, 0x12, 0x03, 0x50, 0x18, 0x93, 0x13,
|
||||
0x06, 0x60, 0x14, 0x45, 0x00, 0x81, 0x00 };
|
||||
|
||||
/* Clear command, MSC -> BSC */
|
||||
static const u_int8_t msc_dtap[] = {
|
||||
0x00, 0x0d, 0xfd,
|
||||
0x06, 0x00, 0x00, 0x05, 0x00, 0x01, 0x06, 0x00,
|
||||
0x04, 0x20, 0x04, 0x01, 0x09 };
|
||||
static const u_int8_t msc_dtap_patched[] = {
|
||||
0x00, 0x0d, 0xfd,
|
||||
0x06, 0x00, 0x00, 0x15, 0x00, 0x01, 0x06, 0x00,
|
||||
0x04, 0x20, 0x04, 0x01, 0x09 };
|
||||
|
||||
/*RLSD, MSC -> BSC */
|
||||
static const u_int8_t msc_rlsd[] = {
|
||||
0x00, 0x0a, 0xfd,
|
||||
0x04, 0x00, 0x00, 0x05, 0x01, 0x1f, 0xe4, 0x00,
|
||||
0x01, 0x00 };
|
||||
static const u_int8_t msc_rlsd_patched[] = {
|
||||
0x00, 0x0a, 0xfd,
|
||||
0x04, 0x00, 0x00, 0x15, 0x01, 0x1f, 0xe4, 0x00,
|
||||
0x01, 0x00 };
|
||||
|
||||
/* RLC, BSC -> MSC */
|
||||
static const u_int8_t bsc_rlc[] = {
|
||||
0x00, 0x07, 0xfd,
|
||||
0x05, 0x01, 0x1f, 0xe4, 0x00, 0x00, 0x15 };
|
||||
|
||||
static const u_int8_t bsc_rlc_patched[] = {
|
||||
0x00, 0x07, 0xfd,
|
||||
0x05, 0x01, 0x1f, 0xe4, 0x00, 0x00, 0x05 };
|
|
@ -27,6 +27,8 @@
|
|||
#include <openbsc/gsm_data.h>
|
||||
#include <openbsc/bsc_nat.h>
|
||||
|
||||
#include <osmocore/talloc.h>
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
/* test messages for ipa */
|
||||
|
@ -145,12 +147,13 @@ static const struct filter_result results[] = {
|
|||
},
|
||||
};
|
||||
|
||||
int main(int argc, char **argv)
|
||||
static void test_filter(void)
|
||||
{
|
||||
int i;
|
||||
|
||||
|
||||
/* start testinh with proper messages */
|
||||
fprintf(stderr, "Testing BSS Filtering.\n");
|
||||
for (i = 0; i < ARRAY_SIZE(results); ++i) {
|
||||
int result;
|
||||
struct bsc_nat_parsed *parsed;
|
||||
|
@ -174,6 +177,143 @@ int main(int argc, char **argv)
|
|||
|
||||
msgb_free(msg);
|
||||
}
|
||||
}
|
||||
|
||||
#include "bsc_data.c"
|
||||
|
||||
static void copy_to_msg(struct msgb *msg, const u_int8_t *data, unsigned int length)
|
||||
{
|
||||
msgb_reset(msg);
|
||||
msg->l2h = msgb_put(msg, length);
|
||||
memcpy(msg->l2h, data, msgb_l2len(msg));
|
||||
}
|
||||
|
||||
#define VERIFY(con_found, con, msg, ver, str) \
|
||||
if (con_found != con) { \
|
||||
fprintf(stderr, "Failed to find the con: 0x%p\n", con_found); \
|
||||
abort(); \
|
||||
} \
|
||||
if (memcmp(msg->data, ver, sizeof(ver)) != 0) { \
|
||||
fprintf(stderr, "Failed to patch the %s msg.\n", str); \
|
||||
abort(); \
|
||||
}
|
||||
|
||||
/* test conn tracking once */
|
||||
static void test_contrack()
|
||||
{
|
||||
int rc;
|
||||
struct bsc_nat *nat;
|
||||
struct bsc_connection *con, *con_found;
|
||||
struct bsc_nat_parsed *parsed;
|
||||
struct msgb *msg;
|
||||
|
||||
fprintf(stderr, "Testing connection tracking.\n");
|
||||
nat = bsc_nat_alloc();
|
||||
con = bsc_connection_alloc(nat);
|
||||
msg = msgb_alloc(4096, "test");
|
||||
|
||||
/* 1.) create a connection */
|
||||
copy_to_msg(msg, bsc_cr, sizeof(bsc_cr));
|
||||
parsed = bsc_nat_parse(msg);
|
||||
con_found = patch_sccp_src_ref_to_msc(msg, parsed, nat);
|
||||
if (con_found != NULL) {
|
||||
fprintf(stderr, "Con should not exist 0x%p\n", con_found);
|
||||
abort();
|
||||
}
|
||||
rc = create_sccp_src_ref(con, msg, parsed);
|
||||
if (rc != 0) {
|
||||
fprintf(stderr, "Failed to create a ref\n");
|
||||
abort();
|
||||
}
|
||||
con_found = patch_sccp_src_ref_to_msc(msg, parsed, nat);
|
||||
if (con_found != con) {
|
||||
fprintf(stderr, "Failed to find the con: 0x%p\n", con_found);
|
||||
abort();
|
||||
}
|
||||
if (memcmp(msg->data, bsc_cr_patched, sizeof(bsc_cr_patched)) != 0) {
|
||||
fprintf(stderr, "Failed to patch the BSC CR msg.\n");
|
||||
abort();
|
||||
}
|
||||
talloc_free(parsed);
|
||||
|
||||
/* 2.) get the cc */
|
||||
copy_to_msg(msg, msc_cc, sizeof(msc_cc));
|
||||
parsed = bsc_nat_parse(msg);
|
||||
if (update_sccp_src_ref(con, msg, parsed) != 0) {
|
||||
fprintf(stderr, "Failed to update the SCCP con.\n");
|
||||
abort();
|
||||
}
|
||||
con_found = patch_sccp_src_ref_to_bsc(msg, parsed, nat);
|
||||
VERIFY(con_found, con, msg, msc_cc_patched, "MSC CC");
|
||||
|
||||
/* 3.) send some data */
|
||||
copy_to_msg(msg, bsc_dtap, sizeof(bsc_dtap));
|
||||
parsed = bsc_nat_parse(msg);
|
||||
con_found = patch_sccp_src_ref_to_msc(msg, parsed, nat);
|
||||
VERIFY(con_found, con, msg, bsc_dtap_patched, "BSC DTAP");
|
||||
|
||||
/* 4.) receive some data */
|
||||
copy_to_msg(msg, msc_dtap, sizeof(msc_dtap));
|
||||
parsed = bsc_nat_parse(msg);
|
||||
con_found = patch_sccp_src_ref_to_bsc(msg, parsed, nat);
|
||||
VERIFY(con_found, con, msg, msc_dtap_patched, "MSC DTAP");
|
||||
|
||||
/* 5.) close the connection */
|
||||
copy_to_msg(msg, msc_rlsd, sizeof(msc_rlsd));
|
||||
parsed = bsc_nat_parse(msg);
|
||||
con_found = patch_sccp_src_ref_to_bsc(msg, parsed, nat);
|
||||
VERIFY(con_found, con, msg, msc_rlsd_patched, "MSC RLSD");
|
||||
|
||||
/* 6.) confirm the connection close */
|
||||
copy_to_msg(msg, bsc_rlc, sizeof(bsc_rlc));
|
||||
parsed = bsc_nat_parse(msg);
|
||||
con_found = patch_sccp_src_ref_to_msc(msg, parsed, nat);
|
||||
if (con_found != con) {
|
||||
fprintf(stderr, "Failed to find the con: 0x%p\n", con_found);
|
||||
abort();
|
||||
}
|
||||
if (memcmp(msg->data, bsc_rlc_patched, sizeof(bsc_rlc_patched)) != 0) {
|
||||
fprintf(stderr, "Failed to patch the BSC CR msg.\n");
|
||||
abort();
|
||||
}
|
||||
remove_sccp_src_ref(con, msg, parsed);
|
||||
con_found = patch_sccp_src_ref_to_msc(msg, parsed, nat);
|
||||
|
||||
/* verify that it is gone */
|
||||
if (con_found != NULL) {
|
||||
fprintf(stderr, "Con should be gone. 0x%p\n", con_found);
|
||||
abort();
|
||||
}
|
||||
talloc_free(parsed);
|
||||
|
||||
|
||||
talloc_free(nat);
|
||||
msgb_free(msg);
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
struct debug_target *stderr_target;
|
||||
|
||||
stderr_target = debug_target_create_stderr();
|
||||
debug_add_target(stderr_target);
|
||||
debug_set_all_filter(stderr_target, 1);
|
||||
|
||||
test_filter();
|
||||
|
||||
debug_set_log_level(stderr_target, 1);
|
||||
test_contrack();
|
||||
return 0;
|
||||
}
|
||||
|
||||
void input_event()
|
||||
{}
|
||||
int nm_state_event()
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
int gsm0408_rcvmsg(struct msgb *msg, u_int8_t link_id)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue