diff options
-rw-r--r-- | openbsc/include/openbsc/bsc_nat.h | 5 | ||||
-rw-r--r-- | openbsc/src/osmo-bsc_nat/bsc_filter.c | 26 | ||||
-rw-r--r-- | openbsc/src/osmo-bsc_nat/bsc_nat.c | 102 | ||||
-rw-r--r-- | openbsc/src/osmo-bsc_nat/bsc_nat_rewrite.c | 2 | ||||
-rw-r--r-- | openbsc/src/osmo-bsc_nat/bsc_ussd.c | 11 | ||||
-rw-r--r-- | openbsc/tests/bsc-nat/bsc_nat_test.c | 164 |
6 files changed, 136 insertions, 174 deletions
diff --git a/openbsc/include/openbsc/bsc_nat.h b/openbsc/include/openbsc/bsc_nat.h index 3eba70d65..86134bec7 100644 --- a/openbsc/include/openbsc/bsc_nat.h +++ b/openbsc/include/openbsc/bsc_nat.h @@ -356,10 +356,7 @@ void bsc_close_connection(struct bsc_connection *); const char *bsc_con_type_to_string(int type); -/** - * parse the given message into the above structure - */ -struct bsc_nat_parsed *bsc_nat_parse(struct msgb *msg); +int bsc_nat_parse(struct msgb *msg, struct bsc_nat_parsed *parsed); /** * filter based on IP Access header in both directions diff --git a/openbsc/src/osmo-bsc_nat/bsc_filter.c b/openbsc/src/osmo-bsc_nat/bsc_filter.c index 432529e15..a8786829d 100644 --- a/openbsc/src/osmo-bsc_nat/bsc_filter.c +++ b/openbsc/src/osmo-bsc_nat/bsc_filter.c @@ -72,19 +72,24 @@ static struct bsc_pkt_filter white_list[] = { { IPAC_PROTO_MGCP_OLD, ALLOW_ANY, ALLOW_ANY, ALLOW_ANY, FILTER_TO_BOTH }, }; -struct bsc_nat_parsed *bsc_nat_parse(struct msgb *msg) + /*! Parse the given message into the parsed structure. + * \param[in] msg the IPA message to parse + * \param[out] parsed the structure to fill with parsed values + * \returns 0 on success, negative on error + */ +int bsc_nat_parse(struct msgb *msg, struct bsc_nat_parsed *parsed) { struct sccp_parse_result result; - struct bsc_nat_parsed *parsed; struct ipaccess_head *hh; /* quick fail */ if (msg->len < 4) - return NULL; + return -1; - parsed = talloc_zero(msg, struct bsc_nat_parsed); if (!parsed) - return NULL; + return -1; + + memset(parsed, 0, sizeof(*parsed)); /* more init */ parsed->ipa_proto = parsed->called_ssn = parsed->calling_ssn = -1; @@ -99,22 +104,19 @@ struct bsc_nat_parsed *bsc_nat_parse(struct msgb *msg) /* do a size check on the input */ if (ntohs(hh->len) != msgb_l2len(msg)) { LOGP(DLINP, LOGL_ERROR, "Wrong input length?\n"); - talloc_free(parsed); - return NULL; + return -1; } /* analyze sccp down here */ if (parsed->ipa_proto == IPAC_PROTO_SCCP) { memset(&result, 0, sizeof(result)); if (sccp_parse_header(msg, &result) != 0) { - talloc_free(parsed); - return 0; + return -1; } if (msg->l3h && msgb_l3len(msg) < 3) { LOGP(DNAT, LOGL_ERROR, "Not enough space or GSM payload\n"); - talloc_free(parsed); - return 0; + return -1; } parsed->sccp_type = sccp_determine_msg_type(msg); @@ -132,7 +134,7 @@ struct bsc_nat_parsed *bsc_nat_parse(struct msgb *msg) } } - return parsed; + return 0; } /* Returns 0 if message is whitelisted (has to beforwarded by bsc-nat), 1 if diff --git a/openbsc/src/osmo-bsc_nat/bsc_nat.c b/openbsc/src/osmo-bsc_nat/bsc_nat.c index 30e4b3423..2e2eac04d 100644 --- a/openbsc/src/osmo-bsc_nat/bsc_nat.c +++ b/openbsc/src/osmo-bsc_nat/bsc_nat.c @@ -696,24 +696,23 @@ static int forward_sccp_to_bts(struct bsc_msc_connection *msc_con, struct msgb * { struct nat_sccp_connection *con = NULL; struct bsc_connection *bsc; - struct bsc_nat_parsed *parsed; + struct bsc_nat_parsed parsed; int proto; /* filter, drop, patch the message? */ - parsed = bsc_nat_parse(msg); - if (!parsed) { + if (bsc_nat_parse(msg, &parsed) < 0) { LOGP(DNAT, LOGL_ERROR, "Can not parse msg from BSC.\n"); return -1; } - if (bsc_nat_filter_ipa(DIR_BSC, msg, parsed)) + if (bsc_nat_filter_ipa(DIR_BSC, msg, &parsed)) goto exit; - proto = parsed->ipa_proto; + proto = parsed.ipa_proto; /* Route and modify the SCCP packet */ if (proto == IPAC_PROTO_SCCP) { - switch (parsed->sccp_type) { + switch (parsed.sccp_type) { case SCCP_MSG_TYPE_UDT: /* forward UDT messages to every BSC */ goto send_to_all; @@ -722,8 +721,8 @@ static int forward_sccp_to_bts(struct bsc_msc_connection *msc_con, struct msgb * case SCCP_MSG_TYPE_CREF: case SCCP_MSG_TYPE_DT1: case SCCP_MSG_TYPE_IT: - con = patch_sccp_src_ref_to_bsc(msg, parsed, nat); - if (parsed->gsm_type == BSS_MAP_MSG_ASSIGMENT_RQST) { + con = patch_sccp_src_ref_to_bsc(msg, &parsed, nat); + if (parsed.gsm_type == BSS_MAP_MSG_ASSIGMENT_RQST) { osmo_counter_inc(nat->stats.sccp.calls); if (con) { @@ -735,14 +734,14 @@ static int forward_sccp_to_bts(struct bsc_msc_connection *msc_con, struct msgb * } else LOGP(DNAT, LOGL_ERROR, "Assignment command but no BSC.\n"); } else if (con && con->con_local == NAT_CON_END_USSD && - parsed->gsm_type == BSS_MAP_MSG_CLEAR_CMD) { + parsed.gsm_type == BSS_MAP_MSG_CLEAR_CMD) { LOGP(DNAT, LOGL_NOTICE, "Clear Command for USSD Connection. Ignoring.\n"); con = NULL; } break; case SCCP_MSG_TYPE_CC: - con = patch_sccp_src_ref_to_bsc(msg, parsed, nat); - if (!con || update_sccp_src_ref(con, parsed) != 0) + con = patch_sccp_src_ref_to_bsc(msg, &parsed, nat); + if (!con || update_sccp_src_ref(con, &parsed) != 0) goto exit; break; case SCCP_MSG_TYPE_RLC: @@ -755,27 +754,24 @@ static int forward_sccp_to_bts(struct bsc_msc_connection *msc_con, struct msgb * goto exit; } - if (!con && parsed->sccp_type == SCCP_MSG_TYPE_RLSD) { + if (!con && parsed.sccp_type == SCCP_MSG_TYPE_RLSD) { LOGP(DNAT, LOGL_NOTICE, "Sending fake RLC on RLSD message to network.\n"); /* Exchange src/dest for the reply */ - nat_send_rlc(msc_con, &parsed->original_dest_ref, - parsed->src_local_ref); + nat_send_rlc(msc_con, &parsed.original_dest_ref, + parsed.src_local_ref); } else if (!con) - LOGP(DNAT, LOGL_ERROR, "Unknown connection for msg type: 0x%x from the MSC.\n", parsed->sccp_type); + LOGP(DNAT, LOGL_ERROR, "Unknown connection for msg type: 0x%x from the MSC.\n", parsed.sccp_type); } - if (!con) { - talloc_free(parsed); + if (!con) return -1; - } + if (!con->bsc->authenticated) { - talloc_free(parsed); LOGP(DNAT, LOGL_ERROR, "Selected BSC not authenticated.\n"); return -1; } - update_con_authorize(con, parsed, msg); - talloc_free(parsed); + update_con_authorize(con, &parsed, msg); bsc_send_data(con->bsc, msg->l2h, msgb_l2len(msg), proto); return 0; @@ -786,7 +782,7 @@ send_to_all: * Command to every BSC in our network. We will analys the PAGING * message and then send it to the authenticated messages... */ - if (parsed->ipa_proto == IPAC_PROTO_SCCP && parsed->gsm_type == BSS_MAP_MSG_PAGING) { + if (parsed.ipa_proto == IPAC_PROTO_SCCP && parsed.gsm_type == BSS_MAP_MSG_PAGING) { bsc_nat_handle_paging(nat, msg); goto exit; } @@ -795,11 +791,10 @@ send_to_all: if (!bsc->authenticated) continue; - bsc_send_data(bsc, msg->l2h, msgb_l2len(msg), parsed->ipa_proto); + bsc_send_data(bsc, msg->l2h, msgb_l2len(msg), parsed.ipa_proto); } exit: - talloc_free(parsed); return 0; } @@ -1130,19 +1125,19 @@ static int forward_sccp_to_msc(struct bsc_connection *bsc, struct msgb *msg, boo struct bsc_msc_connection *con_msc = NULL; struct bsc_connection *con_bsc = NULL; int con_type; - struct bsc_nat_parsed *parsed; + struct bsc_nat_parsed parsed; struct bsc_filter_reject_cause cause; *bsc_conn_closed = false; /* Parse and filter messages */ - parsed = bsc_nat_parse(msg); - if (!parsed) { + bool parsed_ok = bsc_nat_parse(msg, &parsed) == 0; + if (!parsed_ok) { LOGP(DNAT, LOGL_ERROR, "Can not parse msg from BSC.\n"); msgb_free(msg); return -1; } - if (bsc_nat_filter_ipa(DIR_MSC, msg, parsed)) + if (bsc_nat_filter_ipa(DIR_MSC, msg, &parsed)) goto exit; /* @@ -1157,32 +1152,32 @@ static int forward_sccp_to_msc(struct bsc_connection *bsc, struct msgb *msg, boo /* modify the SCCP entries */ - if (parsed->ipa_proto == IPAC_PROTO_SCCP) { + if (parsed.ipa_proto == IPAC_PROTO_SCCP) { int filter; struct nat_sccp_connection *con; - switch (parsed->sccp_type) { + switch (parsed.sccp_type) { case SCCP_MSG_TYPE_CR: memset(&cause, 0, sizeof(cause)); - filter = bsc_nat_filter_sccp_cr(bsc, msg, parsed, + filter = bsc_nat_filter_sccp_cr(bsc, msg, &parsed, &con_type, &imsi, &cause); if (filter < 0) { if (imsi) bsc_nat_inform_reject(bsc, imsi); bsc_stat_reject(filter, bsc, 0); /* send a SCCP Connection Refused */ - bsc_send_con_refuse(bsc, parsed, con_type, &cause); + bsc_send_con_refuse(bsc, &parsed, con_type, &cause); goto exit2; } - if (!create_sccp_src_ref(bsc, parsed)) + if (!create_sccp_src_ref(bsc, &parsed)) goto exit2; - con = patch_sccp_src_ref_to_msc(msg, parsed, bsc); + con = patch_sccp_src_ref_to_msc(msg, &parsed, bsc); OSMO_ASSERT(con); con->msc_con = bsc->nat->msc_con; con_msc = con->msc_con; con->filter_state.con_type = con_type; con->filter_state.imsi_checked = filter; - bsc_nat_extract_lac(bsc, con, parsed, msg); + bsc_nat_extract_lac(bsc, con, &parsed, msg); if (imsi) con->filter_state.imsi = talloc_steal(con, imsi); imsi = NULL; @@ -1194,13 +1189,13 @@ static int forward_sccp_to_msc(struct bsc_connection *bsc, struct msgb *msg, boo case SCCP_MSG_TYPE_DT1: case SCCP_MSG_TYPE_CC: case SCCP_MSG_TYPE_IT: - con = patch_sccp_src_ref_to_msc(msg, parsed, bsc); + con = patch_sccp_src_ref_to_msc(msg, &parsed, bsc); if (con) { /* only filter non local connections */ if (!con->con_local) { memset(&cause, 0, sizeof(cause)); filter = bsc_nat_filter_dt(bsc, msg, - con, parsed, &cause); + con, &parsed, &cause); if (filter < 0) { if (con->filter_state.imsi) bsc_nat_inform_reject(bsc, @@ -1212,20 +1207,19 @@ static int forward_sccp_to_msc(struct bsc_connection *bsc, struct msgb *msg, boo } /* hand data to a side channel */ - if (bsc_ussd_check(con, parsed, msg) == 1) + if (bsc_ussd_check(con, &parsed, msg) == 1) con->con_local = NAT_CON_END_USSD; /* * Optionally rewrite setup message. This can - * replace the msg and the parsed structure becomes - * invalid. + * replace the msg and hence data in struct parsed + * becomes invalid. */ - msg = bsc_nat_rewrite_msg(bsc->nat, msg, parsed, + msg = bsc_nat_rewrite_msg(bsc->nat, msg, &parsed, con->filter_state.imsi); - talloc_free(parsed); - parsed = NULL; + parsed_ok = false; } else if (con->con_local == NAT_CON_END_USSD) { - bsc_ussd_check(con, parsed, msg); + bsc_ussd_check(con, &parsed, msg); } con_bsc = con->bsc; @@ -1235,13 +1229,13 @@ static int forward_sccp_to_msc(struct bsc_connection *bsc, struct msgb *msg, boo break; case SCCP_MSG_TYPE_RLC: - con = patch_sccp_src_ref_to_msc(msg, parsed, bsc); + con = patch_sccp_src_ref_to_msc(msg, &parsed, bsc); if (con) { con_bsc = con->bsc; con_msc = con->msc_con; con_filter = con->con_local; } - remove_sccp_src_ref(bsc, msg, parsed); + remove_sccp_src_ref(bsc, msg, &parsed); *bsc_conn_closed = bsc_maybe_close(bsc); break; case SCCP_MSG_TYPE_UDT: @@ -1249,16 +1243,16 @@ static int forward_sccp_to_msc(struct bsc_connection *bsc, struct msgb *msg, boo con = NULL; break; default: - LOGP(DNAT, LOGL_ERROR, "Not forwarding to msc sccp type: 0x%x\n", parsed->sccp_type); + LOGP(DNAT, LOGL_ERROR, "Not forwarding to msc sccp type: 0x%x\n", parsed.sccp_type); con = NULL; goto exit2; break; } - } else if (parsed->ipa_proto == IPAC_PROTO_MGCP_OLD) { + } else if (parsed.ipa_proto == IPAC_PROTO_MGCP_OLD) { bsc_mgcp_forward(bsc, msg); goto exit2; } else { - LOGP(DNAT, LOGL_ERROR, "Not forwarding unknown stream id: 0x%x\n", parsed->ipa_proto); + LOGP(DNAT, LOGL_ERROR, "Not forwarding unknown stream id: 0x%x\n", parsed.ipa_proto); goto exit2; } @@ -1275,22 +1269,21 @@ static int forward_sccp_to_msc(struct bsc_connection *bsc, struct msgb *msg, boo if (!con_msc) { LOGP(DNAT, LOGL_ERROR, "Not forwarding data bsc_nr: %d ipa: %d type: 0x%x\n", bsc->cfg->nr, - parsed ? parsed->ipa_proto : -1, - parsed ? parsed->sccp_type : -1); + parsed_ok ? parsed.ipa_proto : -1, + parsed_ok ? parsed.sccp_type : -1); goto exit2; } /* send the non-filtered but maybe modified msg */ - talloc_free(parsed); queue_for_msc(con_msc, msg); return 0; exit: /* if we filter out the reset send an ack to the BSC */ - if (parsed->bssap == 0 && parsed->gsm_type == BSS_MAP_MSG_RESET) { + if (parsed.bssap == 0 && parsed.gsm_type == BSS_MAP_MSG_RESET) { send_reset_ack(bsc); - } else if (parsed->ipa_proto == IPAC_PROTO_IPACCESS) { + } else if (parsed.ipa_proto == IPAC_PROTO_IPACCESS) { /* do we know who is handling this? */ if (msg->l2h[0] == IPAC_MSGT_ID_RESP && msgb_l2len(msg) > 2) { struct tlv_parsed tvp; @@ -1315,7 +1308,6 @@ exit: exit2: if (imsi) talloc_free(imsi); - talloc_free(parsed); msgb_free(msg); return -1; } diff --git a/openbsc/src/osmo-bsc_nat/bsc_nat_rewrite.c b/openbsc/src/osmo-bsc_nat/bsc_nat_rewrite.c index e7c387c22..1dd2ada0f 100644 --- a/openbsc/src/osmo-bsc_nat/bsc_nat_rewrite.c +++ b/openbsc/src/osmo-bsc_nat/bsc_nat_rewrite.c @@ -618,8 +618,6 @@ struct msgb *bsc_nat_rewrite_msg(struct bsc_nat *nat, struct msgb *msg, struct b ipa_prepend_header(sccp, IPAC_PROTO_SCCP); - /* the parsed hangs off from msg but it needs to survive */ - talloc_steal(sccp, parsed); msgb_free(msg); return sccp; } diff --git a/openbsc/src/osmo-bsc_nat/bsc_ussd.c b/openbsc/src/osmo-bsc_nat/bsc_ussd.c index dea18073f..d44b1b2fe 100644 --- a/openbsc/src/osmo-bsc_nat/bsc_ussd.c +++ b/openbsc/src/osmo-bsc_nat/bsc_ussd.c @@ -90,30 +90,27 @@ static void ussd_pong(struct bsc_nat_ussd_con *conn) static int forward_sccp(struct bsc_nat *nat, struct msgb *msg) { struct nat_sccp_connection *con; - struct bsc_nat_parsed *parsed; + struct bsc_nat_parsed parsed; - - parsed = bsc_nat_parse(msg); - if (!parsed) { + if (bsc_nat_parse(msg, &parsed) < 0) { LOGP(DNAT, LOGL_ERROR, "Can not parse msg from USSD.\n"); msgb_free(msg); return -1; } - if (!parsed->dest_local_ref) { + if (!parsed.dest_local_ref) { LOGP(DNAT, LOGL_ERROR, "No destination local reference.\n"); msgb_free(msg); return -1; } - con = bsc_nat_find_con_by_bsc(nat, parsed->dest_local_ref); + con = bsc_nat_find_con_by_bsc(nat, parsed.dest_local_ref); if (!con || !con->bsc) { LOGP(DNAT, LOGL_ERROR, "No active connection found.\n"); msgb_free(msg); return -1; } - talloc_free(parsed); bsc_write_msg(&con->bsc->write_queue, msg); return 0; } diff --git a/openbsc/tests/bsc-nat/bsc_nat_test.c b/openbsc/tests/bsc-nat/bsc_nat_test.c index e0d0051ba..4bee60d8c 100644 --- a/openbsc/tests/bsc-nat/bsc_nat_test.c +++ b/openbsc/tests/bsc-nat/bsc_nat_test.c @@ -235,20 +235,19 @@ static void test_filter(void) printf("Testing BSS Filtering.\n"); for (i = 0; i < ARRAY_SIZE(results); ++i) { int result; - struct bsc_nat_parsed *parsed; + struct bsc_nat_parsed parsed; struct msgb *msg = msgb_alloc(4096, "test-message"); printf("Going to test item: %d\n", i); memcpy(msg->data, results[i].data, results[i].length); msg->l2h = msgb_put(msg, results[i].length); - parsed = bsc_nat_parse(msg); - if (!parsed) { + if (bsc_nat_parse(msg, &parsed) < 0) { printf("FAIL: Failed to parse the message\n"); continue; } - result = bsc_nat_filter_ipa(results[i].dir, msg, parsed); + result = bsc_nat_filter_ipa(results[i].dir, msg, &parsed); if (result != results[i].result) { printf("FAIL: Not the expected result got: %d wanted: %d\n", result, results[i].result); @@ -310,7 +309,7 @@ static void test_contrack() struct bsc_connection *con; struct nat_sccp_connection *con_found; struct nat_sccp_connection *rc_con; - struct bsc_nat_parsed *parsed; + struct bsc_nat_parsed parsed; struct msgb *msg; printf("Testing connection tracking.\n"); @@ -326,19 +325,19 @@ static void test_contrack() /* 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, con); + OSMO_ASSERT(bsc_nat_parse(msg, &parsed) == 0); + con_found = patch_sccp_src_ref_to_msc(msg, &parsed, con); if (con_found != NULL) { printf("Con should not exist realref(%u)\n", sccp_src_ref_to_int(&con_found->real_ref)); abort(); } - rc_con = create_sccp_src_ref(con, parsed); + rc_con = create_sccp_src_ref(con, &parsed); if (!rc_con) { printf("Failed to create a ref\n"); abort(); } - con_found = patch_sccp_src_ref_to_msc(msg, parsed, con); + con_found = patch_sccp_src_ref_to_msc(msg, &parsed, con); if (!con_found) { printf("Failed to find connection.\n"); abort(); @@ -356,40 +355,39 @@ static void test_contrack() printf("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); - con_found = patch_sccp_src_ref_to_bsc(msg, parsed, nat); + OSMO_ASSERT(bsc_nat_parse(msg, &parsed) == 0); + con_found = patch_sccp_src_ref_to_bsc(msg, &parsed, nat); VERIFY(con_found, con, msg, msc_cc_patched, "MSC CC"); - if (update_sccp_src_ref(con_found, parsed) != 0) { + if (update_sccp_src_ref(con_found, &parsed) != 0) { printf("Failed to update the SCCP con.\n"); abort(); } /* 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, con); + OSMO_ASSERT(bsc_nat_parse(msg, &parsed) == 0); + con_found = patch_sccp_src_ref_to_msc(msg, &parsed, con); 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); + OSMO_ASSERT(bsc_nat_parse(msg, &parsed) == 0); + 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); + OSMO_ASSERT(bsc_nat_parse(msg, &parsed) == 0); + 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, con); + OSMO_ASSERT(bsc_nat_parse(msg, &parsed) == 0); + con_found = patch_sccp_src_ref_to_msc(msg, &parsed, con); if (!con_found) { printf("Failed to find connection.\n"); abort(); @@ -403,12 +401,11 @@ static void test_contrack() printf("Failed to patch the BSC CR msg.\n"); abort(); } - remove_sccp_src_ref(con, msg, parsed); - talloc_free(parsed); + remove_sccp_src_ref(con, msg, &parsed); copy_to_msg(msg, bsc_rlc, sizeof(bsc_rlc)); - parsed = bsc_nat_parse(msg); - con_found = patch_sccp_src_ref_to_msc(msg, parsed, con); + OSMO_ASSERT(bsc_nat_parse(msg, &parsed) == 0); + con_found = patch_sccp_src_ref_to_msc(msg, &parsed, con); /* verify that it is gone */ if (con_found != NULL) { @@ -416,8 +413,6 @@ static void test_contrack() sccp_src_ref_to_int(&con_found->real_ref)); abort(); } - talloc_free(parsed); - bsc_config_free(con->cfg); bsc_nat_free(nat); @@ -507,7 +502,7 @@ static void test_mgcp_ass_tracking(void) struct bsc_connection *bsc; struct bsc_nat *nat; struct nat_sccp_connection con; - struct bsc_nat_parsed *parsed; + struct bsc_nat_parsed parsed; struct msgb *msg; printf("Testing MGCP.\n"); @@ -529,7 +524,7 @@ static void test_mgcp_ass_tracking(void) msg = msgb_alloc(4096, "foo"); copy_to_msg(msg, ass_cmd, sizeof(ass_cmd)); - parsed = bsc_nat_parse(msg); + OSMO_ASSERT(bsc_nat_parse(msg, &parsed) == 0); if (msg->l2h[16] != 0 || msg->l2h[17] != 0x1) { @@ -568,8 +563,6 @@ static void test_mgcp_ass_tracking(void) abort(); } - talloc_free(parsed); - bsc_mgcp_dlcx(&con); if (con.bsc_endp != -1 || con.msc_endp != -1 || con.bsc->_endpoint_status[1] != 0 || con.bsc->last_endpoint != 0x1) { @@ -867,7 +860,7 @@ static void test_cr_filter() { int i, res, contype; struct msgb *msg = msgb_alloc(4096, "test_cr_filter"); - struct bsc_nat_parsed *parsed; + struct bsc_nat_parsed parsed; struct bsc_msg_acc_lst *nat_lst, *bsc_lst; struct bsc_msg_acc_lst_entry *nat_entry, *bsc_entry; struct bsc_filter_reject_cause cause; @@ -912,14 +905,13 @@ static void test_cr_filter() &cr_filter[i].bsc_imsi_deny) != 0) abort(); - parsed = bsc_nat_parse(msg); - if (!parsed) { + if (bsc_nat_parse(msg, &parsed) < 0) { printf("FAIL: Failed to parse the message\n"); abort(); } memset(&cause, 0, sizeof(cause)); - res = bsc_nat_filter_sccp_cr(bsc, msg, parsed, &contype, &imsi, &cause); + res = bsc_nat_filter_sccp_cr(bsc, msg, &parsed, &contype, &imsi, &cause); if (res != cr_filter[i].result) { printf("FAIL: Wrong result %d for test %d.\n", res, i); abort(); @@ -934,8 +926,7 @@ static void test_cr_filter() abort(); } - talloc_steal(parsed, imsi); - talloc_free(parsed); + talloc_free(imsi); } msgb_free(msg); @@ -946,7 +937,7 @@ static void test_dt_filter() { int i; struct msgb *msg = msgb_alloc(4096, "test_dt_filter"); - struct bsc_nat_parsed *parsed; + struct bsc_nat_parsed parsed; struct bsc_filter_reject_cause cause; struct bsc_nat *nat = bsc_nat_alloc(); @@ -960,26 +951,25 @@ static void test_dt_filter() msgb_reset(msg); copy_to_msg(msg, id_resp, ARRAY_SIZE(id_resp)); - parsed = bsc_nat_parse(msg); - if (!parsed) { + if (bsc_nat_parse(msg, &parsed) < 0) { printf("FAIL: Could not parse ID resp\n"); abort(); } - if (parsed->bssap != BSSAP_MSG_DTAP) { + if (parsed.bssap != BSSAP_MSG_DTAP) { printf("FAIL: It should be dtap\n"); abort(); } /* gsm_type is actually the size of the dtap */ - if (parsed->gsm_type < msgb_l3len(msg) - 3) { + if (parsed.gsm_type < msgb_l3len(msg) - 3) { printf("FAIL: Not enough space for the content\n"); abort(); } memset(&cause, 0, sizeof(cause)); OSMO_ASSERT(!con->filter_state.imsi); - if (bsc_nat_filter_dt(bsc, msg, con, parsed, &cause) != 1) { + if (bsc_nat_filter_dt(bsc, msg, con, &parsed, &cause) != 1) { printf("FAIL: Should have passed..\n"); abort(); } @@ -991,13 +981,13 @@ static void test_dt_filter() msgb_reset(msg); copy_to_msg(msg, id_resp, ARRAY_SIZE(id_resp)); - parsed = bsc_nat_parse(msg); - if (!parsed) + if (bsc_nat_parse(msg, &parsed) < 0) continue; + con->filter_state.imsi_checked = 0; memset(&cause, 0, sizeof(cause)); - bsc_nat_filter_dt(bsc, msg, con, parsed, &cause); + bsc_nat_filter_dt(bsc, msg, con, &parsed, &cause); } msgb_free(msg); @@ -1008,7 +998,7 @@ static void test_setup_rewrite() { struct msgb *msg = msgb_alloc(4096, "test_dt_filter"); struct msgb *out; - struct bsc_nat_parsed *parsed; + struct bsc_nat_parsed parsed; const char *imsi = "27408000001234"; struct bsc_nat *nat = bsc_nat_alloc(); @@ -1028,31 +1018,28 @@ static void test_setup_rewrite() /* verify that nothing changed */ msgb_reset(msg); copy_to_msg(msg, cc_setup_international, ARRAY_SIZE(cc_setup_international)); - parsed = bsc_nat_parse(msg); - if (!parsed) { + if (bsc_nat_parse(msg, &parsed) < 0) { printf("FAIL: Could not parse ID resp\n"); abort(); } - out = bsc_nat_rewrite_msg(nat, msg, parsed, imsi); + out = bsc_nat_rewrite_msg(nat, msg, &parsed, imsi); if (msg != out) { printf("FAIL: The message should not have been changed\n"); abort(); } verify_msg(out, cc_setup_international, ARRAY_SIZE(cc_setup_international)); - talloc_free(parsed); /* verify that something in the message changes */ msgb_reset(msg); copy_to_msg(msg, cc_setup_national, ARRAY_SIZE(cc_setup_national)); - parsed = bsc_nat_parse(msg); - if (!parsed) { + if (bsc_nat_parse(msg, &parsed) < 0) { printf("FAIL: Could not parse ID resp\n"); abort(); } - out = bsc_nat_rewrite_msg(nat, msg, parsed, imsi); + out = bsc_nat_rewrite_msg(nat, msg, &parsed, imsi); if (!out) { printf("FAIL: A new message should be created.\n"); abort(); @@ -1071,13 +1058,12 @@ static void test_setup_rewrite() bsc_nat_num_rewr_entry_adapt(nat, &nat->num_rewr, &entries); msg = msgb_alloc(4096, "test_dt_filter"); copy_to_msg(msg, cc_setup_national, ARRAY_SIZE(cc_setup_national)); - parsed = bsc_nat_parse(msg); - if (!parsed) { + if (bsc_nat_parse(msg, &parsed) < 0) { printf("FAIL: Could not parse ID resp\n"); abort(); } - out = bsc_nat_rewrite_msg(nat, msg, parsed, imsi); + out = bsc_nat_rewrite_msg(nat, msg, &parsed, imsi); if (!out) { printf("FAIL: A new message should be created.\n"); abort(); @@ -1096,13 +1082,12 @@ static void test_setup_rewrite() bsc_nat_num_rewr_entry_adapt(nat, &nat->num_rewr, &entries); msg = msgb_alloc(4096, "test_dt_filter"); copy_to_msg(msg, cc_setup_national, ARRAY_SIZE(cc_setup_national)); - parsed = bsc_nat_parse(msg); - if (!parsed) { + if (bsc_nat_parse(msg, &parsed) < 0) { printf("FAIL: Could not parse ID resp\n"); abort(); } - out = bsc_nat_rewrite_msg(nat, msg, parsed, imsi); + out = bsc_nat_rewrite_msg(nat, msg, &parsed, imsi); if (out != msg) { printf("FAIL: The message should be unchanged.\n"); abort(); @@ -1118,13 +1103,12 @@ static void test_setup_rewrite() bsc_nat_num_rewr_entry_adapt(nat, &nat->num_rewr, &entries); msg = msgb_alloc(4096, "test_dt_filter"); copy_to_msg(msg, cc_setup_national_patched, ARRAY_SIZE(cc_setup_national_patched)); - parsed = bsc_nat_parse(msg); - if (!parsed) { + if (bsc_nat_parse(msg, &parsed) < 0) { printf("FAIL: Could not parse ID resp %d\n", __LINE__); abort(); } - out = bsc_nat_rewrite_msg(nat, msg, parsed, imsi); + out = bsc_nat_rewrite_msg(nat, msg, &parsed, imsi); if (!out) { printf("FAIL: A new message should be created %d.\n", __LINE__); abort(); @@ -1146,13 +1130,12 @@ static void test_setup_rewrite() bsc_nat_num_rewr_entry_adapt(nat, &nat->num_rewr, &entries); msg = msgb_alloc(4096, "test_dt_filter"); copy_to_msg(msg, cc_setup_national_patched, ARRAY_SIZE(cc_setup_national_patched)); - parsed = bsc_nat_parse(msg); - if (!parsed) { + if (bsc_nat_parse(msg, &parsed) < 0) { printf("FAIL: Could not parse ID resp %d\n", __LINE__); abort(); } - out = bsc_nat_rewrite_msg(nat, msg, parsed, imsi); + out = bsc_nat_rewrite_msg(nat, msg, &parsed, imsi); if (!out) { printf("FAIL: A new message should be created %d.\n", __LINE__); abort(); @@ -1174,7 +1157,7 @@ static void test_setup_rewrite_prefix(void) { struct msgb *msg = msgb_alloc(4096, "test_dt_filter"); struct msgb *out; - struct bsc_nat_parsed *parsed; + struct bsc_nat_parsed parsed; const char *imsi = "27408000001234"; struct bsc_nat *nat = bsc_nat_alloc(); @@ -1195,13 +1178,12 @@ static void test_setup_rewrite_prefix(void) msgb_reset(msg); copy_to_msg(msg, cc_setup_national, ARRAY_SIZE(cc_setup_national)); - parsed = bsc_nat_parse(msg); - if (!parsed) { + if (bsc_nat_parse(msg, &parsed) < 0) { printf("FAIL: Could not parse ID resp\n"); abort(); } - out = bsc_nat_rewrite_msg(nat, msg, parsed, imsi); + out = bsc_nat_rewrite_msg(nat, msg, &parsed, imsi); if (!out) { printf("FAIL: A new message should be created.\n"); abort(); @@ -1223,7 +1205,7 @@ static void test_setup_rewrite_post(void) { struct msgb *msg = msgb_alloc(4096, "test_dt_filter"); struct msgb *out; - struct bsc_nat_parsed *parsed; + struct bsc_nat_parsed parsed; const char *imsi = "27408000001234"; struct bsc_nat *nat = bsc_nat_alloc(); @@ -1255,13 +1237,12 @@ static void test_setup_rewrite_post(void) msgb_reset(msg); copy_to_msg(msg, cc_setup_national, ARRAY_SIZE(cc_setup_national)); - parsed = bsc_nat_parse(msg); - if (!parsed) { + if (bsc_nat_parse(msg, &parsed) < 0) { printf("FAIL: Could not parse ID resp\n"); abort(); } - out = bsc_nat_rewrite_msg(nat, msg, parsed, imsi); + out = bsc_nat_rewrite_msg(nat, msg, &parsed, imsi); if (!out) { printf("FAIL: A new message should be created.\n"); abort(); @@ -1281,7 +1262,7 @@ static void test_setup_rewrite_post(void) static void test_sms_smsc_rewrite() { struct msgb *msg = msgb_alloc(4096, "SMSC rewrite"), *out; - struct bsc_nat_parsed *parsed; + struct bsc_nat_parsed parsed; const char *imsi = "515039900406700"; struct bsc_nat *nat = bsc_nat_alloc(); @@ -1317,13 +1298,12 @@ static void test_sms_smsc_rewrite() * Check if the SMSC address is changed */ copy_to_msg(msg, smsc_rewrite, ARRAY_SIZE(smsc_rewrite)); - parsed = bsc_nat_parse(msg); - if (!parsed) { + if (bsc_nat_parse(msg, &parsed) < 0) { printf("FAIL: Could not parse SMS\n"); abort(); } - out = bsc_nat_rewrite_msg(nat, msg, parsed, imsi); + out = bsc_nat_rewrite_msg(nat, msg, &parsed, imsi); if (out == msg) { printf("FAIL: This should have changed.\n"); abort(); @@ -1337,13 +1317,12 @@ static void test_sms_smsc_rewrite() bsc_nat_num_rewr_entry_adapt(nat, &nat->smsc_rewr, NULL); msg = msgb_alloc(4096, "SMSC rewrite"); copy_to_msg(msg, smsc_rewrite, ARRAY_SIZE(smsc_rewrite)); - parsed = bsc_nat_parse(msg); - if (!parsed) { + if (bsc_nat_parse(msg, &parsed) < 0) { printf("FAIL: Could not parse SMS\n"); abort(); } - out = bsc_nat_rewrite_msg(nat, msg, parsed, imsi); + out = bsc_nat_rewrite_msg(nat, msg, &parsed, imsi); if (out == msg) { printf("FAIL: This should have changed.\n"); abort(); @@ -1357,13 +1336,12 @@ static void test_sms_smsc_rewrite() bsc_nat_num_rewr_entry_adapt(nat, &nat->sms_clear_tp_srr, NULL); msg = msgb_alloc(4096, "SMSC rewrite"); copy_to_msg(msg, smsc_rewrite, ARRAY_SIZE(smsc_rewrite)); - parsed = bsc_nat_parse(msg); - if (!parsed) { + if (bsc_nat_parse(msg, &parsed) < 0) { printf("FAIL: Could not parse SMS\n"); abort(); } - out = bsc_nat_rewrite_msg(nat, msg, parsed, imsi); + out = bsc_nat_rewrite_msg(nat, msg, &parsed, imsi); if (out != msg) { printf("FAIL: This should not have changed.\n"); abort(); @@ -1377,7 +1355,7 @@ static void test_sms_smsc_rewrite() static void test_sms_number_rewrite(void) { struct msgb *msg, *out; - struct bsc_nat_parsed *parsed; + struct bsc_nat_parsed parsed; const char *imsi = "515039900406700"; struct bsc_nat *nat = bsc_nat_alloc(); @@ -1401,13 +1379,12 @@ static void test_sms_number_rewrite(void) */ msg = msgb_alloc(4096, "SMSC rewrite"); copy_to_msg(msg, smsc_rewrite, ARRAY_SIZE(smsc_rewrite)); - parsed = bsc_nat_parse(msg); - if (!parsed) { + if (bsc_nat_parse(msg, &parsed) < 0) { printf("FAIL: Could not parse SMS\n"); abort(); } - out = bsc_nat_rewrite_msg(nat, msg, parsed, imsi); + out = bsc_nat_rewrite_msg(nat, msg, &parsed, imsi); if (out == msg) { printf("FAIL: This should have changed.\n"); abort(); @@ -1429,13 +1406,12 @@ static void test_sms_number_rewrite(void) msg = msgb_alloc(4096, "SMSC rewrite"); copy_to_msg(msg, smsc_rewrite, ARRAY_SIZE(smsc_rewrite)); - parsed = bsc_nat_parse(msg); - if (!parsed) { + if (bsc_nat_parse(msg, &parsed) < 0) { printf("FAIL: Could not parse SMS\n"); abort(); } - out = bsc_nat_rewrite_msg(nat, msg, parsed, imsi); + out = bsc_nat_rewrite_msg(nat, msg, &parsed, imsi); if (out == msg) { printf("FAIL: This should have changed.\n"); abort(); @@ -1520,7 +1496,7 @@ static void test_nat_extract_lac() struct bsc_connection *bsc; struct bsc_nat *nat; struct nat_sccp_connection con; - struct bsc_nat_parsed *parsed; + struct bsc_nat_parsed parsed; struct msgb *msg = msgb_alloc(4096, "test-message"); printf("Testing LAC extraction from SCCP CR\n"); @@ -1538,8 +1514,8 @@ static void test_nat_extract_lac() memcpy(msg->l2h, bssmap_cr, ARRAY_SIZE(bssmap_cr)); /* parse it and pass it on */ - parsed = bsc_nat_parse(msg); - res = bsc_nat_extract_lac(bsc, &con, parsed, msg); + OSMO_ASSERT(bsc_nat_parse(msg, &parsed) == 0); + res = bsc_nat_extract_lac(bsc, &con, &parsed, msg); OSMO_ASSERT(res == 0); /* verify the LAC */ |