diff --git a/openbsc/include/openbsc/bsc_nat.h b/openbsc/include/openbsc/bsc_nat.h index 6ec666a17..e27234911 100644 --- a/openbsc/include/openbsc/bsc_nat.h +++ b/openbsc/include/openbsc/bsc_nat.h @@ -205,5 +205,6 @@ void bsc_mgcp_forward(struct bsc_connection *bsc, struct msgb *msg); int bsc_mgcp_parse_response(const char *str, int *code, char transaction[60]); int bsc_mgcp_extract_ci(const char *resp); +int bsc_mgcp_extract_port(const char *resp); #endif diff --git a/openbsc/src/nat/bsc_mgcp_utils.c b/openbsc/src/nat/bsc_mgcp_utils.c index 74ef67bb5..82eeefc6b 100644 --- a/openbsc/src/nat/bsc_mgcp_utils.c +++ b/openbsc/src/nat/bsc_mgcp_utils.c @@ -185,7 +185,7 @@ void bsc_mgcp_forward(struct bsc_connection *bsc, struct msgb *msg) struct msgb *output; struct bsc_endpoint *bsc_endp = NULL; struct mgcp_endpoint *endp = NULL; - int i, code; + int i, code, port; char transaction_id[60]; /* Some assumption that our buffer is big enough.. and null terminate */ @@ -223,6 +223,9 @@ void bsc_mgcp_forward(struct bsc_connection *bsc, struct msgb *msg) /* make it point to our endpoint */ endp->ci = bsc_mgcp_extract_ci((const char *) msg->l2h); + port = bsc_mgcp_extract_port((const char *) msg->l2h); + endp->bts_rtp = htons(port); + endp->bts_rtcp = htons(port + 1); output = bsc_mgcp_rewrite((char * ) msg->l2h, msgb_l2len(msg), bsc->nat->mgcp_cfg->source_addr, endp->rtp_port); if (!output) { @@ -254,6 +257,18 @@ int bsc_mgcp_extract_ci(const char *str) return ci; } +int bsc_mgcp_extract_port(const char *str) +{ + int port; + char *res = strstr(str, "m=audio "); + if (!res) + return 0; + + if (sscanf(res, "m=audio %d RTP/AVP %*d", &port) != 1) + return 0; + return port; +} + /* we need to replace some strings... */ struct msgb *bsc_mgcp_rewrite(char *input, int length, const char *ip, int port) { diff --git a/openbsc/tests/bsc-nat/bsc_nat_test.c b/openbsc/tests/bsc-nat/bsc_nat_test.c index def6bfec8..705372c8d 100644 --- a/openbsc/tests/bsc-nat/bsc_nat_test.c +++ b/openbsc/tests/bsc-nat/bsc_nat_test.c @@ -482,6 +482,19 @@ static void test_mgcp_parse(void) } } +static void test_mgcp_parse_port(void) +{ + int port; + + fprintf(stderr, "Test MGCP port parsing.\n"); + + port = bsc_mgcp_extract_port(mdcx_resp); + if (port != 4002) { + fprintf(stderr, "Could not parse port. Got: %d\n", port); + abort(); + } +} + int main(int argc, char **argv) { struct debug_target *stderr_target; @@ -497,6 +510,7 @@ int main(int argc, char **argv) test_mgcp_find(); test_mgcp_rewrite(); test_mgcp_parse(); + test_mgcp_parse_port(); return 0; }