Hi Jolly, all,

I spent some time figuring out why LCR and OpenBSC wouldn't want to work with
each other. The reason was the addition of an element to the MNCC structure. I
propose to send a hello packet down the MNCC socket and leave it to the client
to decide if the version is acceptable.

I will need to move the mncc header to libosmocore as osmocomBB is currently
using a copy of the OpenBSC header.

comments
        holger
>From 249543405cc5e4532a3663ed1058349ef4b4989c Mon Sep 17 00:00:00 2001
From: Holger Hans Peter Freyther <[email protected]>
Date: Fri, 21 Oct 2011 14:12:46 +0200
Subject: [PATCH] mncc: Introduce a hello packet that is sent to the client.

Send a hello packet down to the client with the version number
of the MNCC interface. The hello structure might be extended to
include the endianes, size of each structure, etc.
---
 openbsc/include/openbsc/mncc.h |    8 ++++++++
 openbsc/src/libmsc/mncc_sock.c |   24 ++++++++++++++++++++++++
 2 files changed, 32 insertions(+), 0 deletions(-)

diff --git a/openbsc/include/openbsc/mncc.h b/openbsc/include/openbsc/mncc.h
index 8c59fe2..9153d65 100644
--- a/openbsc/include/openbsc/mncc.h
+++ b/openbsc/include/openbsc/mncc.h
@@ -96,6 +96,8 @@ struct gsm_call {
 #define GSM_TCHF_FRAME		0x0300
 #define GSM_TCHF_FRAME_EFR	0x0301
 
+#define MNCC_SOCKET_HELLO	0x0400
+
 #define GSM_MAX_FACILITY	128
 #define GSM_MAX_SSVERSION	128
 #define GSM_MAX_USERUSER	128
@@ -158,6 +160,12 @@ struct gsm_data_frame {
 	unsigned char	data[0];
 };
 
+#define MNCC_SOCK_VERSION	1
+struct gsm_mncc_hello {
+	uint32_t	msg_type;
+	uint32_t	version;
+};
+
 char *get_mncc_name(int value);
 void mncc_set_cause(struct gsm_mncc *data, int loc, int val);
 void cc_tx_to_mncc(struct gsm_network *net, struct msgb *msg);
diff --git a/openbsc/src/libmsc/mncc_sock.c b/openbsc/src/libmsc/mncc_sock.c
index d8caf07..b9ebdb0 100644
--- a/openbsc/src/libmsc/mncc_sock.c
+++ b/openbsc/src/libmsc/mncc_sock.c
@@ -213,6 +213,29 @@ static int mncc_sock_cb(struct osmo_fd *bfd, unsigned int flags)
 	return rc;
 }
 
+/**
+ * Send a version indication to the remote.
+ */
+static void queue_hello(struct mncc_sock_state *mncc)
+{
+	struct gsm_mncc_hello *hello;
+	struct msgb *msg;
+
+	msg = msgb_alloc(512, "mncc hello");
+	if (!msg) {
+		LOGP(DMNCC, LOGL_ERROR, "Failed to allocate hello.\n");
+		mncc_sock_close(mncc);
+		return;
+	}
+
+	hello = (struct gsm_mncc_hello *) msgb_put(msg, sizeof(*hello));
+	hello->msg_type = MNCC_SOCKET_HELLO;
+	hello->version = MNCC_SOCK_VERSION;
+
+	msgb_enqueue(&mncc->net->upqueue, msg);
+	mncc->conn_bfd.when |= BSC_FD_WRITE;
+}
+
 /* accept a new connection */
 static int mncc_sock_accept(struct osmo_fd *bfd, unsigned int flags)
 {
@@ -253,6 +276,7 @@ static int mncc_sock_accept(struct osmo_fd *bfd, unsigned int flags)
 	LOGP(DMNCC, LOGL_NOTICE, "MNCC Socket has connection with external "
 		"call control application\n");
 
+	queue_hello(state);
 	return 0;
 }
 
-- 
1.7.5.4

>From 7a20ab9e551ee3a4fa9fa968a3eb54a2874d6d39 Mon Sep 17 00:00:00 2001
From: Holger Hans Peter Freyther <[email protected]>
Date: Fri, 21 Oct 2011 14:11:04 +0200
Subject: [PATCH] gsm: Verify the MNCC_VERSION of the BSC/MS and close the
 socket on mismatch

The BSC/MS will send a Hello packet that includes the version number,
make LCR verify this version number and close the socket in case it
does not match a supported version.
---
 gsm.cpp |   12 ++++++++++++
 mncc.h  |    7 +++++++
 2 files changed, 19 insertions(+), 0 deletions(-)

diff --git a/gsm.cpp b/gsm.cpp
index e6806c3..227d618 100644
--- a/gsm.cpp
+++ b/gsm.cpp
@@ -1042,6 +1042,7 @@ static int mncc_fd_read(struct lcr_fd *lfd, void *inst, int idx)
 	int rc;
 	static char buf[sizeof(struct gsm_mncc)+1024];
 	struct gsm_mncc *mncc_prim = (struct gsm_mncc *) buf;
+	struct gsm_mncc_hello *hello = (struct gsm_mncc_hello *) buf;
 
 	memset(buf, 0, sizeof(buf));
 	rc = recv(lfd->fd, buf, sizeof(buf), 0);
@@ -1050,6 +1051,17 @@ static int mncc_fd_read(struct lcr_fd *lfd, void *inst, int idx)
 	if (rc < 0)
 		return rc;
 
+	/* TODO: size check? */
+	switch (mncc_prim->msg_type) {
+	case MNCC_SOCKET_HELLO:
+		if (hello->version != MNCC_SOCK_VERSION) {
+			PERROR("MNCC version different. BSC version is %u\n", hello->version);
+			mncc_fd_close(lcr_gsm, lfd);
+			return 0;
+		}
+		break;
+	}
+
 	/* Hand the MNCC message into LCR */
 	switch (lcr_gsm->type) {
 #ifdef WITH_GSM_BS
diff --git a/mncc.h b/mncc.h
index e5f8216..fac7145 100644
--- a/mncc.h
+++ b/mncc.h
@@ -56,6 +56,8 @@
 #define GSM_TCHF_FRAME		0x0300
 #define GSM_TCHF_FRAME_EFR	0x0301
 
+#define MNCC_SOCKET_HELLO	0x0400
+
 #define GSM_MAX_FACILITY	128
 #define GSM_MAX_SSVERSION	128
 #define GSM_MAX_USERUSER	128
@@ -185,3 +187,8 @@ struct gsm_data_frame {
 	unsigned char	data[0];
 };
 
+#define MNCC_SOCK_VERSION	1
+struct gsm_mncc_hello {
+	u_int32_t	msg_type;
+	u_int32_t	version;
+};
-- 
1.7.5.4

Reply via email to