[nat] Set the connection type/reason as out parameter

We are analyzing each CR message and it is nice to know the
reason these connections were created. Change the nat method.
diff --git a/openbsc/include/openbsc/bsc_nat.h b/openbsc/include/openbsc/bsc_nat.h
index 351a06d..b9a8c60 100644
--- a/openbsc/include/openbsc/bsc_nat.h
+++ b/openbsc/include/openbsc/bsc_nat.h
@@ -42,6 +42,14 @@
 
 struct bsc_nat;
 
+enum {
+	NAT_CON_TYPE_NONE,
+	NAT_CON_TYPE_LU,
+	NAT_CON_TYPE_CM_SERV_REQ,
+	NAT_CON_TYPE_PAG_RESP,
+	NAT_CON_TYPE_OTHER,
+};
+
 /*
  * For the NAT we will need to analyze and later patch
  * the received message. This would require us to parse
@@ -261,7 +269,8 @@
 /**
  * Content filtering.
  */
-int bsc_nat_filter_sccp_cr(struct bsc_connection *, struct msgb *msg, struct bsc_nat_parsed *);
+int bsc_nat_filter_sccp_cr(struct bsc_connection *bsc, struct msgb *msg,
+			   struct bsc_nat_parsed *, int *con_type);
 
 /**
  * SCCP patching and handling
diff --git a/openbsc/src/nat/bsc_nat.c b/openbsc/src/nat/bsc_nat.c
index fe53f49..9bfa54e 100644
--- a/openbsc/src/nat/bsc_nat.c
+++ b/openbsc/src/nat/bsc_nat.c
@@ -574,6 +574,7 @@
 
 static int forward_sccp_to_msc(struct bsc_connection *bsc, struct msgb *msg)
 {
+	int con_type;
 	struct msgb *refuse;
 	struct sccp_connections *con;
 	struct bsc_nat_parsed *parsed;
@@ -605,7 +606,7 @@
 	if (parsed->ipa_proto == IPAC_PROTO_SCCP) {
 		switch (parsed->sccp_type) {
 		case SCCP_MSG_TYPE_CR:
-			if (bsc_nat_filter_sccp_cr(bsc, msg, parsed) != 0)
+			if (bsc_nat_filter_sccp_cr(bsc, msg, parsed, &con_type) != 0)
 				goto exit3;
 			if (create_sccp_src_ref(bsc, msg, parsed) != 0)
 				goto exit2;
diff --git a/openbsc/src/nat/bsc_nat_utils.c b/openbsc/src/nat/bsc_nat_utils.c
index 18fac0c..616e52f 100644
--- a/openbsc/src/nat/bsc_nat_utils.c
+++ b/openbsc/src/nat/bsc_nat_utils.c
@@ -315,13 +315,15 @@
 }
 
 /* Filter out CR data... */
