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);