gbproxy: Refactor gb_proxy.c into several files

This patch moves several functions and declarations out of gb_proxy.c
to make them reusable by other components and to separate them by
context and task.

Counter enums (prefix is changed to gbproxy_):
  enum gbprox_global_ctr -> gprs/gb_proxy.h
  enum gbprox_peer_ctr -> gprs/gb_proxy.h

Generic Gb parsing (prefix is changed to gprs_gb_):
  struct gbproxy_parse_context -> openbsc/gprs_gb_parse.h
  gbprox_parse_dtap() -> gprs/gprs_gb_parse.c
  gbprox_parse_llc() -> gprs/gprs_gb_parse.c
  gbprox_parse_bssgp() -> gprs/gprs_gb_parse.c
  gbprox_log_parse_context() -> gprs/gprs_gb_parse.c
  *_shift(), *_match() -> gprs/gprs_gb_parse.c (no prefix)
  gbprox_parse_gmm_* -> gprs/gprs_gb_parse.c (static)
  gbprox_parse_gsm_* -> gprs/gprs_gb_parse.c (static)

MI testing/parsing (prefix gprs_ added):
  is_mi_tmsi() -> gprs/gprs_utils.c
  is_mi_imsi() -> gprs/gprs_utils.c
  parse_mi_tmsi() -> gprs/gprs_utils.c

TLLI state handling (prefix is changed to gbproxy_):
  gbprox_*tlli* -> gprs/gb_proxy_tlli.c
  (except gbprox_patch_tlli, gbproxy_make_sgsn_tlli)

Message patching (prefix is changed to gbproxy_):
  gbprox_*patch* -> gprs/gb_proxy_patch.c
  gbprox_check_imsi -> gprs/gb_proxy_patch.c

Sponsored-by: On-Waves ehf
diff --git a/openbsc/include/openbsc/gb_proxy.h b/openbsc/include/openbsc/gb_proxy.h
index e7d1b1c..345a317 100644
--- a/openbsc/include/openbsc/gb_proxy.h
+++ b/openbsc/include/openbsc/gb_proxy.h
@@ -11,6 +11,7 @@
 #include <regex.h>
 
 struct rate_ctr_group;
+struct gprs_gb_parse_context;
 
 enum gbproxy_patch_mode {
 	GBPROX_PATCH_DEFAULT,
@@ -22,6 +23,42 @@
 	GBPROX_PATCH_LLC,		/*!< BSSGP and all supported LLC msgs */
 };
 
