trunk: parse E1 trunk number
The E1 trunk number is currently not parsed, whenever a trunk prefix is
detected that indicates an E1 trunk, then the entire request is
rejected.
Parse the trunk number and select the trunk accordingly
Related: OS#2547
Change-Id: Ifdaab953544151e73b58cc3e95d21afdb40765f4
diff --git a/include/osmocom/mgcp/mgcp_trunk.h b/include/osmocom/mgcp/mgcp_trunk.h
index c6a0997..82728fe 100644
--- a/include/osmocom/mgcp/mgcp_trunk.h
+++ b/include/osmocom/mgcp/mgcp_trunk.h
@@ -50,6 +50,7 @@
int mgcp_trunk_alloc_endpts(struct mgcp_trunk *tcfg);
struct mgcp_trunk *mgcp_trunk_by_num(const struct mgcp_config *cfg, int index);
struct mgcp_trunk *mgcp_trunk_by_name(const struct mgcp_config *cfg, const char *epname);
+int e1_trunk_nr_from_epname(const char *epname);
/* The virtual trunk is always created on trunk id 0 for historical reasons,
* use this define constant as ID when allocating a virtual trunk. Other
diff --git a/src/libosmo-mgcp/mgcp_trunk.c b/src/libosmo-mgcp/mgcp_trunk.c
index bd7bb2a..cc6637b 100644
--- a/src/libosmo-mgcp/mgcp_trunk.c
+++ b/src/libosmo-mgcp/mgcp_trunk.c
@@ -118,6 +118,27 @@
return NULL;
}
+/* Made public for unit-testing, do not use from outside this file */
+int e1_trunk_nr_from_epname(const char *epname)
+{
+ unsigned long int trunk_nr;
+ size_t prefix_len;
+ char *str_trunk_nr_end;
+
+ prefix_len = sizeof(MGCP_ENDPOINT_PREFIX_E1_TRUNK) - 1;
+ if (strncmp(epname, MGCP_ENDPOINT_PREFIX_E1_TRUNK, prefix_len) != 0)
+ return -EINVAL;
+
+ errno = 0;
+ trunk_nr = strtoul(epname + prefix_len, &str_trunk_nr_end, 10);
+ if (errno == ERANGE || trunk_nr > 64 || trunk_nr == 0
+ || epname + prefix_len == str_trunk_nr_end
+ || str_trunk_nr_end[0] != '/')
+ return -EINVAL;
+ else
+ return trunk_nr;
+}
+
/*! Find a trunk by the trunk prefix in the endpoint name.
* \param[in] epname endpoint name with trunk prefix to look up.
* \param[in] cfg that contains the trunks where the endpoint is located.
@@ -126,6 +147,7 @@
{
size_t prefix_len;
char epname_lc[MGCP_ENDPOINT_MAXLEN];
+ unsigned long int trunk_nr;
osmo_str_tolower_buf(epname_lc, sizeof(epname_lc), epname);
epname = epname_lc;
@@ -135,13 +157,12 @@
return mgcp_trunk_by_num(cfg, MGCP_VIRT_TRUNK_ID);
}
- /* E1 trunks are not implemented yet, so we deny any request for an
- * e1 trunk for now. */
prefix_len = sizeof(MGCP_ENDPOINT_PREFIX_E1_TRUNK) - 1;
if (strncmp(epname, MGCP_ENDPOINT_PREFIX_E1_TRUNK, prefix_len) == 0) {
- LOGP(DLMGCP, LOGL_ERROR,
- "endpoint name \"%s\" suggests an E1 trunk, but E1 trunks are not implemented in this version of osmo-mgw!\n", epname);
- return NULL;
+ trunk_nr = e1_trunk_nr_from_epname(epname);
+ if (trunk_nr < 0)
+ return NULL;
+ return mgcp_trunk_by_num(cfg, trunk_nr);
}
/* Earlier versions of osmo-mgw were accepting endpoint names
diff --git a/tests/mgcp/mgcp_test.c b/tests/mgcp/mgcp_test.c
index 56a17b1..b0647f4 100644
--- a/tests/mgcp/mgcp_test.c
+++ b/tests/mgcp/mgcp_test.c
@@ -2130,6 +2130,48 @@
talloc_free(conn);
}
+void test_e1_trunk_nr_from_epname()
+{
+ int trunk_nr;
+
+ /* Note: e1_trunk_nr_from_epname does not check the text
+ * after the E1 trunk number, after the delimiter
+ * character "/" arbitrary text may follow. */
+ trunk_nr = e1_trunk_nr_from_epname("ds/e1-1/s-1/su16-0");
+ OSMO_ASSERT(trunk_nr == 1);
+ trunk_nr = e1_trunk_nr_from_epname("ds/e1-2/s-2/su16-0");
+ OSMO_ASSERT(trunk_nr == 2);
+ trunk_nr = e1_trunk_nr_from_epname("ds/e1-3/s-23/su32-0");
+ OSMO_ASSERT(trunk_nr == 3);
+ trunk_nr = e1_trunk_nr_from_epname("ds/e1-3/xxxxxxx");
+ OSMO_ASSERT(trunk_nr == 3);
+ trunk_nr = e1_trunk_nr_from_epname("ds/e1-24/s-1/su16-0");
+ OSMO_ASSERT(trunk_nr == 24);
+ trunk_nr = e1_trunk_nr_from_epname("ds/e1-64/s-1/su16-0");
+ OSMO_ASSERT(trunk_nr == 64);
+
+ /* The following endpoint strings should fail, either the
+ * trunk number exceeds the valid range or the trunk prefix
+ * is wrong. Also when the delimiter character "/" at the
+ * end of the trunk is wrong the parsing should fail. */
+ trunk_nr = e1_trunk_nr_from_epname("ds/e1-0/s-1/su16-0");
+ OSMO_ASSERT(trunk_nr == -EINVAL);
+ trunk_nr = e1_trunk_nr_from_epname("ds/e1-65/s-1/su16-0");
+ OSMO_ASSERT(trunk_nr == -EINVAL);
+ trunk_nr = e1_trunk_nr_from_epname("ds/e1--1/s-1/su16-0");
+ OSMO_ASSERT(trunk_nr == -EINVAL);
+ trunk_nr = e1_trunk_nr_from_epname("xxxxxx4zyz");
+ OSMO_ASSERT(trunk_nr == -EINVAL);
+ trunk_nr = e1_trunk_nr_from_epname("ds/e1+2/s-1/su16-0");
+ OSMO_ASSERT(trunk_nr == -EINVAL);
+ trunk_nr = e1_trunk_nr_from_epname("ds/e2-24/s-1/su16-0");
+ OSMO_ASSERT(trunk_nr == -EINVAL);
+ trunk_nr = e1_trunk_nr_from_epname("ds/e1-24s-1/su16-0");
+ OSMO_ASSERT(trunk_nr == -EINVAL);
+
+ return;
+}
+
int main(int argc, char **argv)
{
void *ctx = talloc_named_const(NULL, 0, "mgcp_test");
@@ -2155,6 +2197,7 @@
test_check_local_cx_options(ctx);
test_mgcp_codec_pt_translate();
test_conn_id_matching();
+ test_e1_trunk_nr_from_epname();
OSMO_ASSERT(talloc_total_size(msgb_ctx) == 0);
OSMO_ASSERT(talloc_total_blocks(msgb_ctx) == 1);