diff mbox

[4/6] gprs: Add MCC/MNC patch support for LLC/GMM messages

Message ID 1404386897-27883-4-git-send-email-jerlbeck@sysmocom.de
State Superseded
Headers show

Commit Message

Jacob Erlbeck July 3, 2014, 11:28 a.m. UTC
This patch extends the BSSGP patch code to also patch LLC information
elements along with MCC/MNC patching support for the following messages:

- Attach Request
- Attach Accept
- Routing Area Update Request
- Routing Area Update Accept
- P-TMSI reallocation command

Note that encrypted packets will not be patched.

Ticket: OW#1185
Sponsored-by: On-Waves ehf
---
 openbsc/include/openbsc/gb_proxy.h    |  10 ++
 openbsc/src/gprs/gb_proxy.c           | 281 +++++++++++++++++++++++++++++++++-
 openbsc/src/gprs/gb_proxy_vty.c       |  34 ++++
 openbsc/tests/gbproxy/gbproxy_test.ok |  24 +--
 4 files changed, 336 insertions(+), 13 deletions(-)

Comments

Holger Freyther July 7, 2014, 6:28 p.m. UTC | #1
On Thu, Jul 03, 2014 at 01:28:15PM +0200, Jacob Erlbeck wrote:

> +	/* Skip Attach result */
> +	/* Skip Force to standby */
> +	/* Skip Periodic RA update timer */
> +	/* Skip Radio priority for SMS */
> +	/* Skip Spare half octet */
> +	data_len -= 3;
> +	data += 3;

Which are the other half octets here?

> +	/* Skip Update type */
> +	/* Skip GPRS ciphering key sequence number */
> +	data_len -= 1;
> +	data += 1;

I don't have a copy of the specification open right now. Could you
please indicate how the number of skips relate to data_len/data
adjustments here?

> +	if (data[0] != 5)
> +		/* invalid */
> +		return 0;;

Extra ';' :)

> +			/* LLC patch (GMM) has been requested explicitely */

								^-- typo

