diff --git a/openbsc/tests/bsc-nat/Makefile.am b/openbsc/tests/bsc-nat/Makefile.am index 0a47e374d..f0d21f01f 100644 --- a/openbsc/tests/bsc-nat/Makefile.am +++ b/openbsc/tests/bsc-nat/Makefile.am @@ -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) diff --git a/openbsc/tests/bsc-nat/bsc_data.c b/openbsc/tests/bsc-nat/bsc_data.c new file mode 100644 index 000000000..b31bf2299 --- /dev/null +++ b/openbsc/tests/bsc-nat/bsc_data.c @@ -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 }; diff --git a/openbsc/tests/bsc-nat/bsc_nat_test.c b/openbsc/tests/bsc-nat/bsc_nat_test.c index df9c5b9cb..399cec962 100644 --- a/openbsc/tests/bsc-nat/bsc_nat_test.c +++ b/openbsc/tests/bsc-nat/bsc_nat_test.c @@ -27,6 +27,8 @@ #include #include +#include + #include /* 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; +}