-int bsc_nat_filter_sccp_cr(struct bsc_connection *bsc, struct msgb *msg, struct bsc_nat_parsed *parsed)
+int bsc_nat_filter_sccp_cr(struct bsc_connection *bsc, struct msgb *msg, struct bsc_nat_parsed *parsed, int *con_type)
 {
 	struct tlv_parsed tp;
 	struct gsm48_hdr *hdr48;
 	int hdr48_len;
 	int len;
 
+	*con_type = NAT_CON_TYPE_NONE;
+
 	if (parsed->gsm_type != BSS_MAP_MSG_COMPLETE_LAYER_3) {
 		LOGP(DNAT, LOGL_ERROR,
 		     "Rejecting CR message due wrong GSM Type %d\n", parsed->gsm_type);
@@ -357,15 +359,19 @@
 
 	if (hdr48->proto_discr == GSM48_PDISC_MM &&
 	    hdr48->msg_type == GSM48_MT_MM_LOC_UPD_REQUEST) {
+		*con_type = NAT_CON_TYPE_LU;
 		return _cr_check_loc_upd(bsc, &hdr48->data[0], hdr48_len - sizeof(*hdr48));
 	} else if (hdr48->proto_discr == GSM48_PDISC_MM &&
 		  hdr48->msg_type == GSM48_MT_MM_CM_SERV_REQ) {
+		*con_type = NAT_CON_TYPE_CM_SERV_REQ;
 		return _cr_check_cm_serv_req(bsc, &hdr48->data[0], hdr48_len - sizeof(*hdr48));
 	} else if (hdr48->proto_discr == GSM48_PDISC_RR &&
 		   hdr48->msg_type == GSM48_MT_RR_PAG_RESP) {
+		*con_type = NAT_CON_TYPE_PAG_RESP;
 		return _cr_check_pag_resp(bsc, &hdr48->data[0], hdr48_len - sizeof(*hdr48));
 	} else {
 		/* We only want to filter the above, let other things pass */
+		*con_type = NAT_CON_TYPE_OTHER;
 		return 0;
 	}
 }
diff --git a/openbsc/tests/bsc-nat/bsc_nat_test.c b/openbsc/tests/bsc-nat/bsc_nat_test.c
index 0ccd23f..adc8a19 100644
--- a/openbsc/tests/bsc-nat/bsc_nat_test.c
+++ b/openbsc/tests/bsc-nat/bsc_nat_test.c
@@ -566,6 +566,7 @@
 	const u_int8_t *data;
 	int length;
 	int result;
+	int contype;
 
 	const char *bsc_imsi_allow;
 	const char *bsc_imsi_deny;
@@ -577,16 +578,19 @@
 		.data = bssmap_cr,
 		.length = sizeof(bssmap_cr),
 		.result = 0,
+		.contype = NAT_CON_TYPE_CM_SERV_REQ,
 	},
 	{
 		.data = bss_lu,
 		.length = sizeof(bss_lu),
 		.result = 0,
+		.contype = NAT_CON_TYPE_LU,
 	},
 	{
 		.data = pag_resp,
 		.length = sizeof(pag_resp),
 		.result = 0,
+		.contype = NAT_CON_TYPE_PAG_RESP,
 	},
 	{
 		/* nat deny is before blank/null BSC */
@@ -594,6 +598,7 @@
 		.length = sizeof(bss_lu),
 		.result = -3,
 		.nat_imsi_deny = "[0-9]*",
+		.contype = NAT_CON_TYPE_LU,
 	},
 	{
 		/* BSC allow is before NAT deny */
@@ -602,6 +607,7 @@
 		.result = 0,
 		.nat_imsi_deny = "[0-9]*",
 		.bsc_imsi_allow = "2440[0-9]*",
+		.contype = NAT_CON_TYPE_LU,
 	},
 	{
 		/* BSC allow is before NAT deny */
@@ -610,6 +616,7 @@
 		.result = 0,
 		.bsc_imsi_allow = "[0-9]*",
 		.nat_imsi_deny = "[0-9]*",
+		.contype = NAT_CON_TYPE_LU,
 	},
 	{
 		/* filter as deny is first */
@@ -619,13 +626,14 @@
 		.bsc_imsi_deny = "[0-9]*",
 		.bsc_imsi_allow = "[0-9]*",
 		.nat_imsi_deny = "[0-9]*",
+		.contype = NAT_CON_TYPE_LU,
 	},
 
 };
 
 static void test_cr_filter()
 {
-	int i, res;
+	int i, res, contype;
 	struct msgb *msg = msgb_alloc(4096, "test_cr_filter");
 	struct bsc_nat_parsed *parsed;
 
@@ -653,12 +661,17 @@
 			abort();
 		}
 
-		res = bsc_nat_filter_sccp_cr(bsc, msg, parsed);
+		res = bsc_nat_filter_sccp_cr(bsc, msg, parsed, &contype);
 		if (res != cr_filter[i].result) {
 			fprintf(stderr, "FAIL: Wrong result %d for test %d.\n", res, i);
 			abort();
 		}
 
+		if (contype != cr_filter[i].contype) {
+			fprintf(stderr, "FAIL: Wrong contype %d for test %d.\n", res, contype);
+			abort();
+		}
+
 		talloc_free(parsed);
 	}