> +		/* Fix LLC IE len */
> +		if (llc[-2] == BSSGP_IE_LLC_PDU && llc[-1] & 0x80) {
> +			/* most probably a one byte length */

You mentioned this to me already. What API documentation do you need? Keep
track inside the tlv_parsed structure of _where_ the tag started?

> +	patch_mode = gbcfg.patch_mode;
> +	if (patch_mode == GBPROX_PATCH_DEFAULT)
> +		patch_mode = GBPROX_PATCH_LLC;

I am thinking of the "gbcfg.patch_mode > GBPROX_PATCH_LLC_ATTACH_REQ". So
we are lucky as default is < GBPROX_PATCH_LLC_ATTACH_REQ right now. Wouldn't
it be better to not access gbcfg.patch_mode directly and do the "default"
handling inside this method?
diff mbox

Patch

diff --git a/openbsc/include/openbsc/gb_proxy.h b/openbsc/include/openbsc/gb_proxy.h
index 220636e..7bac832 100644
--- a/openbsc/include/openbsc/gb_proxy.h
+++ b/openbsc/include/openbsc/gb_proxy.h
@@ -7,6 +7,15 @@ 
 #include <osmocom/gprs/gprs_ns.h>
 #include <osmocom/vty/command.h>
 
+enum gbproxy_patch_mode {
+	GBPROX_PATCH_DEFAULT,
+	GBPROX_PATCH_BSSGP,		/*!< BSGGP messages only */
+	GBPROX_PATCH_LLC_ATTACH_REQ,	/*!< BSSGP and Attach Request */
+	GBPROX_PATCH_LLC_ATTACH,	/*!< BSSGP and Attach Request/Response */
+	GBPROX_PATCH_LLC_GMM,		/*!< BSSGP and all GMM msgs */
+	GBPROX_PATCH_LLC,		/*!< BSSGP and all supported LLC msgs */
+};
+
 struct gbproxy_config {
 	/* parsed from config file */
 	uint16_t nsip_sgsn_nsei;
@@ -17,6 +26,7 @@  struct gbproxy_config {
 	/* force mcc/mnc */
 	int core_mnc;
 	int core_mcc;
+	enum gbproxy_patch_mode patch_mode;
 };
 
 extern struct gbproxy_config gbcfg;
diff --git a/openbsc/src/gprs/gb_proxy.c b/openbsc/src/gprs/gb_proxy.c
index 61059bb..5340c4d 100644
--- a/openbsc/src/gprs/gb_proxy.c
+++ b/openbsc/src/gprs/gb_proxy.c
@@ -61,6 +61,7 @@  enum gbprox_global_ctr {
 	GBPROX_GLOB_CTR_OTHER_ERR,
 	GBPROX_GLOB_CTR_RAID_PATCHED_BSS,
 	GBPROX_GLOB_CTR_RAID_PATCHED_SGSN,
+	GBPROX_GLOB_CTR_PATCH_CRYPT_ERR,
 	GBPROX_GLOB_CTR_PATCH_ERR,
 };
 
@@ -78,7 +79,8 @@  static const struct rate_ctr_desc global_ctr_description[] = {
 	{ "error",          "Other error                     " },
 	{ "raid-mod.bss",   "RAID patched              (BSS )" },
 	{ "raid-mod.sgsn",  "RAID patched              (SGSN)" },
-	{ "mod-err",        "Patching error                  " },
+	{ "mod-crypt-err",  "Patch error: encrypted          " },
+	{ "mod-err",        "Patch error: other              " },
 };
 
 static const struct rate_ctr_group_desc global_ctrg_desc = {
@@ -346,6 +348,270 @@  static void gbprox_patch_raid(uint8_t *raid_enc, struct gbprox_patch_state *stat
 	}
 }
 
+static int gbprox_patch_gmm_attach_req(struct msgb *msg,
+				       uint8_t *data, size_t data_len,
+				       struct gbprox_patch_state *state,
+				       int to_bss, int *len_change)
+{
+	/* Check minimum length, always includes the RAI */
+	if (data_len < 23)
+		return 0;
+
+	/* Skip MS network capability */
+	if (data[0] < 1 || data[0] > 2)
+		/* invalid */
+		return 0;
+	data_len -= data[0] + 1;
+	data += data[0] + 1;
+
+	/* Skip Attach type */
+	/* Skip Ciphering key sequence number */
+	/* Skip DRX parameter */
+	data_len -= 3;
+	data += 3;
+
+	/* Skip Mobile identity */
+	if (data[0] < 5 || data[0] > 8)
+		/* invalid */
+		return 0;
+	data_len -= data[0] + 1;
+	data += data[0] + 1;
+
+	gbprox_patch_raid(data, state, to_bss, "LLC/ATTACH_REQ");
+
+	return 1;
+}
+
+static int gbprox_patch_gmm_attach_ack(struct msgb *msg,
+				       uint8_t *data, size_t data_len,
+				       struct gbprox_patch_state *state,
+				       int to_bss, int *len_change)
+{
+	/* Check minimum length, always includes the RAI */
+	if (data_len < 9)
+		return 0;;
+
+	/* Skip Attach result */
+	/* Skip Force to standby */
+	/* Skip Periodic RA update timer */
+	/* Skip Radio priority for SMS */
+	/* Skip Spare half octet */
+	data_len -= 3;
+	data += 3;
+
+	gbprox_patch_raid(data, state, to_bss, "LLC/ATTACH_ACK");
+
+	return 1;
+}
+
+static int gbprox_patch_gmm_ra_upd_req(struct msgb *msg,
+				       uint8_t *data, size_t data_len,
+				       struct gbprox_patch_state *state,
+				       int to_bss, int *len_change)
+{
+	/* Check minimum length, always includes the RAI */
+	if (data_len < 13)
+		return 0;;
+
+	/* Skip Update type */
+	/* Skip GPRS ciphering key sequence number */
+	data_len -= 1;
+	data += 1;
+
+	gbprox_patch_raid(data, state, to_bss, "LLC/RA_UPD_REQ");
+
+	return 1;
+}
+
+static int gbprox_patch_gmm_ra_upd_ack(struct msgb *msg,
+				       uint8_t *data, size_t data_len,
+				       struct gbprox_patch_state *state,
+				       int to_bss, int *len_change)
+{
+	/* Check minimum length, always includes the RAI */
+	if (data_len < 8)
+		return 0;;
+
+	/* Skip Force to standby */
+	/* Skip Update result */
+	/* Skip Periodic RA update timer */
+	data_len -= 2;
+	data += 2;
+
+	gbprox_patch_raid(data, state, to_bss, "LLC/RA_UPD_ACK");
+
+	return 1;
+}
+
+static int gbprox_patch_gmm_ptmsi_reall_cmd(struct msgb *msg,
+					    uint8_t *data, size_t data_len,
+					    struct gbprox_patch_state *state,
+					    int to_bss, int *len_change)
+{
+	/* Check minimum length, always includes the RAI */
+	if (data_len < 12)
+		return 0;;
+
+	/* Skip Allocated P-TMSI */
+	if (data[0] != 5)
+		/* invalid */
+		return 0;;
+	data_len -= 6;
+	data += 6;
+
+	gbprox_patch_raid(data, state, to_bss, "LLC/PTMSI_REALL_CMD");
+
+	return 1;
+}
+
+static int gbprox_patch_dtap(struct msgb *msg, uint8_t *data, size_t data_len,
+			     struct gbprox_patch_state *state,
+			     enum gbproxy_patch_mode patch_mode, int to_bss,
+			     int *len_change)
+{
+	struct gsm48_hdr *g48h;
+
+	*len_change = 0;
+
+	if (data_len < 2)
+		return 0;
+
+	g48h = (struct gsm48_hdr *)data;
+
+	data += sizeof(struct gsm48_hdr);
+	data_len -= sizeof(struct gsm48_hdr);
+
+	if ((g48h->proto_discr & 0x0f) != GSM48_PDISC_MM_GPRS &&
+	    (g48h->proto_discr & 0x0f) != GSM48_PDISC_SM_GPRS)
+		return 0;
+
+	switch (g48h->msg_type) {
+	case GSM48_MT_GMM_ATTACH_REQ:
+		return gbprox_patch_gmm_attach_req(msg, data, data_len,
+						   state, to_bss, len_change);
+
+	case GSM48_MT_GMM_ATTACH_ACK:
+		if (patch_mode < GBPROX_PATCH_LLC_ATTACH)
+			break;
+		return gbprox_patch_gmm_attach_ack(msg, data, data_len,
+						   state, to_bss, len_change);
+
+	case GSM48_MT_GMM_RA_UPD_REQ:
+		if (patch_mode < GBPROX_PATCH_LLC_GMM)
+			break;
+		return gbprox_patch_gmm_ra_upd_req(msg, data, data_len,
+						   state, to_bss, len_change);
+
+	case GSM48_MT_GMM_RA_UPD_ACK:
+		if (patch_mode < GBPROX_PATCH_LLC_GMM)
+			break;
+		return gbprox_patch_gmm_ra_upd_ack(msg, data, data_len,
+						   state, to_bss, len_change);
+
+	case GSM48_MT_GMM_PTMSI_REALL_CMD:
+		if (patch_mode < GBPROX_PATCH_LLC_GMM)
+			break;
+		return gbprox_patch_gmm_ptmsi_reall_cmd(msg, data, data_len,
+							state, to_bss, len_change);
+
+	default:
+		break;
+	};
+
+	return 0;
+}
+
+static void gbprox_patch_llc(struct msgb *msg, uint8_t *llc, size_t llc_len,
+			     struct gbprox_patch_state *state,
+			     enum gbproxy_patch_mode patch_mode, int to_bss)
+{
+	struct gprs_llc_hdr_parsed ghp = {0};
+	int rc;
+	uint8_t *data;
+	size_t data_len;
+	int fcs;
+	int len_change = 0;
+	const char *err_info = NULL;
+	int err_ctr = -1;
+
+	/* parse LLC */
+	rc = gprs_llc_hdr_parse(&ghp, llc, llc_len);
+	gprs_llc_hdr_dump(&ghp);
+	if (rc != 0) {
+		LOGP(DLLC, LOGL_NOTICE, "Error during LLC header parsing\n");
+		return;
+	}
+
+	fcs = gprs_llc_fcs(llc, ghp.crc_length);
+	LOGP(DLLC, LOGL_DEBUG, "Got LLC message, CRC: %06x (computed %06x)\n",
+	     ghp.fcs, fcs);
+
+	if (!ghp.data)
+		return;
+
+	if (ghp.sapi != GPRS_SAPI_GMM)
+		return;
+
+	if (ghp.cmd != GPRS_LLC_UI)
+		return;
+
+	if (ghp.is_encrypted) {
+		if (gbcfg.patch_mode > GBPROX_PATCH_LLC_ATTACH_REQ) {
+			/* LLC patch (GMM) has been requested explicitely */
+			err_info = "GMM message is encrypted";
+			err_ctr = GBPROX_GLOB_CTR_PATCH_CRYPT_ERR;
+			goto patch_error;
+		}
+
+		return;
+	}
+
+	/* fix DTAP GMM/GSM */
+	data = ghp.data;
+	data_len = ghp.data_len;
+
+	rc = gbprox_patch_dtap(msg, data, data_len, state, patch_mode, to_bss,
+			       &len_change);
+
+	if (rc > 0) {
+		llc_len += len_change;
+		ghp.crc_length += len_change;
+
+		/* Fix LLC IE len */
+		if (llc[-2] == BSSGP_IE_LLC_PDU && llc[-1] & 0x80) {
+			/* most probably a one byte length */
+			if (llc_len > 127) {
+				err_info = "Cannot increase size";
+				err_ctr = GBPROX_GLOB_CTR_PATCH_ERR;
+				goto patch_error;
+			}
+			llc[-1] = llc_len | 0x80;
+		} else {
+			llc[-2] = (llc_len >> 8) & 0x7f;
+			llc[-1] = llc_len & 0xff;
+		}
+
+		/* Fix FCS */
+		fcs = gprs_llc_fcs(llc, ghp.crc_length);
+		LOGP(DLLC, LOGL_DEBUG, "Updated LLC message, CRC: %06x -> %06x\n",
+		     ghp.fcs, fcs);
+
+		llc[llc_len - 3] = fcs & 0xff;
+		llc[llc_len - 2] = (fcs >> 8) & 0xff;
+		llc[llc_len - 1] = (fcs >> 16) & 0xff;
+	}
+
+	return;
+
+patch_error:
+	OSMO_ASSERT(err_ctr >= 0);
+	rate_ctr_inc(&get_global_ctrg()->ctr[err_ctr]);
+	LOGP(DGPRS, LOGL_ERROR,
+	     "Failed to patch BSSGP/GMM message as requested: %s.\n", err_info);
+
+	return;
+}
+
 /* patch BSSGP message to use core_mcc/mnc on the SGSN side */
 static void gbprox_patch_bssgp_message(struct msgb *msg, int to_bss)
 {
@@ -356,6 +622,7 @@  static void gbprox_patch_bssgp_message(struct msgb *msg, int to_bss)
 	struct gbprox_patch_state *state = &gbprox_patch_state;
 	uint8_t *data;
 	size_t data_len;
+	enum gbproxy_patch_mode patch_mode;
 
 	if (!gbcfg.core_mcc && !gbcfg.core_mnc)
 		return;
@@ -363,6 +630,9 @@  static void gbprox_patch_bssgp_message(struct msgb *msg, int to_bss)
 	bgph = (struct bssgp_normal_hdr *) msgb_bssgph(msg);
 	budh = (struct bssgp_ud_hdr *) msgb_bssgph(msg);
 	pdu_type = bgph->pdu_type;
+	patch_mode = gbcfg.patch_mode;
+	if (patch_mode == GBPROX_PATCH_DEFAULT)
+		patch_mode = GBPROX_PATCH_LLC;
 
 	if (to_bss && !state->local_mcc && !state->local_mnc)
 		return;
@@ -386,6 +656,15 @@  static void gbprox_patch_bssgp_message(struct msgb *msg, int to_bss)
 	if (TLVP_PRESENT(&tp, BSSGP_IE_CELL_ID))
 		gbprox_patch_raid((uint8_t *)TLVP_VAL(&tp, BSSGP_IE_CELL_ID),
 				  state, to_bss, "CELL_ID");
+
+	if (TLVP_PRESENT(&tp, BSSGP_IE_LLC_PDU) &&
+	    patch_mode >= GBPROX_PATCH_LLC_ATTACH_REQ) {
+		uint8_t *llc = (uint8_t *)TLVP_VAL(&tp, BSSGP_IE_LLC_PDU);
+		size_t llc_len = TLVP_LEN(&tp, BSSGP_IE_LLC_PDU);
+		gbprox_patch_llc(msg, llc, llc_len, state, patch_mode, to_bss);
+		/* Note that the tp struct might contain invalid pointers here
+		 * if the LLC field has changed its size */
+	}
 }
 
 /* feed a message down the NS-VC associated with the specified peer */
diff --git a/openbsc/src/gprs/gb_proxy_vty.c b/openbsc/src/gprs/gb_proxy_vty.c
index acd8051..06f8082 100644
--- a/openbsc/src/gprs/gb_proxy_vty.c
+++ b/openbsc/src/gprs/gb_proxy_vty.c
@@ -44,6 +44,16 @@  static struct cmd_node gbproxy_node = {
 	1,
 };
 
+static const struct value_string patch_modes[] = {
+	{GBPROX_PATCH_DEFAULT, "default"},
+	{GBPROX_PATCH_BSSGP, "bssgp"},
+	{GBPROX_PATCH_LLC_ATTACH_REQ, "llc-attach-req"},
+	{GBPROX_PATCH_LLC_ATTACH, "llc-attach"},
+	{GBPROX_PATCH_LLC_GMM, "llc-gmm"},
+	{GBPROX_PATCH_LLC, "llc"},
+	{0, NULL}
+};
+
 static int config_write_gbproxy(struct vty *vty)
 {
 	vty_out(vty, "gbproxy%s", VTY_NEWLINE);
@@ -58,6 +68,11 @@  static int config_write_gbproxy(struct vty *vty)
 		vty_out(vty, " core-mobile-network-code %d%s",
 			g_cfg->core_mnc, VTY_NEWLINE);
 
+	if (g_cfg->patch_mode != GBPROX_PATCH_DEFAULT)
+		vty_out(vty, " patch-mode %s%s",
+			get_value_string(patch_modes, g_cfg->patch_mode),
+			VTY_NEWLINE);
+
 	return CMD_SUCCESS;
 }
 
@@ -123,6 +138,24 @@  DEFUN(cfg_gbproxy_no_core_mcc,
 	return CMD_SUCCESS;
 }
 
+DEFUN(cfg_gbproxy_patch_mode,
+      cfg_gbproxy_patch_mode_cmd,
+      "patch-mode (default|bssgp|llc-attach-req|llc-attach|llc)",
+      "Set patch mode\n"
+      "Use build-in default (at least llc-attach-req)\n"
+      "Only patch BSSGP headers\n"
+      "Patch BSSGP headers and LLC Attach Request messages\n"
+      "Patch BSSGP headers and LLC Attach Request/Accept messages\n"
+      "Patch BSSGP headers and all supported GMM LLC messages\n"
+      )
+{
+	int val = get_string_value(patch_modes, argv[0]);
+	OSMO_ASSERT(val >= 0);
+	g_cfg->patch_mode = val;
+	return CMD_SUCCESS;
+}
+
+
 
 int gbproxy_vty_init(void)
 {
@@ -139,6 +172,7 @@  int gbproxy_vty_init(void)
 	install_element(GBPROXY_NODE, &cfg_gbproxy_core_mnc_cmd);
 	install_element(GBPROXY_NODE, &cfg_gbproxy_no_core_mcc_cmd);
 	install_element(GBPROXY_NODE, &cfg_gbproxy_no_core_mnc_cmd);
+	install_element(GBPROXY_NODE, &cfg_gbproxy_patch_mode_cmd);
 
 	return 0;
 }
diff --git a/openbsc/tests/gbproxy/gbproxy_test.ok b/openbsc/tests/gbproxy/gbproxy_test.ok
index f8bd1e7..d3de445 100644
--- a/openbsc/tests/gbproxy/gbproxy_test.ok
+++ b/openbsc/tests/gbproxy/gbproxy_test.ok
@@ -1677,10 +1677,10 @@  CALLBACK, event 0, msg length 75, bvci 0x1002
 01 bb c5 46 79 00 00 04 08 88 11 22 33 40 50 60 75 30 00 80 0e 00 34 01 c0 01 08 01 02 f5 e0 21 08 02 05 f4 fb c5 46 79 11 22 33 40 50 60 19 18 b3 43 2b 25 96 62 00 60 80 9a c2 c6 62 00 60 80 ba c8 c6 62 00 60 80 00 16 6d 01 
 
 NS UNITDATA MESSAGE to SGSN, BVCI 0x1002, msg length 75
-01 bb c5 46 79 00 00 04 08 88 21 63 54 40 50 60 75 30 00 80 0e 00 34 01 c0 01 08 01 02 f5 e0 21 08 02 05 f4 fb c5 46 79 11 22 33 40 50 60 19 18 b3 43 2b 25 96 62 00 60 80 9a c2 c6 62 00 60 80 ba c8 c6 62 00 60 80 00 16 6d 01 
+01 bb c5 46 79 00 00 04 08 88 21 63 54 40 50 60 75 30 00 80 0e 00 34 01 c0 01 08 01 02 f5 e0 21 08 02 05 f4 fb c5 46 79 21 63 54 40 50 60 19 18 b3 43 2b 25 96 62 00 60 80 9a c2 c6 62 00 60 80 ba c8 c6 62 00 60 80 00 8e cd 32 
 
 MESSAGE to SGSN at 0x05060708:32000, msg length 79
-00 00 10 02 01 bb c5 46 79 00 00 04 08 88 21 63 54 40 50 60 75 30 00 80 0e 00 34 01 c0 01 08 01 02 f5 e0 21 08 02 05 f4 fb c5 46 79 11 22 33 40 50 60 19 18 b3 43 2b 25 96 62 00 60 80 9a c2 c6 62 00 60 80 ba c8 c6 62 00 60 80 00 16 6d 01 
+00 00 10 02 01 bb c5 46 79 00 00 04 08 88 21 63 54 40 50 60 75 30 00 80 0e 00 34 01 c0 01 08 01 02 f5 e0 21 08 02 05 f4 fb c5 46 79 21 63 54 40 50 60 19 18 b3 43 2b 25 96 62 00 60 80 9a c2 c6 62 00 60 80 ba c8 c6 62 00 60 80 00 8e cd 32 
 
 result (UNITDATA) = 79
 
@@ -1691,10 +1691,10 @@  CALLBACK, event 0, msg length 88, bvci 0x1002
 00 bb c5 46 79 00 50 20 16 82 02 58 13 99 18 b3 43 2b 25 96 62 00 60 80 9a c2 c6 62 00 60 80 ba c8 c6 62 00 60 80 00 0a 82 08 02 0d 88 11 12 13 14 15 16 17 18 00 81 00 0e 9e 41 c0 05 08 02 01 49 04 21 63 54 40 50 60 19 cd d7 08 17 16 18 05 f4 fb c5 47 22 42 67 9a 
 
 NS UNITDATA MESSAGE to BSS, BVCI 0x1002, msg length 88
-00 bb c5 46 79 00 50 20 16 82 02 58 13 99 18 b3 43 2b 25 96 62 00 60 80 9a c2 c6 62 00 60 80 ba c8 c6 62 00 60 80 00 0a 82 08 02 0d 88 11 12 13 14 15 16 17 18 00 81 00 0e 9e 41 c0 05 08 02 01 49 04 21 63 54 40 50 60 19 cd d7 08 17 16 18 05 f4 fb c5 47 22 42 67 9a 
+00 bb c5 46 79 00 50 20 16 82 02 58 13 99 18 b3 43 2b 25 96 62 00 60 80 9a c2 c6 62 00 60 80 ba c8 c6 62 00 60 80 00 0a 82 08 02 0d 88 11 12 13 14 15 16 17 18 00 81 00 0e 9e 41 c0 05 08 02 01 49 04 11 22 33 40 50 60 19 cd d7 08 17 16 18 05 f4 fb c5 47 22 af 3d ab 
 
 MESSAGE to BSS at 0x01020304:1111, msg length 92
-00 00 10 02 00 bb c5 46 79 00 50 20 16 82 02 58 13 99 18 b3 43 2b 25 96 62 00 60 80 9a c2 c6 62 00 60 80 ba c8 c6 62 00 60 80 00 0a 82 08 02 0d 88 11 12 13 14 15 16 17 18 00 81 00 0e 9e 41 c0 05 08 02 01 49 04 21 63 54 40 50 60 19 cd d7 08 17 16 18 05 f4 fb c5 47 22 42 67 9a 
+00 00 10 02 00 bb c5 46 79 00 50 20 16 82 02 58 13 99 18 b3 43 2b 25 96 62 00 60 80 9a c2 c6 62 00 60 80 ba c8 c6 62 00 60 80 00 0a 82 08 02 0d 88 11 12 13 14 15 16 17 18 00 81 00 0e 9e 41 c0 05 08 02 01 49 04 11 22 33 40 50 60 19 cd d7 08 17 16 18 05 f4 fb c5 47 22 af 3d ab 
 
 result (UNITDATA) = 92
 
@@ -1705,10 +1705,10 @@  CALLBACK, event 0, msg length 85, bvci 0x1002
 01 af e2 80 6e 00 00 04 08 88 11 22 33 40 50 60 70 80 00 80 0e 00 3e 01 c0 15 08 08 10 11 22 33 40 50 60 1d 19 13 42 33 57 2b f7 c8 48 02 13 48 50 c8 48 02 14 48 50 c8 48 02 17 49 10 c8 48 02 00 19 8b b2 92 17 16 27 07 04 31 02 e5 e0 32 02 20 00 96 3e 97 
 
 NS UNITDATA MESSAGE to SGSN, BVCI 0x1002, msg length 85
-01 af e2 80 6e 00 00 04 08 88 21 63 54 40 50 60 70 80 00 80 0e 00 3e 01 c0 15 08 08 10 11 22 33 40 50 60 1d 19 13 42 33 57 2b f7 c8 48 02 13 48 50 c8 48 02 14 48 50 c8 48 02 17 49 10 c8 48 02 00 19 8b b2 92 17 16 27 07 04 31 02 e5 e0 32 02 20 00 96 3e 97 
+01 af e2 80 6e 00 00 04 08 88 21 63 54 40 50 60 70 80 00 80 0e 00 3e 01 c0 15 08 08 10 21 63 54 40 50 60 1d 19 13 42 33 57 2b f7 c8 48 02 13 48 50 c8 48 02 14 48 50 c8 48 02 17 49 10 c8 48 02 00 19 8b b2 92 17 16 27 07 04 31 02 e5 e0 32 02 20 00 1d f0 41 
 
 MESSAGE to SGSN at 0x05060708:32000, msg length 89
-00 00 10 02 01 af e2 80 6e 00 00 04 08 88 21 63 54 40 50 60 70 80 00 80 0e 00 3e 01 c0 15 08 08 10 11 22 33 40 50 60 1d 19 13 42 33 57 2b f7 c8 48 02 13 48 50 c8 48 02 14 48 50 c8 48 02 17 49 10 c8 48 02 00 19 8b b2 92 17 16 27 07 04 31 02 e5 e0 32 02 20 00 96 3e 97 
+00 00 10 02 01 af e2 80 6e 00 00 04 08 88 21 63 54 40 50 60 70 80 00 80 0e 00 3e 01 c0 15 08 08 10 21 63 54 40 50 60 1d 19 13 42 33 57 2b f7 c8 48 02 13 48 50 c8 48 02 14 48 50 c8 48 02 17 49 10 c8 48 02 00 19 8b b2 92 17 16 27 07 04 31 02 e5 e0 32 02 20 00 1d f0 41 
 
 result (UNITDATA) = 89
 
@@ -1719,10 +1719,10 @@  CALLBACK, event 0, msg length 91, bvci 0x1002
 00 af e2 80 6e 00 50 20 16 82 02 58 13 9d 19 13 42 33 57 2b f7 c8 48 02 13 48 50 c8 48 02 14 48 50 c8 48 02 17 49 10 c8 48 02 00 0a 82 07 04 0d 88 11 12 13 14 15 16 17 18 00 81 00 0e 9d 41 c0 19 08 09 00 49 21 63 54 40 50 60 19 54 ab b3 18 05 f4 ef e2 81 17 17 16 c3 bf cc 
 
 NS UNITDATA MESSAGE to BSS, BVCI 0x1002, msg length 91
-00 af e2 80 6e 00 50 20 16 82 02 58 13 9d 19 13 42 33 57 2b f7 c8 48 02 13 48 50 c8 48 02 14 48 50 c8 48 02 17 49 10 c8 48 02 00 0a 82 07 04 0d 88 11 12 13 14 15 16 17 18 00 81 00 0e 9d 41 c0 19 08 09 00 49 21 63 54 40 50 60 19 54 ab b3 18 05 f4 ef e2 81 17 17 16 c3 bf cc 
+00 af e2 80 6e 00 50 20 16 82 02 58 13 9d 19 13 42 33 57 2b f7 c8 48 02 13 48 50 c8 48 02 14 48 50 c8 48 02 17 49 10 c8 48 02 00 0a 82 07 04 0d 88 11 12 13 14 15 16 17 18 00 81 00 0e 9d 41 c0 19 08 09 00 49 11 22 33 40 50 60 19 54 ab b3 18 05 f4 ef e2 81 17 17 16 2e e5 fd 
 
 MESSAGE to BSS at 0x01020304:1111, msg length 95
-00 00 10 02 00 af e2 80 6e 00 50 20 16 82 02 58 13 9d 19 13 42 33 57 2b f7 c8 48 02 13 48 50 c8 48 02 14 48 50 c8 48 02 17 49 10 c8 48 02 00 0a 82 07 04 0d 88 11 12 13 14 15 16 17 18 00 81 00 0e 9d 41 c0 19 08 09 00 49 21 63 54 40 50 60 19 54 ab b3 18 05 f4 ef e2 81 17 17 16 c3 bf cc 
+00 00 10 02 00 af e2 80 6e 00 50 20 16 82 02 58 13 9d 19 13 42 33 57 2b f7 c8 48 02 13 48 50 c8 48 02 14 48 50 c8 48 02 17 49 10 c8 48 02 00 0a 82 07 04 0d 88 11 12 13 14 15 16 17 18 00 81 00 0e 9d 41 c0 19 08 09 00 49 11 22 33 40 50 60 19 54 ab b3 18 05 f4 ef e2 81 17 17 16 2e e5 fd 
 
 result (UNITDATA) = 95
 
@@ -1755,8 +1755,8 @@  MESSAGE to SGSN at 0x05060708:32000, msg length 80
 result (UNITDATA) = 80
 
 Gbproxy global:
-    RAID patched              (BSS ): 6
-    RAID patched              (SGSN): 1
+    RAID patched              (BSS ): 8
+    RAID patched              (SGSN): 3
 Peers:
   NSEI 4096, BVCI 4098, not blocked, RAI 112-332-16464-96
 --- Bad cases ---
@@ -1786,8 +1786,8 @@  result (BVC_SUSPEND_ACK) = 28
 Gbproxy global:
     Invalid BVC Identifier          : 1
     Invalid Routing Area Identifier : 1
-    RAID patched              (BSS ): 6
-    RAID patched              (SGSN): 2
+    RAID patched              (BSS ): 8
+    RAID patched              (SGSN): 4
 Peers:
   NSEI 4096, BVCI 4098, not blocked, RAI 112-332-16464-96
 ===== GbProxy test END