aboutsummaryrefslogtreecommitdiffstats
path: root/openbsc
diff options
context:
space:
mode:
authorHolger Hans Peter Freyther <zecke@selfish.org>2010-08-05 06:55:58 +0800
committerHolger Hans Peter Freyther <zecke@selfish.org>2010-08-05 06:57:29 +0800
commite602cd69881bc222c0bedc61aa49cbb7294bf7d6 (patch)
treed1f44d815d3d856c39451fd48ff33a4228448ab3 /openbsc
parent1fc432984c22fcf78b66723af0712be08e8fabde (diff)
mgcp: Separate recv from net/bts and remove autodetection
This allows a more strict check on the source of RTP messages and we can more easily reject those. For the BTS without an ip address we will also update the ip address.
Diffstat (limited to 'openbsc')
-rw-r--r--openbsc/src/mgcp/mgcp_network.c105
1 files changed, 64 insertions, 41 deletions
diff --git a/openbsc/src/mgcp/mgcp_network.c b/openbsc/src/mgcp/mgcp_network.c
index 107d2fd56..729a89c95 100644
--- a/openbsc/src/mgcp/mgcp_network.c
+++ b/openbsc/src/mgcp/mgcp_network.c
@@ -211,13 +211,54 @@ static int recevice_from(struct mgcp_endpoint *endp, int fd, struct sockaddr_in
return rc;
}
-static int rtp_data_cb(struct bsc_fd *fd, unsigned int what)
+static int rtp_data_net(struct bsc_fd *fd, unsigned int what)
+{
+ char buf[4096];
+ struct sockaddr_in addr;
+ struct mgcp_endpoint *endp;
+ int rc, proto;
+
+ endp = (struct mgcp_endpoint *) fd->data;
+
+ rc = recevice_from(endp, fd->fd, &addr, buf, sizeof(buf));
+ if (rc <= 0)
+ return -1;
+
+ if (memcmp(&addr.sin_addr, &endp->net_end.addr, sizeof(addr.sin_addr)) != 0) {
+ LOGP(DMGCP, LOGL_ERROR,
+ "Data from wrong address %s on 0x%x\n",
+ inet_ntoa(addr.sin_addr), ENDPOINT_NUMBER(endp));
+ return -1;
+ }
+
+ if (endp->net_end.rtp_port != addr.sin_port &&
+ endp->net_end.rtcp_port != addr.sin_port) {
+ LOGP(DMGCP, LOGL_ERROR,
+ "Data from wrong source port %d on 0x%x\n",
+ ntohs(addr.sin_port), ENDPOINT_NUMBER(endp));
+ return -1;
+ }
+
+ /* throw away the dummy message */
+ if (rc == 1 && buf[0] == DUMMY_LOAD) {
+ LOGP(DMGCP, LOGL_NOTICE, "Filtered dummy from network on 0x%x\n",
+ ENDPOINT_NUMBER(endp));
+ return 0;
+ }
+
+ proto = fd == &endp->net_end.rtp ? PROTO_RTP : PROTO_RTCP;
+ endp->net_end.packets += 1;
+ return send_to(endp, DEST_BTS, proto == PROTO_RTP, &addr, &buf[0], rc);
+}
+
+
+static int rtp_data_bts(struct bsc_fd *fd, unsigned int what)
{
char buf[4096];
struct sockaddr_in addr;
struct mgcp_endpoint *endp;
struct mgcp_config *cfg;
- int rc, dest, proto;
+ int rc, proto;
endp = (struct mgcp_endpoint *) fd->data;
cfg = endp->cfg;
@@ -226,53 +267,35 @@ static int rtp_data_cb(struct bsc_fd *fd, unsigned int what)
if (rc <= 0)
return -1;
-
- /*
- * Figure out where to forward it to. This code assumes that we
- * have received the Connection Modify and know who is a legitimate
- * partner. According to the spec we could attempt to forward even
- * after the Create Connection but we will not as we are not really
- * able to tell if this is legitimate.
- */
- dest = memcmp(&addr.sin_addr, &endp->net_end.addr, sizeof(addr.sin_addr)) == 0 &&
- (endp->net_end.rtp_port == addr.sin_port || endp->net_end.rtcp_port == addr.sin_port)
- ? DEST_BTS : DEST_NETWORK;
- proto = (fd == &endp->net_end.rtp || fd == &endp->bts_end.rtp) ? PROTO_RTP : PROTO_RTCP;
+ proto = &endp->bts_end.rtp ? PROTO_RTP : PROTO_RTCP;
/* We have no idea who called us, maybe it is the BTS. */
- if (dest == DEST_NETWORK && endp->bts_end.rtp_port == 0) {
- /* it was the BTS... */
- if (!cfg->bts_ip
- || memcmp(&addr.sin_addr, &cfg->bts_in, sizeof(cfg->bts_in)) == 0
- || memcmp(&addr.sin_addr, &endp->bts_end.addr, sizeof(endp->bts_end.addr)) == 0) {
- if (proto == PROTO_RTP) {
- endp->bts_end.rtp_port = addr.sin_port;
- } else {
- endp->bts_end.rtcp_port = addr.sin_port;
- }
-
- endp->bts_end.addr = addr.sin_addr;
- LOGP(DMGCP, LOGL_NOTICE, "Found BTS for endpoint: 0x%x on port: %d/%d of %s\n",
- ENDPOINT_NUMBER(endp), ntohs(endp->bts_end.rtp_port), ntohs(endp->bts_end.rtcp_port),
- inet_ntoa(addr.sin_addr));
-
- }
+ /* it was the BTS... */
+ if (!cfg->bts_ip
+ || memcmp(&addr.sin_addr, &cfg->bts_in, sizeof(cfg->bts_in)) == 0
+ || memcmp(&addr.sin_addr, &endp->bts_end.addr, sizeof(endp->bts_end.addr)) == 0) {
+ if (proto == PROTO_RTP)
+ endp->bts_end.rtp_port = addr.sin_port;
+ else
+ endp->bts_end.rtcp_port = addr.sin_port;
+
+ endp->bts_end.addr = addr.sin_addr;
+ LOGP(DMGCP, LOGL_NOTICE, "Found BTS for endpoint: 0x%x on port: %d/%d of %s\n",
+ ENDPOINT_NUMBER(endp), ntohs(endp->bts_end.rtp_port), ntohs(endp->bts_end.rtcp_port),
+ inet_ntoa(addr.sin_addr));
}
/* throw away the dummy message */
if (rc == 1 && buf[0] == DUMMY_LOAD) {
- LOGP(DMGCP, LOGL_NOTICE, "Filtered dummy on 0x%x\n",
+ LOGP(DMGCP, LOGL_NOTICE, "Filtered dummy from bts on 0x%x\n",
ENDPOINT_NUMBER(endp));
return 0;
}
/* do this before the loop handling */
- if (dest == DEST_NETWORK)
- ++endp->bts_end.packets;
- else
- ++endp->net_end.packets;
+ endp->bts_end.packets += 1;
- return send_to(endp, dest, proto == PROTO_RTP, &addr, &buf[0], rc);
+ return send_to(endp, DEST_NETWORK, proto == PROTO_RTP, &addr, &buf[0], rc);
}
static int create_bind(const char *source_addr, struct bsc_fd *fd, int port)
@@ -355,19 +378,19 @@ cleanup0:
int mgcp_bind_bts_rtp_port(struct mgcp_endpoint *endp, int rtp_port)
{
endp->bts_end.local_port = rtp_port;
- endp->bts_end.rtp.cb = rtp_data_cb;
+ endp->bts_end.rtp.cb = rtp_data_bts;
endp->bts_end.rtp.data = endp;
endp->bts_end.rtcp.data = endp;
- endp->bts_end.rtcp.cb = rtp_data_cb;
+ endp->bts_end.rtcp.cb = rtp_data_bts;
return bind_rtp(endp->cfg, &endp->bts_end, ENDPOINT_NUMBER(endp));
}
int mgcp_bind_net_rtp_port(struct mgcp_endpoint *endp, int rtp_port)
{
endp->net_end.local_port = rtp_port;
- endp->net_end.rtp.cb = rtp_data_cb;
+ endp->net_end.rtp.cb = rtp_data_net;
endp->net_end.rtp.data = endp;
endp->net_end.rtcp.data = endp;
- endp->net_end.rtcp.cb = rtp_data_cb;
+ endp->net_end.rtcp.cb = rtp_data_net;
return bind_rtp(endp->cfg, &endp->net_end, ENDPOINT_NUMBER(endp));
}