+enum gbproxy_global_ctr {
+	GBPROX_GLOB_CTR_INV_BVCI,
+	GBPROX_GLOB_CTR_INV_LAI,
+	GBPROX_GLOB_CTR_INV_RAI,
+	GBPROX_GLOB_CTR_INV_NSEI,
+	GBPROX_GLOB_CTR_PROTO_ERR_BSS,
+	GBPROX_GLOB_CTR_PROTO_ERR_SGSN,
+	GBPROX_GLOB_CTR_NOT_SUPPORTED_BSS,
+	GBPROX_GLOB_CTR_NOT_SUPPORTED_SGSN,
+	GBPROX_GLOB_CTR_RESTART_RESET_SGSN,
+	GBPROX_GLOB_CTR_TX_ERR_SGSN,
+	GBPROX_GLOB_CTR_OTHER_ERR,
+	GBPROX_GLOB_CTR_PATCH_PEER_ERR,
+};
+
+enum gbproxy_peer_ctr {
+	GBPROX_PEER_CTR_BLOCKED,
+	GBPROX_PEER_CTR_UNBLOCKED,
+	GBPROX_PEER_CTR_DROPPED,
+	GBPROX_PEER_CTR_INV_NSEI,
+	GBPROX_PEER_CTR_TX_ERR,
+	GBPROX_PEER_CTR_RAID_PATCHED_BSS,
+	GBPROX_PEER_CTR_RAID_PATCHED_SGSN,
+	GBPROX_PEER_CTR_APN_PATCHED,
+	GBPROX_PEER_CTR_TLLI_PATCHED_BSS,
+	GBPROX_PEER_CTR_TLLI_PATCHED_SGSN,
+	GBPROX_PEER_CTR_PTMSI_PATCHED_BSS,
+	GBPROX_PEER_CTR_PTMSI_PATCHED_SGSN,
+	GBPROX_PEER_CTR_PATCH_CRYPT_ERR,
+	GBPROX_PEER_CTR_PATCH_ERR,
+	GBPROX_PEER_CTR_ATTACH_REQS,
+	GBPROX_PEER_CTR_ATTACH_REJS,
+	GBPROX_PEER_CTR_TLLI_UNKNOWN,
+	GBPROX_PEER_CTR_TLLI_CACHE_SIZE,
+};
+
 struct gbproxy_config {
 	/* parsed from config file */
 	uint16_t nsip_sgsn_nsei;
@@ -130,31 +167,74 @@
 
 void gbprox_reset(struct gbproxy_config *cfg);
 
-int gbprox_set_patch_filter(struct gbproxy_config *cfg, const char *filter,
-		const char **err_msg);
-void gbprox_clear_patch_filter(struct gbproxy_config *cfg);
-
-void gbprox_delete_tlli(struct gbproxy_peer *peer,
-			       struct gbproxy_tlli_info *tlli_info);
-int gbprox_remove_stale_tllis(struct gbproxy_peer *peer, time_t now);
 int gbprox_cleanup_peers(struct gbproxy_config *cfg, uint16_t nsei, uint16_t bvci);
 
 struct gbproxy_peer *gbprox_peer_by_nsei(struct gbproxy_config *cfg, uint16_t nsei);
 
-struct gbproxy_tlli_info *gbprox_find_tlli(struct gbproxy_peer *peer,
-					   uint32_t tlli);
-struct gbproxy_tlli_info *gbprox_find_tlli_by_mi(struct gbproxy_peer *peer,
-						 const uint8_t *mi_data,
-						 size_t mi_data_len);
-struct gbproxy_tlli_info *gbprox_find_tlli_by_sgsn_tlli(
-	struct gbproxy_peer *peer,
-	uint32_t tlli);
-struct gbproxy_tlli_info *gbprox_register_tlli(
-	struct gbproxy_peer *peer, uint32_t tlli,
-	const uint8_t *imsi, size_t imsi_len, time_t now);
 struct gbproxy_peer *gbproxy_peer_alloc(struct gbproxy_config *cfg, uint16_t bvci);
 void gbproxy_peer_free(struct gbproxy_peer *peer);
 
-int gbprox_check_imsi(struct gbproxy_peer *peer,
-		const uint8_t *imsi, size_t imsi_len);
+/* TLLI state handling */
+void gbproxy_delete_tllis(struct gbproxy_peer *peer);
+int gbproxy_check_tlli(struct gbproxy_peer *peer, uint32_t tlli);
+struct gbproxy_tlli_info *gbprox_find_tlli_by_ptmsi(
+	struct gbproxy_peer *peer,
+	uint32_t ptmsi);
+uint32_t gbproxy_map_tlli(
+	uint32_t other_tlli, struct gbproxy_tlli_info *tlli_info, int to_bss);
+struct gbproxy_tlli_info *gbproxy_update_tlli_state_ul(
+	struct gbproxy_peer *peer, time_t now,
+	struct gprs_gb_parse_context *parse_ctx);
+struct gbproxy_tlli_info *gbproxy_update_tlli_state_dl(
+	struct gbproxy_peer *peer, time_t now,
+	struct gprs_gb_parse_context *parse_ctx);
+void gbproxy_update_tlli_state_after(
+	struct gbproxy_peer *peer, struct gbproxy_tlli_info *tlli_info,
+	time_t now, struct gprs_gb_parse_context *parse_ctx);
+int gbproxy_remove_stale_tllis(struct gbproxy_peer *peer, time_t now);
+void gbproxy_delete_tlli(struct gbproxy_peer *peer,
+			 struct gbproxy_tlli_info *tlli_info);
+
+struct gbproxy_tlli_info *gbproxy_register_tlli(
+	struct gbproxy_peer *peer, uint32_t tlli,
+	const uint8_t *imsi, size_t imsi_len, time_t now);
+
+struct gbproxy_tlli_info *gbproxy_find_tlli(
+	struct gbproxy_peer *peer, uint32_t tlli);
+struct gbproxy_tlli_info *gbproxy_find_tlli_by_mi(
+	struct gbproxy_peer *peer, const uint8_t *mi_data, size_t mi_data_len);
+struct gbproxy_tlli_info *gbproxy_find_tlli_by_sgsn_tlli(
+	struct gbproxy_peer *peer,
+	uint32_t tlli);
+struct gbproxy_tlli_info *gbproxy_find_tlli_by_ptmsi(
+	struct gbproxy_peer *peer,
+	uint32_t ptmsi);
+
+/* needed by gb_proxy_tlli.h */
+uint32_t gbproxy_make_bss_ptmsi(struct gbproxy_peer *peer, uint32_t sgsn_ptmsi);
+uint32_t gbproxy_make_sgsn_tlli(
+	struct gbproxy_peer *peer, struct gbproxy_tlli_info *tlli_info,
+	uint32_t bss_tlli);
+int gbproxy_check_imsi(
+	struct gbproxy_peer *peer, const uint8_t *imsi, size_t imsi_len);
+
+/* Message patching */
+void gbproxy_patch_bssgp(
+	struct msgb *msg, uint8_t *bssgp, size_t bssgp_len,
+	struct gbproxy_peer *peer, struct gbproxy_tlli_info *tlli_info,
+	int *len_change, struct gprs_gb_parse_context *parse_ctx)
+	__attribute__((nonnull));
+
+int gbproxy_patch_llc(
+	struct msgb *msg, uint8_t *llc, size_t llc_len,
+	struct gbproxy_peer *peer, struct gbproxy_tlli_info *tlli_info,
+	int *len_change, struct gprs_gb_parse_context *parse_ctx)
+	__attribute__((nonnull));
+
+int gbproxy_set_patch_filter(
+	struct gbproxy_config *cfg, const char *filter, const char **err_msg);
+void gbproxy_clear_patch_filter(struct gbproxy_config *cfg);
+int gbproxy_check_imsi(
+	struct gbproxy_peer *peer, const uint8_t *imsi, size_t imsi_len);
+
 #endif
diff --git a/openbsc/include/openbsc/gprs_gb_parse.h b/openbsc/include/openbsc/gprs_gb_parse.h
new file mode 100644
index 0000000..e5ef4ef
--- /dev/null
+++ b/openbsc/include/openbsc/gprs_gb_parse.h
@@ -0,0 +1,52 @@
+#pragma once
+
+#include <openbsc/gprs_llc.h>
+
+#include <sys/types.h>
+
+struct gprs_gb_parse_context {
+	/* Pointer to protocol specific parts */
+	struct gsm48_hdr *g48_hdr;
+	struct bssgp_normal_hdr *bgp_hdr;
+	struct bssgp_ud_hdr *bud_hdr;
+	uint8_t *bssgp_data;
+	size_t bssgp_data_len;
+	uint8_t *llc;
+	size_t llc_len;
+
+	/* Extracted information */
+	struct gprs_llc_hdr_parsed llc_hdr_parsed;
+	struct tlv_parsed bssgp_tp;
+	int to_bss;
+	uint8_t *tlli_enc;
+	uint8_t *imsi;
+	size_t imsi_len;
+	uint8_t *apn_ie;
+	size_t apn_ie_len;
+	uint8_t *ptmsi_enc;
+	uint8_t *new_ptmsi_enc;
+	uint8_t *raid_enc;
+	uint8_t *old_raid_enc;
+	uint8_t *bssgp_raid_enc;
+	uint8_t *bssgp_ptimsi;
+
+	/* General info */
+	const char *llc_msg_name;
+	int invalidate_tlli;
+	int need_decryption;
+	uint32_t tlli;
+	int pdu_type;
+	int old_raid_matches;
+};
+
+int gprs_gb_parse_dtap(uint8_t *data, size_t data_len,
+		       struct gprs_gb_parse_context *parse_ctx) __attribute__((nonnull));
+
+int gprs_gb_parse_llc(uint8_t *llc, size_t llc_len,
+		      struct gprs_gb_parse_context *parse_ctx) __attribute__((nonnull));
+
+int gprs_gb_parse_bssgp(uint8_t *bssgp, size_t bssgp_len,
+			struct gprs_gb_parse_context *parse_ctx) __attribute__((nonnull));
+
+void gprs_gb_log_parse_context(struct gprs_gb_parse_context *parse_ctx,
+			       const char *default_msg_name) __attribute__((nonnull(1)));
diff --git a/openbsc/include/openbsc/gprs_utils.h b/openbsc/include/openbsc/gprs_utils.h
index 2ad5fe4..e610fde 100644
--- a/openbsc/include/openbsc/gprs_utils.h
+++ b/openbsc/include/openbsc/gprs_utils.h
@@ -31,3 +31,6 @@
 			    size_t old_size, size_t new_size);
 char *gprs_apn_to_str(char *out_str, const uint8_t *apn_enc, size_t rest_chars);
 int gprs_str_to_apn(uint8_t *apn_enc, size_t max_len, const char *str);
+int gprs_is_mi_tmsi(const uint8_t *value, size_t value_len);
+int gprs_is_mi_imsi(const uint8_t *value, size_t value_len);
+int gprs_parse_mi_tmsi(const uint8_t *value, size_t value_len, uint32_t *tmsi);