Merge Jacob's GPRS GB Proxy related configs

All review feedback will be addressed _after_ the split of the
files. This is the only reasonable approach to get the split of
files merged. I didn't have the time to review all of the code
before the point of splitting.
This commit is contained in:
Holger Hans Peter Freyther 2014-08-24 16:17:17 +02:00
commit ddbbe695b3
14 changed files with 3440 additions and 1804 deletions

View File

@ -11,6 +11,8 @@
#include <regex.h>
struct rate_ctr_group;
struct gprs_gb_parse_context;
struct tlv_parsed;
enum gbproxy_patch_mode {
GBPROX_PATCH_DEFAULT,
@ -22,6 +24,42 @@ enum gbproxy_patch_mode {
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;
@ -44,10 +82,15 @@ struct gbproxy_config {
enum gbproxy_patch_mode patch_mode;
int tlli_max_age;
int tlli_max_len;
int patch_ptmsi;
/* IMSI checking/matching */
int check_imsi;
regex_t imsi_re_comp;
/* Used to generate identifiers */
unsigned bss_ptmsi_state;
unsigned sgsn_tlli_state;
};
struct gbproxy_patch_state {
@ -81,14 +124,26 @@ struct gbproxy_peer {
struct gbproxy_patch_state patch_state;
};
struct gbproxy_tlli_state {
uint32_t current;
uint32_t assigned;
int bss_validated;
int net_validated;
uint32_t ptmsi;
};
struct gbproxy_tlli_info {
struct llist_head list;
uint32_t tlli;
struct gbproxy_tlli_state tlli;
struct gbproxy_tlli_state sgsn_tlli;
time_t timestamp;
uint8_t *mi_data;
size_t mi_data_len;
int enable_patching;
};
@ -113,26 +168,85 @@ int gbprox_reset_persistent_nsvcs(struct gprs_ns_inst *nsi);
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);
/* 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);
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_by_mi(struct gbproxy_peer *peer,
const uint8_t *mi_data,
size_t mi_data_len);
struct gbproxy_tlli_info *gbprox_register_tlli(
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_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);
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);
/* Peer handling */
struct gbproxy_peer *gbproxy_peer_by_bvci(
struct gbproxy_config *cfg, uint16_t bvci) __attribute__((nonnull));
struct gbproxy_peer *gbproxy_peer_by_nsei(
struct gbproxy_config *cfg, uint16_t nsei) __attribute__((nonnull));
struct gbproxy_peer *gbproxy_peer_by_rai(
struct gbproxy_config *cfg, const uint8_t *ra) __attribute__((nonnull));
struct gbproxy_peer *gbproxy_peer_by_lai(
struct gbproxy_config *cfg, const uint8_t *la) __attribute__((nonnull));
struct gbproxy_peer *gbproxy_peer_by_bssgp_tlv(
struct gbproxy_config *cfg, struct tlv_parsed *tp)
__attribute__((nonnull));
struct gbproxy_peer *gbproxy_peer_alloc(struct gbproxy_config *cfg, uint16_t bvci)
__attribute__((nonnull));
void gbproxy_peer_free(struct gbproxy_peer *peer) __attribute__((nonnull));
int gbproxy_cleanup_peers(struct gbproxy_config *cfg, uint16_t nsei, uint16_t bvci)
__attribute__((nonnull));
#endif

View File

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

View File

@ -31,3 +31,6 @@ int gprs_msgb_resize_area(struct msgb *msg, uint8_t *area,
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);

View File

@ -14,7 +14,8 @@ bin_PROGRAMS = osmo-gbproxy
endif
osmo_gbproxy_SOURCES = gb_proxy.c gb_proxy_main.c gb_proxy_vty.c \
gprs_llc_parse.c crc24.c gprs_utils.c
gb_proxy_patch.c gb_proxy_tlli.c gb_proxy_peer.c \
gprs_gb_parse.c gprs_llc_parse.c crc24.c gprs_utils.c
osmo_gbproxy_LDADD = $(top_builddir)/src/libcommon/libcommon.a \
$(OSMO_LIBS)

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,475 @@
/* Gb-proxy message patching */
/* (C) 2014 by On-Waves
* All Rights Reserved
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#include <openbsc/gb_proxy.h>
#include <openbsc/gprs_utils.h>
#include <openbsc/gprs_gb_parse.h>
#include <openbsc/gsm_data_shared.h>
#include <openbsc/gsm_04_08_gprs.h>
#include <openbsc/debug.h>
#include <osmocom/gprs/protocol/gsm_08_18.h>
#include <osmocom/core/rate_ctr.h>
/* check whether patching is enabled at this level */
static int patching_is_enabled(struct gbproxy_peer *peer,
enum gbproxy_patch_mode need_at_least)
{
enum gbproxy_patch_mode patch_mode = peer->cfg->patch_mode;
if (patch_mode == GBPROX_PATCH_DEFAULT)
patch_mode = GBPROX_PATCH_LLC;
return need_at_least <= patch_mode;
}
/* check whether patching is enabled at this level */
static int patching_is_required(struct gbproxy_peer *peer,
enum gbproxy_patch_mode need_at_least)
{
return need_at_least <= peer->cfg->patch_mode;
}
static int allow_message_patching(struct gbproxy_peer *peer, int msg_type)
{
if (msg_type >= GSM48_MT_GSM_ACT_PDP_REQ) {
return patching_is_enabled(peer, GBPROX_PATCH_LLC_GSM);
} else if (msg_type > GSM48_MT_GMM_ATTACH_REJ) {
return patching_is_enabled(peer, GBPROX_PATCH_LLC);
} else if (msg_type > GSM48_MT_GMM_ATTACH_REQ) {
return patching_is_enabled(peer, GBPROX_PATCH_LLC_ATTACH);
} else {
return patching_is_enabled(peer, GBPROX_PATCH_LLC_ATTACH_REQ);
}
}
/* patch RA identifier in place */
static void gbproxy_patch_raid(uint8_t *raid_enc, struct gbproxy_peer *peer,
int to_bss, const char *log_text)
{
struct gbproxy_patch_state *state = &peer->patch_state;
int old_mcc;
int old_mnc;
struct gprs_ra_id raid;
gsm48_parse_ra(&raid, raid_enc);
old_mcc = raid.mcc;
old_mnc = raid.mnc;
if (!to_bss) {
/* BSS -> SGSN */
if (state->local_mcc)
raid.mcc = peer->cfg->core_mcc;
if (state->local_mnc)
raid.mnc = peer->cfg->core_mnc;
} else {
/* SGSN -> BSS */
if (state->local_mcc)
raid.mcc = state->local_mcc;
if (state->local_mnc)
raid.mnc = state->local_mnc;
}
if (state->local_mcc || state->local_mnc) {
enum gbproxy_peer_ctr counter =
to_bss ?
GBPROX_PEER_CTR_RAID_PATCHED_SGSN :
GBPROX_PEER_CTR_RAID_PATCHED_BSS;
LOGP(DGPRS, LOGL_DEBUG,
"Patching %s to %s: "
"%d-%d-%d-%d -> %d-%d-%d-%d\n",
log_text,
to_bss ? "BSS" : "SGSN",
old_mcc, old_mnc, raid.lac, raid.rac,
raid.mcc, raid.mnc, raid.lac, raid.rac);
gsm48_construct_ra(raid_enc, &raid);
rate_ctr_inc(&peer->ctrg->ctr[counter]);
}
}
static void gbproxy_patch_apn_ie(struct msgb *msg,
uint8_t *apn_ie, size_t apn_ie_len,
struct gbproxy_peer *peer,
size_t *new_apn_ie_len, const char *log_text)
{
struct apn_ie_hdr {
uint8_t iei;
uint8_t apn_len;
uint8_t apn[0];
} *hdr = (void *)apn_ie;
size_t apn_len = hdr->apn_len;
uint8_t *apn = hdr->apn;
OSMO_ASSERT(apn_ie_len == apn_len + sizeof(struct apn_ie_hdr));
OSMO_ASSERT(apn_ie_len > 2 && apn_ie_len <= 102);
if (peer->cfg->core_apn_size == 0) {
char str1[110];
/* Remove the IE */
LOGP(DGPRS, LOGL_DEBUG,
"Patching %s to SGSN: Removing APN '%s'\n",
log_text,
gprs_apn_to_str(str1, apn, apn_len));
*new_apn_ie_len = 0;
gprs_msgb_resize_area(msg, apn_ie, apn_ie_len, 0);
} else {
/* Resize the IE */
char str1[110];
char str2[110];
OSMO_ASSERT(peer->cfg->core_apn_size <= 100);
LOGP(DGPRS, LOGL_DEBUG,
"Patching %s to SGSN: "
"Replacing APN '%s' -> '%s'\n",
log_text,
gprs_apn_to_str(str1, apn, apn_len),
gprs_apn_to_str(str2, peer->cfg->core_apn,
peer->cfg->core_apn_size));
*new_apn_ie_len = peer->cfg->core_apn_size + 2;
gprs_msgb_resize_area(msg, apn, apn_len, peer->cfg->core_apn_size);
memcpy(apn, peer->cfg->core_apn, peer->cfg->core_apn_size);
hdr->apn_len = peer->cfg->core_apn_size;
}
rate_ctr_inc(&peer->ctrg->ctr[GBPROX_PEER_CTR_APN_PATCHED]);
}
static int gbproxy_patch_tlli(uint8_t *tlli_enc,
struct gbproxy_peer *peer,
uint32_t new_tlli,
int to_bss, const char *log_text)
{
uint32_t tlli_be;
uint32_t tlli;
enum gbproxy_peer_ctr counter =
to_bss ?
GBPROX_PEER_CTR_TLLI_PATCHED_SGSN :
GBPROX_PEER_CTR_TLLI_PATCHED_BSS;
memcpy(&tlli_be, tlli_enc, sizeof(tlli_be));
tlli = ntohl(tlli_be);
if (tlli == new_tlli)
return 0;
LOGP(DGPRS, LOGL_DEBUG,
"Patching %ss: "
"Replacing %08x -> %08x\n",
log_text, tlli, new_tlli);
tlli_be = htonl(new_tlli);
memcpy(tlli_enc, &tlli_be, sizeof(tlli_be));
rate_ctr_inc(&peer->ctrg->ctr[counter]);
return 1;
}
static int gbproxy_patch_ptmsi(uint8_t *ptmsi_enc,
struct gbproxy_peer *peer,
uint32_t new_ptmsi,
int to_bss, const char *log_text)
{
uint32_t ptmsi_be;
uint32_t ptmsi;
enum gbproxy_peer_ctr counter =
to_bss ?
GBPROX_PEER_CTR_PTMSI_PATCHED_SGSN :
GBPROX_PEER_CTR_PTMSI_PATCHED_BSS;
memcpy(&ptmsi_be, ptmsi_enc + 1, sizeof(ptmsi_be));
ptmsi = ntohl(ptmsi_be);
if (ptmsi == new_ptmsi)
return 0;
LOGP(DGPRS, LOGL_DEBUG,
"Patching %ss: "
"Replacing %08x -> %08x\n",
log_text, ptmsi, new_ptmsi);
ptmsi_be = htonl(new_ptmsi);
memcpy(ptmsi_enc + 1, &ptmsi_be, sizeof(ptmsi_be));
rate_ctr_inc(&peer->ctrg->ctr[counter]);
return 1;
}
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)
{
struct gprs_llc_hdr_parsed *ghp = &parse_ctx->llc_hdr_parsed;
int have_patched = 0;
int fcs;
if (parse_ctx->g48_hdr && !allow_message_patching(peer, parse_ctx->g48_hdr->msg_type))
return have_patched;
if (parse_ctx->ptmsi_enc && tlli_info) {
uint32_t ptmsi;
if (parse_ctx->to_bss)
ptmsi = tlli_info->tlli.ptmsi;
else
ptmsi = tlli_info->sgsn_tlli.ptmsi;
if (ptmsi != GSM_RESERVED_TMSI) {
if (gbproxy_patch_ptmsi(parse_ctx->ptmsi_enc, peer,
ptmsi, parse_ctx->to_bss, "P-TMSI"))
have_patched = 1;
} else {
/* TODO: invalidate old RAI if present (see below) */
}
}
if (parse_ctx->new_ptmsi_enc && tlli_info) {
uint32_t ptmsi;
if (parse_ctx->to_bss)
ptmsi = tlli_info->tlli.ptmsi;
else
ptmsi = tlli_info->sgsn_tlli.ptmsi;
OSMO_ASSERT(ptmsi);
if (gbproxy_patch_ptmsi(parse_ctx->new_ptmsi_enc, peer,
ptmsi, parse_ctx->to_bss, "new P-TMSI"))
have_patched = 1;
}
if (parse_ctx->raid_enc) {
gbproxy_patch_raid(parse_ctx->raid_enc, peer, parse_ctx->to_bss,
parse_ctx->llc_msg_name);
have_patched = 1;
}
if (parse_ctx->old_raid_enc && parse_ctx->old_raid_matches) {
/* TODO: Patch to invalid if P-TMSI unknown. */
gbproxy_patch_raid(parse_ctx->old_raid_enc, peer, parse_ctx->to_bss,
parse_ctx->llc_msg_name);
have_patched = 1;
}
if (parse_ctx->apn_ie &&
peer->cfg->core_apn &&
!parse_ctx->to_bss &&
gbproxy_check_tlli(peer, parse_ctx->tlli)) {
size_t new_len;
gbproxy_patch_apn_ie(msg,
parse_ctx->apn_ie, parse_ctx->apn_ie_len,
peer, &new_len, parse_ctx->llc_msg_name);
*len_change += (int)new_len - (int)parse_ctx->apn_ie_len;
have_patched = 1;
}
if (have_patched) {
llc_len += *len_change;
ghp->crc_length += *len_change;
/* 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 have_patched;
}
/* patch BSSGP message to use core_mcc/mnc on the SGSN side */
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)
{
const char *err_info = NULL;
int err_ctr = -1;
if (!patching_is_enabled(peer, GBPROX_PATCH_BSSGP))
return;
if (parse_ctx->bssgp_raid_enc)
gbproxy_patch_raid(parse_ctx->bssgp_raid_enc, peer,
parse_ctx->to_bss, "BSSGP");
if (!patching_is_enabled(peer, GBPROX_PATCH_LLC_ATTACH_REQ))
return;
if (parse_ctx->need_decryption &&
patching_is_required(peer, GBPROX_PATCH_LLC_ATTACH)) {
/* Patching LLC messages has been requested
* explicitly, but the message (including the
* type) is encrypted, so we possibly fail to
* patch the LLC part of the message. */
err_ctr = GBPROX_PEER_CTR_PATCH_CRYPT_ERR;
err_info = "GMM message is encrypted";
goto patch_error;
}
if (parse_ctx->tlli_enc && tlli_info) {
uint32_t tlli = gbproxy_map_tlli(parse_ctx->tlli,
tlli_info, parse_ctx->to_bss);
if (tlli) {
gbproxy_patch_tlli(parse_ctx->tlli_enc, peer, tlli,
parse_ctx->to_bss, "TLLI");
parse_ctx->tlli = tlli;
} else if (parse_ctx->to_bss) {
/* Happens with unknown (not cached) TLLI coming from
* the SGSN */
/* TODO: What shall be done with the message in this case? */
err_ctr = GBPROX_PEER_CTR_TLLI_UNKNOWN;
err_info = "TLLI sent by the SGSN is unknown";
goto patch_error;
} else {
/* Internal error */
err_ctr = GBPROX_PEER_CTR_PATCH_ERR;
err_info = "Replacement TLLI is 0";
goto patch_error;
}
}
if (parse_ctx->llc) {
uint8_t *llc = parse_ctx->llc;
size_t llc_len = parse_ctx->llc_len;
int llc_len_change = 0;
gbproxy_patch_llc(msg, llc, llc_len, peer, tlli_info,
&llc_len_change, parse_ctx);
/* Note that the APN might have been resized here, but no
* pointer int the parse_ctx will refer to an adress after the
* APN. So it's possible to patch first and do the TLLI
* handling afterwards. */
if (llc_len_change) {
llc_len += llc_len_change;
/* Fix LLC IE len */
/* TODO: This is a kludge, but the a pointer to the
* start of the IE is not available here */
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_PEER_CTR_PATCH_ERR;
goto patch_error;
}
llc[-1] = llc_len | 0x80;
} else {
llc[-2] = (llc_len >> 8) & 0x7f;
llc[-1] = llc_len & 0xff;
}
*len_change += llc_len_change;
}
/* Note that the tp struct might contain invalid pointers here
* if the LLC field has changed its size */
parse_ctx->llc_len = llc_len;
}
return;
patch_error:
OSMO_ASSERT(err_ctr >= 0);
rate_ctr_inc(&peer->ctrg->ctr[err_ctr]);
LOGP(DGPRS, LOGL_ERROR,
"NSEI=%u(%s) failed to patch BSSGP message as requested: %s.\n",
msgb_nsei(msg), parse_ctx->to_bss ? "SGSN" : "BSS",
err_info);
}
void gbproxy_clear_patch_filter(struct gbproxy_config *cfg)
{
if (cfg->check_imsi) {
regfree(&cfg->imsi_re_comp);
cfg->check_imsi = 0;
}
}
int gbproxy_set_patch_filter(struct gbproxy_config *cfg, const char *filter,
const char **err_msg)
{
static char err_buf[300];
int rc;
gbproxy_clear_patch_filter(cfg);
if (!filter)
return 0;
rc = regcomp(&cfg->imsi_re_comp, filter,
REG_EXTENDED | REG_NOSUB | REG_ICASE);
if (rc == 0) {
cfg->check_imsi = 1;
return 0;
}
if (err_msg) {
regerror(rc, &cfg->imsi_re_comp,
err_buf, sizeof(err_buf));
*err_msg = err_buf;
}
return -1;
}
int gbproxy_check_imsi(struct gbproxy_peer *peer,
const uint8_t *imsi, size_t imsi_len)
{
char mi_buf[200];
int rc;
if (!peer->cfg->check_imsi)
return 1;
rc = gprs_is_mi_imsi(imsi, imsi_len);
if (rc > 0)
rc = gsm48_mi_to_string(mi_buf, sizeof(mi_buf), imsi, imsi_len);
if (rc <= 0) {
LOGP(DGPRS, LOGL_NOTICE, "Invalid IMSI %s\n",
osmo_hexdump(imsi, imsi_len));
return -1;
}
LOGP(DGPRS, LOGL_DEBUG, "Checking IMSI '%s' (%d)\n", mi_buf, rc);
rc = regexec(&peer->cfg->imsi_re_comp, mi_buf, 0, NULL, 0);
if (rc == REG_NOMATCH) {
LOGP(DGPRS, LOGL_INFO,
"IMSI '%s' doesn't match pattern '%s'\n",
mi_buf, peer->cfg->match_re);
return 0;
}
return 1;
}

View File

@ -0,0 +1,200 @@
/* Gb proxy peer handling */
/* (C) 2010 by Harald Welte <laforge@gnumonks.org>
* (C) 2010-2013 by On-Waves
* (C) 2013 by Holger Hans Peter Freyther
* All Rights Reserved
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#include <openbsc/gb_proxy.h>
#include <openbsc/gsm_data.h>
#include <openbsc/gsm_data_shared.h>
#include <openbsc/gsm_04_08_gprs.h>
#include <openbsc/debug.h>
#include <osmocom/gprs/protocol/gsm_08_18.h>
#include <osmocom/core/rate_ctr.h>
#include <osmocom/core/talloc.h>
#include <string.h>
static const struct rate_ctr_desc peer_ctr_description[] = {
{ "blocked", "BVC Block " },
{ "unblocked", "BVC Unblock " },
{ "dropped", "BVC blocked, dropped packet " },
{ "inv-nsei", "NSEI mismatch " },
{ "tx-err", "NS Transmission error " },
{ "raid-mod.bss", "RAID patched (BSS )" },
{ "raid-mod.sgsn", "RAID patched (SGSN)" },
{ "apn-mod.sgsn", "APN patched " },
{ "tlli-mod.bss", "TLLI patched (BSS )" },
{ "tlli-mod.sgsn", "TLLI patched (SGSN)" },
{ "ptmsi-mod.bss", "P-TMSI patched (BSS )" },
{ "ptmsi-mod.sgsn","P-TMSI patched (SGSN)" },
{ "mod-crypt-err", "Patch error: encrypted " },
{ "mod-err", "Patch error: other " },
{ "attach-reqs", "Attach Request count " },
{ "attach-rejs", "Attach Reject count " },
{ "tlli-unknown", "TLLI from SGSN unknown " },
{ "tlli-cache", "TLLI cache size " },
};
static const struct rate_ctr_group_desc peer_ctrg_desc = {
.group_name_prefix = "gbproxy.peer",
.group_description = "GBProxy Peer Statistics",
.num_ctr = ARRAY_SIZE(peer_ctr_description),
.ctr_desc = peer_ctr_description,
};
/* Find the gbprox_peer by its BVCI */
struct gbproxy_peer *gbproxy_peer_by_bvci(struct gbproxy_config *cfg, uint16_t bvci)
{
struct gbproxy_peer *peer;
llist_for_each_entry(peer, &cfg->bts_peers, list) {
if (peer->bvci == bvci)
return peer;
}
return NULL;
}
/* Find the gbprox_peer by its NSEI */
struct gbproxy_peer *gbproxy_peer_by_nsei(struct gbproxy_config *cfg,
uint16_t nsei)
{
struct gbproxy_peer *peer;
llist_for_each_entry(peer, &cfg->bts_peers, list) {
if (peer->nsei == nsei)
return peer;
}
return NULL;
}
/* look-up a peer by its Routeing Area Identification (RAI) */
struct gbproxy_peer *gbproxy_peer_by_rai(struct gbproxy_config *cfg,
const uint8_t *ra)
{
struct gbproxy_peer *peer;
llist_for_each_entry(peer, &cfg->bts_peers, list) {
if (!memcmp(peer->ra, ra, 6))
return peer;
}
return NULL;
}
/* look-up a peer by its Location Area Identification (LAI) */
struct gbproxy_peer *gbproxy_peer_by_lai(struct gbproxy_config *cfg,
const uint8_t *la)
{
struct gbproxy_peer *peer;
llist_for_each_entry(peer, &cfg->bts_peers, list) {
if (!memcmp(peer->ra, la, 5))
return peer;
}
return NULL;
}
/* look-up a peer by its Location Area Code (LAC) */
struct gbproxy_peer *gbproxy_peer_by_lac(struct gbproxy_config *cfg,
const uint8_t *la)
{
struct gbproxy_peer *peer;
llist_for_each_entry(peer, &cfg->bts_peers, list) {
if (!memcmp(peer->ra + 3, la + 3, 2))
return peer;
}
return NULL;
}
struct gbproxy_peer *gbproxy_peer_by_bssgp_tlv(struct gbproxy_config *cfg,
struct tlv_parsed *tp)
{
if (TLVP_PRESENT(tp, BSSGP_IE_BVCI)) {
uint16_t bvci;
bvci = ntohs(tlvp_val16_unal(tp, BSSGP_IE_BVCI));
if (bvci >= 2)
return gbproxy_peer_by_bvci(cfg, bvci);
}
if (TLVP_PRESENT(tp, BSSGP_IE_ROUTEING_AREA)) {
uint8_t *rai = (uint8_t *)TLVP_VAL(tp, BSSGP_IE_ROUTEING_AREA);
/* Only compare LAC part, since MCC/MNC are possibly patched.
* Since the LAC of different BSS must be different when
* MCC/MNC are patched, collisions shouldn't happen. */
return gbproxy_peer_by_lac(cfg, rai);
}
if (TLVP_PRESENT(tp, BSSGP_IE_LOCATION_AREA)) {
uint8_t *lai = (uint8_t *)TLVP_VAL(tp, BSSGP_IE_LOCATION_AREA);
return gbproxy_peer_by_lac(cfg, lai);
}
return NULL;
}
struct gbproxy_peer *gbproxy_peer_alloc(struct gbproxy_config *cfg, uint16_t bvci)
{
struct gbproxy_peer *peer;
peer = talloc_zero(tall_bsc_ctx, struct gbproxy_peer);
if (!peer)
return NULL;
peer->bvci = bvci;
peer->ctrg = rate_ctr_group_alloc(peer, &peer_ctrg_desc, bvci);
peer->cfg = cfg;
llist_add(&peer->list, &cfg->bts_peers);
INIT_LLIST_HEAD(&peer->patch_state.enabled_tllis);
return peer;
}
void gbproxy_peer_free(struct gbproxy_peer *peer)
{
llist_del(&peer->list);
gbproxy_delete_tllis(peer);
rate_ctr_group_free(peer->ctrg);
peer->ctrg = NULL;
talloc_free(peer);
}
int gbproxy_cleanup_peers(struct gbproxy_config *cfg, uint16_t nsei, uint16_t bvci)
{
int counter = 0;
struct gbproxy_peer *peer, *tmp;
llist_for_each_entry_safe(peer, tmp, &cfg->bts_peers, list) {
if (peer->nsei != nsei)
continue;
if (bvci && peer->bvci != bvci)
continue;
gbproxy_peer_free(peer);
counter += 1;
}
return counter;
}

View File

@ -0,0 +1,544 @@
/* Gb-proxy TLLI state handling */
/* (C) 2014 by On-Waves
* All Rights Reserved
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#include <openbsc/gb_proxy.h>
#include <openbsc/gprs_utils.h>
#include <openbsc/gprs_gb_parse.h>
#include <openbsc/gsm_data_shared.h>
#include <openbsc/debug.h>
#include <osmocom/gsm/gsm_utils.h>
#include <osmocom/core/rate_ctr.h>
#include <osmocom/core/talloc.h>
struct gbproxy_tlli_info *gbproxy_find_tlli(struct gbproxy_peer *peer,
uint32_t tlli)
{
struct gbproxy_tlli_info *tlli_info;
struct gbproxy_patch_state *state = &peer->patch_state;
llist_for_each_entry(tlli_info, &state->enabled_tllis, list)
if (tlli_info->tlli.current == tlli ||
tlli_info->tlli.assigned == tlli)
return tlli_info;
return NULL;
}
struct gbproxy_tlli_info *gbproxy_find_tlli_by_ptmsi(
struct gbproxy_peer *peer,
uint32_t ptmsi)
{
struct gbproxy_tlli_info *tlli_info;
struct gbproxy_patch_state *state = &peer->patch_state;
llist_for_each_entry(tlli_info, &state->enabled_tllis, list)
if (tlli_info->tlli.ptmsi == ptmsi)
return tlli_info;
return NULL;
}
struct gbproxy_tlli_info *gbproxy_find_tlli_by_sgsn_tlli(
struct gbproxy_peer *peer,
uint32_t tlli)
{
struct gbproxy_tlli_info *tlli_info;
struct gbproxy_patch_state *state = &peer->patch_state;
llist_for_each_entry(tlli_info, &state->enabled_tllis, list)
if (tlli_info->sgsn_tlli.current == tlli ||
tlli_info->sgsn_tlli.assigned == tlli)
return tlli_info;
return NULL;
}
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 *tlli_info;
struct gbproxy_patch_state *state = &peer->patch_state;
if (!gprs_is_mi_imsi(mi_data, mi_data_len))
return NULL;
llist_for_each_entry(tlli_info, &state->enabled_tllis, list) {
if (tlli_info->mi_data_len != mi_data_len)
continue;
if (memcmp(tlli_info->mi_data, mi_data, mi_data_len) != 0)
continue;
return tlli_info;
}
return NULL;
}
void gbproxy_delete_tlli(struct gbproxy_peer *peer,
struct gbproxy_tlli_info *tlli_info)
{
struct gbproxy_patch_state *state = &peer->patch_state;
llist_del(&tlli_info->list);
talloc_free(tlli_info);
state->enabled_tllis_count -= 1;
peer->ctrg->ctr[GBPROX_PEER_CTR_TLLI_CACHE_SIZE].current =
state->enabled_tllis_count;
}
void gbproxy_delete_tllis(struct gbproxy_peer *peer)
{
struct gbproxy_tlli_info *tlli_info, *nxt;
struct gbproxy_patch_state *state = &peer->patch_state;
llist_for_each_entry_safe(tlli_info, nxt, &state->enabled_tllis, list)
gbproxy_delete_tlli(peer, tlli_info);
OSMO_ASSERT(state->enabled_tllis_count == 0);
OSMO_ASSERT(llist_empty(&state->enabled_tllis));
}
static void gbproxy_attach_tlli_info(struct gbproxy_peer *peer, time_t now,
struct gbproxy_tlli_info *tlli_info)
{
struct gbproxy_patch_state *state = &peer->patch_state;
tlli_info->timestamp = now;
llist_add(&tlli_info->list, &state->enabled_tllis);
state->enabled_tllis_count += 1;
peer->ctrg->ctr[GBPROX_PEER_CTR_TLLI_CACHE_SIZE].current =
state->enabled_tllis_count;
}
int gbproxy_remove_stale_tllis(struct gbproxy_peer *peer, time_t now)
{
struct gbproxy_patch_state *state = &peer->patch_state;
int exceeded_max_len = 0;
int deleted_count = 0;
int check_for_age;
if (peer->cfg->tlli_max_len > 0)
exceeded_max_len =
state->enabled_tllis_count - peer->cfg->tlli_max_len;
check_for_age = peer->cfg->tlli_max_age > 0;
for (; exceeded_max_len > 0; exceeded_max_len--) {
struct gbproxy_tlli_info *tlli_info;
OSMO_ASSERT(!llist_empty(&state->enabled_tllis));
tlli_info = llist_entry(state->enabled_tllis.prev,
struct gbproxy_tlli_info,
list);
LOGP(DGPRS, LOGL_INFO,
"Removing TLLI %08x from list "
"(stale, length %d, max_len exceeded)\n",
tlli_info->tlli.current, state->enabled_tllis_count);
gbproxy_delete_tlli(peer, tlli_info);
deleted_count += 1;
}
while (check_for_age && !llist_empty(&state->enabled_tllis)) {
time_t age;
struct gbproxy_tlli_info *tlli_info;
tlli_info = llist_entry(state->enabled_tllis.prev,
struct gbproxy_tlli_info,
list);
age = now - tlli_info->timestamp;
/* age < 0 only happens after system time jumps, discard entry */
if (age <= peer->cfg->tlli_max_age && age >= 0) {
check_for_age = 0;
continue;
}
LOGP(DGPRS, LOGL_INFO,
"Removing TLLI %08x from list "
"(stale, age %d, max_age exceeded)\n",
tlli_info->tlli.current, (int)age);
gbproxy_delete_tlli(peer, tlli_info);
deleted_count += 1;
}
return deleted_count;
}
static struct gbproxy_tlli_info *gbproxy_tlli_info_alloc(
struct gbproxy_peer *peer)
{
struct gbproxy_tlli_info *tlli_info;
tlli_info = talloc_zero(peer, struct gbproxy_tlli_info);
tlli_info->tlli.ptmsi = GSM_RESERVED_TMSI;
tlli_info->sgsn_tlli.ptmsi = GSM_RESERVED_TMSI;
return tlli_info;
}
static void gbproxy_detach_tlli_info(
struct gbproxy_peer *peer,
struct gbproxy_tlli_info *tlli_info)
{
struct gbproxy_patch_state *state = &peer->patch_state;
llist_del(&tlli_info->list);
OSMO_ASSERT(state->enabled_tllis_count > 0);
state->enabled_tllis_count -= 1;
peer->ctrg->ctr[GBPROX_PEER_CTR_TLLI_CACHE_SIZE].current =
state->enabled_tllis_count;
}
static void gbproxy_update_tlli_info(struct gbproxy_tlli_info *tlli_info,
const uint8_t *imsi, size_t imsi_len)
{
if (!gprs_is_mi_imsi(imsi, imsi_len))
return;
tlli_info->mi_data_len = imsi_len;
tlli_info->mi_data =
talloc_realloc_size(tlli_info, tlli_info->mi_data, imsi_len);
OSMO_ASSERT(tlli_info->mi_data != NULL);
memcpy(tlli_info->mi_data, imsi, imsi_len);
}
void gbproxy_reassign_tlli(struct gbproxy_tlli_state *tlli_state,
struct gbproxy_peer *peer, uint32_t new_tlli)
{
if (new_tlli == tlli_state->current)
return;
LOGP(DGPRS, LOGL_INFO,
"The TLLI has been reassigned from %08x to %08x\n",
tlli_state->current, new_tlli);
/* Remember assigned TLLI */
tlli_state->assigned = new_tlli;
tlli_state->bss_validated = 0;
tlli_state->net_validated = 0;
}
uint32_t gbproxy_map_tlli(uint32_t other_tlli,
struct gbproxy_tlli_info *tlli_info, int to_bss)
{
uint32_t tlli = 0;
struct gbproxy_tlli_state *src, *dst;
if (to_bss) {
src = &tlli_info->sgsn_tlli;
dst = &tlli_info->tlli;
} else {
src = &tlli_info->tlli;
dst = &tlli_info->sgsn_tlli;
}
if (src->current == other_tlli)
tlli = dst->current;
else if (src->assigned == other_tlli)
tlli = dst->assigned;
return tlli;
}
static void gbproxy_validate_tlli(struct gbproxy_tlli_state *tlli_state,
uint32_t tlli, int to_bss)
{
LOGP(DGPRS, LOGL_DEBUG,
"%s({current = %08x, assigned = %08x, net_vld = %d, bss_vld = %d}, %08x)\n",
__func__, tlli_state->current, tlli_state->assigned,
tlli_state->net_validated, tlli_state->bss_validated, tlli);
if (!tlli_state->assigned || tlli_state->assigned != tlli)
return;
/* TODO: Is this ok? Check spec */
if (gprs_tlli_type(tlli) != TLLI_LOCAL)
return;
/* See GSM 04.08, 4.7.1.5 */
if (to_bss)
tlli_state->net_validated = 1;
else
tlli_state->bss_validated = 1;
if (!tlli_state->bss_validated || !tlli_state->net_validated)
return;
LOGP(DGPRS, LOGL_INFO,
"The TLLI %08x has been validated (was %08x)\n",
tlli_state->assigned, tlli_state->current);
tlli_state->current = tlli;
tlli_state->assigned = 0;
}
void gbproxy_touch_tlli(struct gbproxy_peer *peer,
struct gbproxy_tlli_info *tlli_info, time_t now)
{
gbproxy_detach_tlli_info(peer, tlli_info);
gbproxy_attach_tlli_info(peer, now, 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 *tlli_info;
int enable_patching = -1;
int tlli_already_known;
/* Check, whether the IMSI matches */
if (gprs_is_mi_imsi(imsi, imsi_len)) {
enable_patching = gbproxy_check_imsi(peer, imsi, imsi_len);
if (enable_patching < 0)
return NULL;
}
tlli_info = gbproxy_find_tlli(peer, tlli);
if (!tlli_info) {
tlli_info = gbproxy_find_tlli_by_mi(peer, imsi, imsi_len);
if (tlli_info) {
/* TLLI has changed somehow, adjust it */
LOGP(DGPRS, LOGL_INFO,
"The TLLI has changed from %08x to %08x\n",
tlli_info->tlli.current, tlli);
tlli_info->tlli.current = tlli;
}
}
if (!tlli_info) {
tlli_info = gbproxy_tlli_info_alloc(peer);
tlli_info->tlli.current = tlli;
} else {
gbproxy_detach_tlli_info(peer, tlli_info);
tlli_already_known = 1;
}
OSMO_ASSERT(tlli_info != NULL);
if (!tlli_already_known)
LOGP(DGPRS, LOGL_INFO, "Adding TLLI %08x to list\n", tlli);
gbproxy_attach_tlli_info(peer, now, tlli_info);
gbproxy_update_tlli_info(tlli_info, imsi, imsi_len);
if (enable_patching >= 0)
tlli_info->enable_patching = enable_patching;
return tlli_info;
}
static void gbproxy_unregister_tlli(struct gbproxy_peer *peer, uint32_t tlli)
{
struct gbproxy_tlli_info *tlli_info;
tlli_info = gbproxy_find_tlli(peer, tlli);
if (tlli_info) {
LOGP(DGPRS, LOGL_INFO,
"Removing TLLI %08x from list\n",
tlli);
gbproxy_delete_tlli(peer, tlli_info);
}
}
int gbproxy_check_tlli(struct gbproxy_peer *peer, uint32_t tlli)
{
struct gbproxy_tlli_info *tlli_info;
LOGP(DGPRS, LOGL_INFO, "Checking TLLI %08x, class: %d\n",
tlli, gprs_tlli_type(tlli));
if (!peer->cfg->check_imsi)
return 1;
tlli_info = gbproxy_find_tlli(peer, tlli);
return tlli_info != NULL && tlli_info->enable_patching;
}
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 *tlli_info = NULL;
if (parse_ctx->tlli_enc)
tlli_info = gbproxy_find_tlli(peer, parse_ctx->tlli);
if (parse_ctx->tlli_enc && parse_ctx->llc) {
uint32_t sgsn_tlli;
if (!tlli_info) {
tlli_info =
gbproxy_register_tlli(peer, parse_ctx->tlli,
parse_ctx->imsi,
parse_ctx->imsi_len, now);
/* Setup TLLIs */
sgsn_tlli = gbproxy_make_sgsn_tlli(peer, tlli_info,
parse_ctx->tlli);
tlli_info->sgsn_tlli.current = sgsn_tlli;
} else {
sgsn_tlli = gbproxy_map_tlli(parse_ctx->tlli, tlli_info, 0);
if (!sgsn_tlli)
sgsn_tlli = gbproxy_make_sgsn_tlli(peer, tlli_info,
parse_ctx->tlli);
gbproxy_validate_tlli(&tlli_info->tlli,
parse_ctx->tlli, 0);
gbproxy_validate_tlli(&tlli_info->sgsn_tlli,
sgsn_tlli, 0);
gbproxy_touch_tlli(peer, tlli_info, now);
}
} else if (tlli_info) {
gbproxy_touch_tlli(peer, tlli_info, now);
}
if (parse_ctx->imsi && tlli_info && tlli_info->mi_data_len == 0) {
int enable_patching;
gbproxy_update_tlli_info(tlli_info,
parse_ctx->imsi, parse_ctx->imsi_len);
/* Check, whether the IMSI matches */
enable_patching = gbproxy_check_imsi(peer, parse_ctx->imsi,
parse_ctx->imsi_len);
if (enable_patching >= 0)
tlli_info->enable_patching = enable_patching;
}
return tlli_info;
}
struct gbproxy_tlli_info *gbproxy_update_tlli_state_dl(
struct gbproxy_peer *peer,
time_t now,
struct gprs_gb_parse_context *parse_ctx)
{
struct gbproxy_tlli_info *tlli_info = NULL;
if (parse_ctx->tlli_enc)
tlli_info = gbproxy_find_tlli_by_sgsn_tlli(peer, parse_ctx->tlli);
if (parse_ctx->tlli_enc && parse_ctx->new_ptmsi_enc) {
/* A new PTMSI has been signaled in the message,
* register new TLLI */
uint32_t new_sgsn_ptmsi;
uint32_t new_sgsn_tlli;
uint32_t new_bss_ptmsi;
uint32_t new_bss_tlli = 0;
if (!gprs_parse_mi_tmsi(parse_ctx->new_ptmsi_enc, GSM48_TMSI_LEN,
&new_sgsn_ptmsi)) {
LOGP(DGPRS, LOGL_ERROR,
"Failed to parse new TLLI/PTMSI (current is %08x)\n",
parse_ctx->tlli);
return tlli_info;
}
new_sgsn_tlli = gprs_tmsi2tlli(new_sgsn_ptmsi, TLLI_LOCAL);
new_bss_ptmsi = gbproxy_make_bss_ptmsi(peer, new_sgsn_ptmsi);
if (new_bss_ptmsi != GSM_RESERVED_TMSI)
new_bss_tlli = gprs_tmsi2tlli(new_bss_ptmsi, TLLI_LOCAL);
LOGP(DGPRS, LOGL_INFO,
"Got new TLLI(PTMSI) %08x(%08x) from SGSN, using %08x(%08x)\n",
new_sgsn_tlli, new_sgsn_ptmsi, new_bss_tlli, new_bss_ptmsi);
if (tlli_info) {
gbproxy_reassign_tlli(&tlli_info->sgsn_tlli,
peer, new_sgsn_tlli);
gbproxy_reassign_tlli(&tlli_info->tlli,
peer, new_bss_tlli);
gbproxy_touch_tlli(peer, tlli_info, now);
} else {
tlli_info = gbproxy_tlli_info_alloc(peer);
LOGP(DGPRS, LOGL_INFO,
"Adding TLLI %08x to list (SGSN, new P-TMSI)\n",
new_sgsn_tlli);
gbproxy_attach_tlli_info(peer, now, tlli_info);
/* Setup TLLIs */
tlli_info->sgsn_tlli.current = new_sgsn_tlli;
}
/* Setup PTMSIs */
tlli_info->sgsn_tlli.ptmsi = new_sgsn_ptmsi;
tlli_info->tlli.ptmsi = new_bss_ptmsi;
} else if (parse_ctx->tlli_enc && parse_ctx->llc && !tlli_info) {
/* Unknown SGSN TLLI */
tlli_info = gbproxy_tlli_info_alloc(peer);
LOGP(DGPRS, LOGL_INFO, "Adding TLLI %08x to list (SGSN)\n",
parse_ctx->tlli);
gbproxy_attach_tlli_info(peer, now, tlli_info);
/* Setup TLLIs */
tlli_info->sgsn_tlli.current = parse_ctx->tlli;
if (peer->cfg->patch_ptmsi) {
/* TODO: We don't know the local TLLI here, perhaps add
* a workaround that derives a PTMSI from the SGSN TLLI
* and use that to get the missing values. This may
* only happen when the gbproxy has been restarted or a
* tlli_info has been discarded due to age or queue
* length.
*/
tlli_info->tlli.current = 0;
} else {
tlli_info->tlli.current = tlli_info->sgsn_tlli.current;
}
} else if (parse_ctx->tlli_enc && parse_ctx->llc && tlli_info) {
uint32_t bss_tlli = gbproxy_map_tlli(parse_ctx->tlli,
tlli_info, 1);
gbproxy_validate_tlli(&tlli_info->sgsn_tlli, parse_ctx->tlli, 1);
gbproxy_validate_tlli(&tlli_info->tlli, bss_tlli, 1);
gbproxy_touch_tlli(peer, tlli_info, now);
} else if (tlli_info) {
gbproxy_touch_tlli(peer, tlli_info, now);
}
if (parse_ctx->imsi && tlli_info && tlli_info->mi_data_len == 0) {
int enable_patching;
gbproxy_update_tlli_info(tlli_info,
parse_ctx->imsi, parse_ctx->imsi_len);
/* Check, whether the IMSI matches */
enable_patching = gbproxy_check_imsi(peer, parse_ctx->imsi,
parse_ctx->imsi_len);
if (enable_patching >= 0)
tlli_info->enable_patching = enable_patching;
}
return tlli_info;
}
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)
{
if (parse_ctx->invalidate_tlli)
gbproxy_unregister_tlli(peer, parse_ctx->tlli);
gbproxy_remove_stale_tllis(peer, now);
}

View File

@ -104,6 +104,11 @@ static int config_write_gbproxy(struct vty *vty)
else
vty_out(vty, "%s", VTY_NEWLINE);
}
if (g_cfg->patch_ptmsi > 0)
vty_out(vty, " patch-ptmsi%s",
VTY_NEWLINE);
if (g_cfg->tlli_max_age > 0)
vty_out(vty, " tlli-list max-age %d%s",
g_cfg->tlli_max_age, VTY_NEWLINE);
@ -193,7 +198,7 @@ static int set_core_apn(struct vty *vty, const char *apn, const char *filter)
talloc_free(g_cfg->core_apn);
g_cfg->core_apn = NULL;
g_cfg->core_apn_size = 0;
gbprox_clear_patch_filter(g_cfg);
gbproxy_clear_patch_filter(g_cfg);
return CMD_SUCCESS;
}
@ -206,8 +211,8 @@ static int set_core_apn(struct vty *vty, const char *apn, const char *filter)
}
if (!filter) {
gbprox_clear_patch_filter(g_cfg);
} else if (gbprox_set_patch_filter(g_cfg, filter, &err_msg) != 0) {
gbproxy_clear_patch_filter(g_cfg);
} else if (gbproxy_set_patch_filter(g_cfg, filter, &err_msg) != 0) {
vty_out(vty, "Match expression invalid: %s%s",
err_msg, VTY_NEWLINE);
return CMD_WARNING;
@ -268,6 +273,28 @@ DEFUN(cfg_gbproxy_no_core_apn,
return set_core_apn(vty, NULL, NULL);
}
#define GBPROXY_PATCH_PTMSI_STR "Patch P-TMSI/TLLI\n"
DEFUN(cfg_gbproxy_patch_ptmsi,
cfg_gbproxy_patch_ptmsi_cmd,
"patch-ptmsi",
GBPROXY_PATCH_PTMSI_STR)
{
g_cfg->patch_ptmsi = 1;
return CMD_SUCCESS;
}
DEFUN(cfg_gbproxy_no_patch_ptmsi,
cfg_gbproxy_no_patch_ptmsi_cmd,
"no patch-ptmsi",
NO_STR GBPROXY_PATCH_PTMSI_STR)
{
g_cfg->patch_ptmsi = 0;
return CMD_SUCCESS;
}
#define GBPROXY_TLLI_LIST_STR "Set TLLI list parameters\n"
#define GBPROXY_MAX_AGE_STR "Limit maximum age\n"
@ -377,7 +404,7 @@ DEFUN(show_gbproxy_tllis, show_gbproxy_tllis_cmd, "show gbproxy tllis",
snprintf(mi_buf, sizeof(mi_buf), "(none)");
}
vty_out(vty, " TLLI %08x, IMSI %s, AGE %d%s",
tlli_info->tlli, mi_buf, (int)age,
tlli_info->tlli.current, mi_buf, (int)age,
VTY_NEWLINE);
}
}
@ -395,7 +422,7 @@ DEFUN(delete_gb_bvci, delete_gb_bvci_cmd,
const uint16_t bvci = atoi(argv[1]);
int counter;
counter = gbprox_cleanup_peers(g_cfg, nsei, bvci);
counter = gbproxy_cleanup_peers(g_cfg, nsei, bvci);
if (counter == 0) {
vty_out(vty, "BVC not found%s", VTY_NEWLINE);
@ -431,7 +458,7 @@ DEFUN(delete_gb_nsei, delete_gb_nsei_cmd,
if (delete_bvc) {
if (!dry_run)
counter = gbprox_cleanup_peers(g_cfg, nsei, 0);
counter = gbproxy_cleanup_peers(g_cfg, nsei, 0);
else {
struct gbproxy_peer *peer;
counter = 0;
@ -514,7 +541,7 @@ DEFUN(delete_gb_tlli, delete_gb_tlli_cmd,
break;
}
peer = gbprox_peer_by_nsei(g_cfg, nsei);
peer = gbproxy_peer_by_nsei(g_cfg, nsei);
if (!peer) {
vty_out(vty, "Didn't find peer with NSEI %d%s",
nsei, VTY_NEWLINE);
@ -524,7 +551,7 @@ DEFUN(delete_gb_tlli, delete_gb_tlli_cmd,
state = &peer->patch_state;
if (match == MATCH_STALE) {
found = gbprox_remove_stale_tllis(peer, time(NULL));
found = gbproxy_remove_stale_tllis(peer, time(NULL));
if (found)
vty_out(vty, "Deleted %d stale TLLI%s%s",
found, found == 1 ? "" : "s", VTY_NEWLINE);
@ -532,7 +559,7 @@ DEFUN(delete_gb_tlli, delete_gb_tlli_cmd,
}
llist_for_each_entry_safe(tlli_info, nxt, &state->enabled_tllis, list) {
if (match == MATCH_TLLI && tlli_info->tlli != tlli)
if (match == MATCH_TLLI && tlli_info->tlli.current != tlli)
continue;
if (match == MATCH_IMSI) {
@ -544,8 +571,9 @@ DEFUN(delete_gb_tlli, delete_gb_tlli_cmd,
if (strcmp(mi_buf, imsi) != 0)
continue;
}
vty_out(vty, "Deleting TLLI %08x%s", tlli_info->tlli, VTY_NEWLINE);
gbprox_delete_tlli(peer, tlli_info);
vty_out(vty, "Deleting TLLI %08x%s", tlli_info->tlli.current,
VTY_NEWLINE);
gbproxy_delete_tlli(peer, tlli_info);
found += 1;
}
@ -574,11 +602,13 @@ int gbproxy_vty_init(void)
install_element(GBPROXY_NODE, &cfg_gbproxy_core_mnc_cmd);
install_element(GBPROXY_NODE, &cfg_gbproxy_core_apn_cmd);
install_element(GBPROXY_NODE, &cfg_gbproxy_core_apn_match_cmd);
install_element(GBPROXY_NODE, &cfg_gbproxy_patch_ptmsi_cmd);
install_element(GBPROXY_NODE, &cfg_gbproxy_tlli_list_max_age_cmd);
install_element(GBPROXY_NODE, &cfg_gbproxy_tlli_list_max_len_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_no_core_apn_cmd);
install_element(GBPROXY_NODE, &cfg_gbproxy_no_patch_ptmsi_cmd);
install_element(GBPROXY_NODE, &cfg_gbproxy_tlli_list_no_max_age_cmd);
install_element(GBPROXY_NODE, &cfg_gbproxy_tlli_list_no_max_len_cmd);
install_element(GBPROXY_NODE, &cfg_gbproxy_patch_mode_cmd);

View File

@ -0,0 +1,642 @@
/* GPRS Gb message parser */
/* (C) 2014 by On-Waves
* All Rights Reserved
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#include <openbsc/gprs_gb_parse.h>
#include <openbsc/gprs_utils.h>
#include <openbsc/gsm_04_08_gprs.h>
#include <openbsc/gsm_data_shared.h>
#include <openbsc/debug.h>
#include <osmocom/gprs/gprs_bssgp.h>
/* TODO: Move shift functions to libosmocore */
int v_fixed_shift(uint8_t **data, size_t *data_len,
size_t len, uint8_t **value)
{
if (len > *data_len)
goto fail;
if (value)
*value = *data;
*data += len;
*data_len -= len;
return len;
fail:
*data += *data_len;
*data_len = 0;
return -1;
}
int tv_fixed_match(uint8_t **data, size_t *data_len,
uint8_t tag, size_t len,
uint8_t **value)
{
size_t ie_len;
if (*data_len == 0)
goto fail;
if ((*data)[0] != tag)
return 0;
if (len > *data_len - 1)
goto fail;
if (value)
*value = *data + 1;
ie_len = len + 1;
*data += ie_len;
*data_len -= ie_len;
return ie_len;
fail:
*data += *data_len;
*data_len = 0;
return -1;
}
int tlv_match(uint8_t **data, size_t *data_len,
uint8_t tag, uint8_t **value, size_t *value_len)
{
size_t len;
size_t ie_len;
if (*data_len < 2)
goto fail;
if ((*data)[0] != tag)
return 0;
len = (*data)[1];
if (len > *data_len - 2)
goto fail;
if (value)
*value = *data + 2;
if (value_len)
*value_len = len;
ie_len = len + 2;
*data += ie_len;
*data_len -= ie_len;
return ie_len;
fail:
*data += *data_len;
*data_len = 0;
return -1;
}
int lv_shift(uint8_t **data, size_t *data_len,
uint8_t **value, size_t *value_len)
{
size_t len;
size_t ie_len;
if (*data_len < 1)
goto fail;
len = (*data)[0];
if (len > *data_len - 1)
goto fail;
if (value)
*value = *data + 1;
if (value_len)
*value_len = len;
ie_len = len + 1;
*data += ie_len;
*data_len -= ie_len;
return ie_len;
fail:
*data += *data_len;
*data_len = 0;
return -1;
}
static int gprs_gb_parse_gmm_attach_req(uint8_t *data, size_t data_len,
struct gprs_gb_parse_context *parse_ctx)
{
uint8_t *value;
size_t value_len;
parse_ctx->llc_msg_name = "ATTACH_REQ";
/* Skip MS network capability */
if (lv_shift(&data, &data_len, NULL, &value_len) <= 0 ||
value_len < 1 || value_len > 2)
/* invalid */
return 0;;
/* Skip Attach type */
/* Skip Ciphering key sequence number */
/* Skip DRX parameter */
v_fixed_shift(&data, &data_len, 3, NULL);
/* Get Mobile identity */
if (lv_shift(&data, &data_len, &value, &value_len) <= 0 ||
value_len < 5 || value_len > 8)
/* invalid */
return 0;
if (gprs_is_mi_tmsi(value, value_len)) {
parse_ctx->ptmsi_enc = value;
} else if (gprs_is_mi_imsi(value, value_len)) {
parse_ctx->imsi = value;
parse_ctx->imsi_len = value_len;
}
if (v_fixed_shift(&data, &data_len, 6, &value) <= 0)
return 0;
parse_ctx->old_raid_enc = value;
return 1;
}
static int gprs_gb_parse_gmm_attach_ack(uint8_t *data, size_t data_len,
struct gprs_gb_parse_context *parse_ctx)
{
uint8_t *value;
size_t value_len;
parse_ctx->llc_msg_name = "ATTACH_ACK";
/* Skip Attach result */
/* Skip Force to standby */
/* Skip Periodic RA update timer */
/* Skip Radio priority for SMS */
/* Skip Spare half octet */
v_fixed_shift(&data, &data_len, 3, NULL);
if (v_fixed_shift(&data, &data_len, 6, &value) <= 0)
return 0;
parse_ctx->raid_enc = value;
/* Skip P-TMSI signature (P-TMSI signature, opt, TV, length 4) */
tv_fixed_match(&data, &data_len, GSM48_IE_GMM_PTMSI_SIG, 3, NULL);
/* Skip Negotiated READY timer value (GPRS timer, opt, TV, length 2) */
tv_fixed_match(&data, &data_len, GSM48_IE_GMM_TIMER_READY, 1, NULL);
/* Allocated P-TMSI (Mobile identity, opt, TLV, length 7) */
if (tlv_match(&data, &data_len, GSM48_IE_GMM_ALLOC_PTMSI,
&value, &value_len) > 0 &&
gprs_is_mi_tmsi(value, value_len))
parse_ctx->new_ptmsi_enc = value;
return 1;
}
static int gprs_gb_parse_gmm_detach_req(uint8_t *data, size_t data_len,
struct gprs_gb_parse_context *parse_ctx)
{
uint8_t *value;
size_t value_len;
int detach_type;
int power_off;
parse_ctx->llc_msg_name = "DETACH_REQ";
/* Skip spare half octet */
/* Get Detach type */
if (v_fixed_shift(&data, &data_len, 1, &value) <= 0)
/* invalid */
return 0;
detach_type = *value & 0x07;
power_off = *value & 0x08 ? 1 : 0;
if (!parse_ctx->to_bss) {
/* Mobile originated */
if (power_off)
parse_ctx->invalidate_tlli = 1;
/* Get P-TMSI (Mobile identity), see GSM 24.008, 9.4.5.2 */
if (tlv_match(&data, &data_len,
GSM48_IE_GMM_ALLOC_PTMSI, &value, &value_len) > 0)
{
if (gprs_is_mi_tmsi(value, value_len))
parse_ctx->ptmsi_enc = value;
}
}
return 1;
}
static int gprs_gb_parse_gmm_ra_upd_req(uint8_t *data, size_t data_len,
struct gprs_gb_parse_context *parse_ctx)
{
uint8_t *value;
parse_ctx->llc_msg_name = "RA_UPD_REQ";
/* Skip Update type */
/* Skip GPRS ciphering key sequence number */
v_fixed_shift(&data, &data_len, 1, NULL);
if (v_fixed_shift(&data, &data_len, 6, &value) <= 0)
return 0;
parse_ctx->old_raid_enc = value;
return 1;
}
static int gprs_gb_parse_gmm_ra_upd_ack(uint8_t *data, size_t data_len,
struct gprs_gb_parse_context *parse_ctx)
{
uint8_t *value;
size_t value_len;
parse_ctx->llc_msg_name = "RA_UPD_ACK";
/* Skip Force to standby */
/* Skip Update result */
/* Skip Periodic RA update timer */
v_fixed_shift(&data, &data_len, 2, NULL);
if (v_fixed_shift(&data, &data_len, 6, &value) <= 0)
return 0;
parse_ctx->raid_enc = value;
/* Skip P-TMSI signature (P-TMSI signature, opt, TV, length 4) */
tv_fixed_match(&data, &data_len, GSM48_IE_GMM_PTMSI_SIG, 3, NULL);
/* Allocated P-TMSI (Mobile identity, opt, TLV, length 7) */
if (tlv_match(&data, &data_len, GSM48_IE_GMM_ALLOC_PTMSI,
&value, &value_len) > 0 &&
gprs_is_mi_tmsi(value, value_len))
parse_ctx->new_ptmsi_enc = value;
return 1;
}
static int gprs_gb_parse_gmm_ptmsi_reall_cmd(uint8_t *data, size_t data_len,
struct gprs_gb_parse_context *parse_ctx)
{
uint8_t *value;
size_t value_len;
parse_ctx->llc_msg_name = "PTMSI_REALL_CMD";
LOGP(DLLC, LOGL_NOTICE,
"Got P-TMSI Reallocation Command which is not covered by unit tests yet.\n");
/* Allocated P-TMSI */
if (lv_shift(&data, &data_len, &value, &value_len) > 0 &&
gprs_is_mi_tmsi(value, value_len))
parse_ctx->new_ptmsi_enc = value;
if (v_fixed_shift(&data, &data_len, 6, &value) <= 0)
return 0;
parse_ctx->raid_enc = value;
return 1;
}
static int gprs_gb_parse_gmm_id_resp(uint8_t *data, size_t data_len,
struct gprs_gb_parse_context *parse_ctx)
{
uint8_t *value;
size_t value_len;
parse_ctx->llc_msg_name = "ID_RESP";
/* Mobile identity, Mobile identity 10.5.1.4, M LV 2-10 */
if (lv_shift(&data, &data_len, &value, &value_len) <= 0 ||
value_len < 1 || value_len > 9)
/* invalid */
return 0;
if (gprs_is_mi_tmsi(value, value_len)) {
parse_ctx->ptmsi_enc = value;
} else if (gprs_is_mi_imsi(value, value_len)) {
parse_ctx->imsi = value;
parse_ctx->imsi_len = value_len;
}
return 1;
}
static int gprs_gb_parse_gsm_act_pdp_req(uint8_t *data, size_t data_len,
struct gprs_gb_parse_context *parse_ctx)
{
ssize_t old_len;
uint8_t *value;
size_t value_len;
parse_ctx->llc_msg_name = "ACT_PDP_REQ";
/* Skip Requested NSAPI */
/* Skip Requested LLC SAPI */
v_fixed_shift(&data, &data_len, 2, NULL);
/* Skip Requested QoS (support 04.08 and 24.008) */
if (lv_shift(&data, &data_len, NULL, &value_len) <= 0 ||
value_len < 4 || value_len > 14)
/* invalid */
return 0;;
/* Skip Requested PDP address */
if (lv_shift(&data, &data_len, NULL, &value_len) <= 0 ||
value_len < 2 || value_len > 18)
/* invalid */
return 0;
/* Access point name */
old_len = tlv_match(&data, &data_len,
GSM48_IE_GSM_APN, &value, &value_len);
if (old_len > 0 && value_len >=1 && value_len <= 100) {
parse_ctx->apn_ie = data - old_len;
parse_ctx->apn_ie_len = old_len;
}
return 1;
}
int gprs_gb_parse_dtap(uint8_t *data, size_t data_len,
struct gprs_gb_parse_context *parse_ctx)
{
struct gsm48_hdr *g48h;
if (v_fixed_shift(&data, &data_len, sizeof(*g48h), (uint8_t **)&g48h) <= 0)
return 0;
parse_ctx->g48_hdr = g48h;
if ((g48h->proto_discr & 0x0f) != GSM48_PDISC_MM_GPRS &&
(g48h->proto_discr & 0x0f) != GSM48_PDISC_SM_GPRS)
return 1;
switch (g48h->msg_type) {
case GSM48_MT_GMM_ATTACH_REQ:
return gprs_gb_parse_gmm_attach_req(data, data_len, parse_ctx);
case GSM48_MT_GMM_ATTACH_ACK:
return gprs_gb_parse_gmm_attach_ack(data, data_len, parse_ctx);
case GSM48_MT_GMM_RA_UPD_REQ:
return gprs_gb_parse_gmm_ra_upd_req(data, data_len, parse_ctx);
case GSM48_MT_GMM_RA_UPD_ACK:
return gprs_gb_parse_gmm_ra_upd_ack(data, data_len, parse_ctx);
case GSM48_MT_GMM_PTMSI_REALL_CMD:
return gprs_gb_parse_gmm_ptmsi_reall_cmd(data, data_len, parse_ctx);
case GSM48_MT_GSM_ACT_PDP_REQ:
return gprs_gb_parse_gsm_act_pdp_req(data, data_len, parse_ctx);
case GSM48_MT_GMM_ID_RESP:
return gprs_gb_parse_gmm_id_resp(data, data_len, parse_ctx);
case GSM48_MT_GMM_DETACH_REQ:
return gprs_gb_parse_gmm_detach_req(data, data_len, parse_ctx);
case GSM48_MT_GMM_DETACH_ACK:
parse_ctx->llc_msg_name = "DETACH_ACK";
parse_ctx->invalidate_tlli = 1;
break;
default:
break;
};
return 1;
}
int gprs_gb_parse_llc(uint8_t *llc, size_t llc_len,
struct gprs_gb_parse_context *parse_ctx)
{
struct gprs_llc_hdr_parsed *ghp = &parse_ctx->llc_hdr_parsed;
int rc;
int fcs;
/* 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 0;
}
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 0;
if (ghp->sapi != GPRS_SAPI_GMM)
return 1;
if (ghp->cmd != GPRS_LLC_UI)
return 1;
if (ghp->is_encrypted) {
parse_ctx->need_decryption = 1;
return 0;
}
return gprs_gb_parse_dtap(ghp->data, ghp->data_len, parse_ctx);
}
int gprs_gb_parse_bssgp(uint8_t *bssgp, size_t bssgp_len,
struct gprs_gb_parse_context *parse_ctx)
{
struct bssgp_normal_hdr *bgph;
struct bssgp_ud_hdr *budh = NULL;
struct tlv_parsed *tp = &parse_ctx->bssgp_tp;
uint8_t pdu_type;
uint8_t *data;
size_t data_len;
int rc;
if (bssgp_len < sizeof(struct bssgp_normal_hdr))
return 0;
bgph = (struct bssgp_normal_hdr *)bssgp;
pdu_type = bgph->pdu_type;
if (pdu_type == BSSGP_PDUT_UL_UNITDATA ||
pdu_type == BSSGP_PDUT_DL_UNITDATA) {
if (bssgp_len < sizeof(struct bssgp_ud_hdr))
return 0;
budh = (struct bssgp_ud_hdr *)bssgp;
bgph = NULL;
data = budh->data;
data_len = bssgp_len - sizeof(*budh);
} else {
data = bgph->data;
data_len = bssgp_len - sizeof(*bgph);
}
if (bssgp_tlv_parse(tp, data, data_len) < 0)
return 0;
parse_ctx->pdu_type = pdu_type;
parse_ctx->bud_hdr = budh;
parse_ctx->bgp_hdr = bgph;
parse_ctx->bssgp_data = data;
parse_ctx->bssgp_data_len = data_len;
if (budh)
parse_ctx->tlli_enc = (uint8_t *)&budh->tlli;
if (TLVP_PRESENT(tp, BSSGP_IE_ROUTEING_AREA))
parse_ctx->bssgp_raid_enc = (uint8_t *)TLVP_VAL(tp, BSSGP_IE_ROUTEING_AREA);
if (TLVP_PRESENT(tp, BSSGP_IE_CELL_ID))
parse_ctx->bssgp_raid_enc = (uint8_t *)TLVP_VAL(tp, BSSGP_IE_CELL_ID);
if (TLVP_PRESENT(tp, BSSGP_IE_IMSI)) {
parse_ctx->imsi = (uint8_t *)TLVP_VAL(tp, BSSGP_IE_IMSI);
parse_ctx->imsi_len = TLVP_LEN(tp, BSSGP_IE_IMSI);
}
/* TODO: This is TLLI old, don't confuse with TLLI current, add
* and use tlli_old_enc instead */
if (0 && TLVP_PRESENT(tp, BSSGP_IE_TLLI))
parse_ctx->tlli_enc = (uint8_t *)TLVP_VAL(tp, BSSGP_IE_TLLI);
if (TLVP_PRESENT(tp, BSSGP_IE_TMSI) && pdu_type == BSSGP_PDUT_PAGING_PS)
parse_ctx->ptmsi_enc = (uint8_t *)TLVP_VAL(tp, BSSGP_IE_TMSI);
if (TLVP_PRESENT(tp, BSSGP_IE_LLC_PDU)) {
uint8_t *llc = (uint8_t *)TLVP_VAL(tp, BSSGP_IE_LLC_PDU);
size_t llc_len = TLVP_LEN(tp, BSSGP_IE_LLC_PDU);
rc = gprs_gb_parse_llc(llc, llc_len, parse_ctx);
if (!rc)
return 0;
parse_ctx->llc = llc;
parse_ctx->llc_len = llc_len;
}
if (parse_ctx->tlli_enc) {
uint32_t tmp_tlli;
memcpy(&tmp_tlli, parse_ctx->tlli_enc, sizeof(tmp_tlli));
parse_ctx->tlli = ntohl(tmp_tlli);
}
return 1;
}
void gprs_gb_log_parse_context(struct gprs_gb_parse_context *parse_ctx,
const char *default_msg_name)
{
const char *msg_name = default_msg_name;
const char *sep = "";
if (!parse_ctx->tlli_enc &&
!parse_ctx->ptmsi_enc &&
!parse_ctx->new_ptmsi_enc &&
!parse_ctx->imsi)
return;
if (parse_ctx->llc_msg_name)
msg_name = parse_ctx->llc_msg_name;
LOGP(DGPRS, LOGL_DEBUG, "%s: Got", msg_name);
if (parse_ctx->tlli_enc) {
LOGP(DGPRS, LOGL_DEBUG, "%s TLLI %08x", sep, parse_ctx->tlli);
sep = ",";
}
if (parse_ctx->bssgp_raid_enc) {
struct gprs_ra_id raid;
gsm48_parse_ra(&raid, parse_ctx->bssgp_raid_enc);
LOGP(DGPRS, LOGL_DEBUG, "%s BSSGP RAID %u-%u-%u-%u", sep,
raid.mcc, raid.mnc, raid.lac, raid.rac);
sep = ",";
}
if (parse_ctx->raid_enc) {
struct gprs_ra_id raid;
gsm48_parse_ra(&raid, parse_ctx->raid_enc);
LOGP(DGPRS, LOGL_DEBUG, "%s RAID %u-%u-%u-%u", sep,
raid.mcc, raid.mnc, raid.lac, raid.rac);
sep = ",";
}
if (parse_ctx->old_raid_enc) {
struct gprs_ra_id raid;
gsm48_parse_ra(&raid, parse_ctx->old_raid_enc);
LOGP(DGPRS, LOGL_DEBUG, "%s old RAID %u-%u-%u-%u", sep,
raid.mcc, raid.mnc, raid.lac, raid.rac);
sep = ",";
}
if (parse_ctx->ptmsi_enc) {
uint32_t ptmsi = GSM_RESERVED_TMSI;
int ok;
ok = gprs_parse_mi_tmsi(parse_ctx->ptmsi_enc, GSM48_TMSI_LEN, &ptmsi);
LOGP(DGPRS, LOGL_DEBUG, "%s PTMSI %08x%s",
sep, ptmsi, ok ? "" : " (parse error)");
sep = ",";
}
if (parse_ctx->new_ptmsi_enc) {
uint32_t new_ptmsi = GSM_RESERVED_TMSI;
int ok;
ok = gprs_parse_mi_tmsi(parse_ctx->new_ptmsi_enc, GSM48_TMSI_LEN,
&new_ptmsi);
LOGP(DGPRS, LOGL_DEBUG, "%s new PTMSI %08x%s",
sep, new_ptmsi, ok ? "" : " (parse error)");
sep = ",";
}
if (parse_ctx->imsi) {
char mi_buf[200];
mi_buf[0] = '\0';
gsm48_mi_to_string(mi_buf, sizeof(mi_buf),
parse_ctx->imsi, parse_ctx->imsi_len);
LOGP(DGPRS, LOGL_DEBUG, "%s IMSI %s",
sep, mi_buf);
sep = ",";
}
if (parse_ctx->invalidate_tlli) {
LOGP(DGPRS, LOGL_DEBUG, "%s invalidate", sep);
sep = ",";
}
LOGP(DGPRS, LOGL_DEBUG, "\n");
}

View File

@ -24,6 +24,8 @@
#include <osmocom/core/msgb.h>
#include <osmocom/gprs/gprs_ns.h>
#include <osmocom/gsm/protocol/gsm_04_08.h>
#include <string.h>
/* FIXME: this needs to go to libosmocore/msgb.c */
@ -162,3 +164,40 @@ int gprs_str_to_apn(uint8_t *apn_enc, size_t max_len, const char *str)
return len;
}
/* GSM 04.08, 10.5.1.4 */
int gprs_is_mi_tmsi(const uint8_t *value, size_t value_len)
{
if (value_len != GSM48_TMSI_LEN)
return 0;
if (!value || (value[0] & GSM_MI_TYPE_MASK) != GSM_MI_TYPE_TMSI)
return 0;
return 1;
}
/* GSM 04.08, 10.5.1.4 */
int gprs_is_mi_imsi(const uint8_t *value, size_t value_len)
{
if (value_len == 0)
return 0;
if (!value || (value[0] & GSM_MI_TYPE_MASK) != GSM_MI_TYPE_IMSI)
return 0;
return 1;
}
int gprs_parse_mi_tmsi(const uint8_t *value, size_t value_len, uint32_t *tmsi)
{
uint32_t tmsi_be;
if (!gprs_is_mi_tmsi(value, value_len))
return 0;
memcpy(&tmsi_be, value + 1, sizeof(tmsi_be));
*tmsi = ntohl(tmsi_be);
return 1;
}

View File

@ -9,6 +9,10 @@ noinst_PROGRAMS = gbproxy_test
gbproxy_test_SOURCES = gbproxy_test.c
gbproxy_test_LDADD = \
$(top_builddir)/src/gprs/gb_proxy.o \
$(top_builddir)/src/gprs/gb_proxy_patch.o \
$(top_builddir)/src/gprs/gb_proxy_peer.o \
$(top_builddir)/src/gprs/gb_proxy_tlli.o \
$(top_builddir)/src/gprs/gprs_gb_parse.o \
$(top_builddir)/src/gprs/gprs_llc_parse.o \
$(top_builddir)/src/gprs/crc24.o \
$(top_builddir)/src/gprs/gprs_utils.o \

File diff suppressed because it is too large Load Diff

View File

@ -1666,10 +1666,10 @@ MESSAGE to SGSN at 0x05060708:32000, msg length 44
result (IDENT RESPONSE) = 44
PROCESSING ATTACH ACCEPT from 0x05060708:32000
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 ef e2 b7 00 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 21 63 54 40 50 60 19 cd d7 08 17 16 18 05 f4 ef e2 b7 00 53 62 f1
CALLBACK, event 0, msg length 88, bvci 0x1002
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 ef e2 b7 00 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 21 63 54 40 50 60 19 cd d7 08 17 16 18 05 f4 ef e2 b7 00 53 62 f1
NS UNITDATA MESSAGE to BSS, BVCI 0x1002, msg length 88 (gprs_ns_sendmsg)
MESSAGE to BSS at 0x01020304:1111, msg length 92
@ -1677,6 +1677,18 @@ MESSAGE to BSS at 0x01020304:1111, msg length 92
result (ATTACH ACCEPT) = 92
PROCESSING ATTACH COMPLETE from 0x01020304:1111
00 00 10 02 01 ef e2 b7 00 00 00 04 08 88 11 22 33 40 50 60 75 30 00 80 0e 00 08 01 c0 11 08 03 ea 67 11
CALLBACK, event 0, msg length 31, bvci 0x1002
00 00 10 02 01 ef e2 b7 00 00 00 04 08 88 11 22 33 40 50 60 75 30 00 80 0e 00 08 01 c0 11 08 03 ea 67 11
NS UNITDATA MESSAGE to SGSN, BVCI 0x1002, msg length 31 (gprs_ns_sendmsg)
MESSAGE to SGSN at 0x05060708:32000, msg length 35
00 00 10 02 01 ef e2 b7 00 00 00 04 08 88 21 63 54 40 50 60 75 30 00 80 0e 00 08 01 c0 11 08 03 ea 67 11
result (ATTACH COMPLETE) = 35
PROCESSING ACT PDP CTX REQ (REPLACE APN) from 0x01020304:1111
00 00 10 02 01 ef e2 b7 00 00 00 04 08 88 11 22 33 40 50 60 75 30 00 80 0e 00 35 01 c0 0d 0a 41 05 03 0c 00 00 1f 10 00 00 00 00 00 00 00 00 02 01 21 28 03 02 61 62 27 14 80 80 21 10 01 00 00 10 81 06 00 00 00 00 83 06 00 00 00 00 5a ff 02
@ -1727,13 +1739,13 @@ result (ACT PDP CTX REQ (REMOVE APN)) = 75
Peers:
NSEI 4096, BVCI 4098, not blocked, RAI 112-332-16464-96
RAID patched (BSS ): 8
RAID patched (BSS ): 9
RAID patched (SGSN): 2
APN patched : 3
Attach Request count : 1
TLLI cache size : 1
TLLI-Cache: 1
TLLI efe2b700, IMSI 12131415161718, AGE 0
TLLI efe2b700 -> efe2b700, IMSI 12131415161718, AGE 0
PROCESSING DETACH REQ from 0x01020304:1111
00 00 10 02 01 ef e2 b7 00 00 00 04 08 88 11 22 33 40 50 60 75 30 00 80 0e 00 15 01 c0 19 08 05 01 18 05 f4 ef e2 b7 00 19 03 b9 97 cb 7e e1 41
@ -1760,7 +1772,7 @@ result (DETACH ACC) = 71
Peers:
NSEI 4096, BVCI 4098, not blocked, RAI 112-332-16464-96
RAID patched (BSS ): 9
RAID patched (BSS ): 10
RAID patched (SGSN): 2
APN patched : 3
Attach Request count : 1
@ -1780,16 +1792,16 @@ MESSAGE to SGSN at 0x05060708:32000, msg length 89
result (RA UPD REQ) = 89
PROCESSING RA UPD ACC from 0x05060708:32000
00 00 10 02 00 bb c5 46 79 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 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 9d 41 c0 19 08 09 00 49 21 63 54 40 50 60 19 54 ab b3 18 05 f4 ef e2 b7 00 17 16 d7 59 65
CALLBACK, event 0, msg length 91, bvci 0x1002
00 00 10 02 00 bb c5 46 79 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
CALLBACK, event 0, msg length 87, bvci 0x1002
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 9d 41 c0 19 08 09 00 49 21 63 54 40 50 60 19 54 ab b3 18 05 f4 ef e2 b7 00 17 16 d7 59 65
NS UNITDATA MESSAGE to BSS, BVCI 0x1002, msg length 91 (gprs_ns_sendmsg)
MESSAGE to BSS at 0x01020304:1111, msg length 95
00 00 10 02 00 bb c5 46 79 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
NS UNITDATA MESSAGE to BSS, BVCI 0x1002, msg length 87 (gprs_ns_sendmsg)
MESSAGE to BSS at 0x01020304:1111, msg length 91
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 9d 41 c0 19 08 09 00 49 11 22 33 40 50 60 19 54 ab b3 18 05 f4 ef e2 b7 00 17 16 3a 03 54
result (RA UPD ACC) = 95
result (RA UPD ACC) = 91
PROCESSING ACT PDP CTX REQ (REMOVE APN) from 0x01020304:1111
00 00 10 02 01 ef e2 b7 00 00 00 04 08 88 11 22 33 40 50 60 75 30 00 80 0e 00 35 01 c0 0d 0a 41 05 03 0c 00 00 1f 10 00 00 00 00 00 00 00 00 02 01 21 28 03 02 61 62 27 14 80 80 21 10 01 00 00 10 81 06 00 00 00 00 83 06 00 00 00 00 5a ff 02
@ -1797,56 +1809,41 @@ PROCESSING ACT PDP CTX REQ (REMOVE APN) from 0x01020304:1111
CALLBACK, event 0, msg length 76, bvci 0x1002
00 00 10 02 01 ef e2 b7 00 00 00 04 08 88 11 22 33 40 50 60 75 30 00 80 0e 00 35 01 c0 0d 0a 41 05 03 0c 00 00 1f 10 00 00 00 00 00 00 00 00 02 01 21 28 03 02 61 62 27 14 80 80 21 10 01 00 00 10 81 06 00 00 00 00 83 06 00 00 00 00 5a ff 02
NS UNITDATA MESSAGE to SGSN, BVCI 0x1002, msg length 76 (gprs_ns_sendmsg)
MESSAGE to SGSN at 0x05060708:32000, msg length 80
00 00 10 02 01 ef e2 b7 00 00 00 04 08 88 21 63 54 40 50 60 75 30 00 80 0e 00 35 01 c0 0d 0a 41 05 03 0c 00 00 1f 10 00 00 00 00 00 00 00 00 02 01 21 28 03 02 61 62 27 14 80 80 21 10 01 00 00 10 81 06 00 00 00 00 83 06 00 00 00 00 5a ff 02
NS UNITDATA MESSAGE to SGSN, BVCI 0x1002, msg length 71 (gprs_ns_sendmsg)
MESSAGE to SGSN at 0x05060708:32000, msg length 75
00 00 10 02 01 ef e2 b7 00 00 00 04 08 88 21 63 54 40 50 60 75 30 00 80 0e 00 30 01 c0 0d 0a 41 05 03 0c 00 00 1f 10 00 00 00 00 00 00 00 00 02 01 21 27 14 80 80 21 10 01 00 00 10 81 06 00 00 00 00 83 06 00 00 00 00 85 fa 60
result (ACT PDP CTX REQ (REMOVE APN)) = 80
result (ACT PDP CTX REQ (REMOVE APN)) = 75
Peers:
NSEI 4096, BVCI 4098, not blocked, RAI 112-332-16464-96
RAID patched (BSS ): 12
RAID patched (SGSN): 3
APN patched : 3
Attach Request count : 1
TLLI cache size : 2
TLLI-Cache: 2
TLLI efe2b700, IMSI (none), AGE 0
TLLI efe28117, IMSI 12131415161718, AGE 0
PROCESSING DETACH REQ from 0x01020304:1111
00 00 10 02 01 ef e2 b7 00 00 00 04 08 88 11 22 33 40 50 60 75 30 00 80 0e 00 15 01 c0 19 08 05 01 18 05 f4 ef e2 b7 00 19 03 b9 97 cb 7e e1 41
CALLBACK, event 0, msg length 44, bvci 0x1002
00 00 10 02 01 ef e2 b7 00 00 00 04 08 88 11 22 33 40 50 60 75 30 00 80 0e 00 15 01 c0 19 08 05 01 18 05 f4 ef e2 b7 00 19 03 b9 97 cb 7e e1 41
NS UNITDATA MESSAGE to SGSN, BVCI 0x1002, msg length 44 (gprs_ns_sendmsg)
MESSAGE to SGSN at 0x05060708:32000, msg length 48
00 00 10 02 01 ef e2 b7 00 00 00 04 08 88 21 63 54 40 50 60 75 30 00 80 0e 00 15 01 c0 19 08 05 01 18 05 f4 ef e2 b7 00 19 03 b9 97 cb 7e e1 41
result (DETACH REQ) = 48
PROCESSING DETACH ACC from 0x05060708:32000
00 00 10 02 00 ef e2 b7 00 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 89 41 c0 15 08 06 00 f7 35 f0
CALLBACK, event 0, msg length 67, bvci 0x1002
00 00 10 02 00 ef e2 b7 00 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 89 41 c0 15 08 06 00 f7 35 f0
NS UNITDATA MESSAGE to BSS, BVCI 0x1002, msg length 67 (gprs_ns_sendmsg)
MESSAGE to BSS at 0x01020304:1111, msg length 71
00 00 10 02 00 ef e2 b7 00 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 89 41 c0 15 08 06 00 f7 35 f0
result (DETACH ACC) = 71
Gbproxy global:
Peers:
NSEI 4096, BVCI 4098, not blocked, RAI 112-332-16464-96
RAID patched (BSS ): 13
RAID patched (SGSN): 3
APN patched : 3
APN patched : 4
Attach Request count : 1
TLLI cache size : 1
TLLI-Cache: 1
TLLI efe28117, IMSI 12131415161718, AGE 0
TLLI bbc54679/efe2b700 -> bbc54679/efe2b700, IMSI 12131415161718, AGE 0
PROCESSING DETACH REQ (PWR OFF) from 0x01020304:1111
00 00 10 02 01 ef e2 b7 00 00 00 04 08 88 11 22 33 40 50 60 75 30 00 80 0e 00 15 01 c0 19 08 05 09 18 05 f4 ef e2 b7 00 19 03 b9 97 cb 84 0c eb
CALLBACK, event 0, msg length 44, bvci 0x1002
00 00 10 02 01 ef e2 b7 00 00 00 04 08 88 11 22 33 40 50 60 75 30 00 80 0e 00 15 01 c0 19 08 05 09 18 05 f4 ef e2 b7 00 19 03 b9 97 cb 84 0c eb
NS UNITDATA MESSAGE to SGSN, BVCI 0x1002, msg length 44 (gprs_ns_sendmsg)
MESSAGE to SGSN at 0x05060708:32000, msg length 48
00 00 10 02 01 ef e2 b7 00 00 00 04 08 88 21 63 54 40 50 60 75 30 00 80 0e 00 15 01 c0 19 08 05 09 18 05 f4 ef e2 b7 00 19 03 b9 97 cb 84 0c eb
result (DETACH REQ (PWR OFF)) = 48
Gbproxy global:
Peers:
NSEI 4096, BVCI 4098, not blocked, RAI 112-332-16464-96
RAID patched (BSS ): 14
RAID patched (SGSN): 3
APN patched : 4
Attach Request count : 1
TLLI-Cache: 0
--- Bad cases ---
TLLI is already detached, shouldn't patch
@ -1880,14 +1877,391 @@ Gbproxy global:
Patch error: no peer : 1
Peers:
NSEI 4096, BVCI 4098, not blocked, RAI 112-332-16464-96
RAID patched (BSS ): 14
RAID patched (BSS ): 15
RAID patched (SGSN): 3
APN patched : 3
APN patched : 4
Attach Request count : 1
TLLI cache size : 2
TLLI-Cache: 2
TLLI efe2b700, IMSI (none), AGE 0
TLLI efe28117, IMSI 12131415161718, AGE 0
TLLI cache size : 1
TLLI-Cache: 1
TLLI efe2b700 -> efe2b700, IMSI (none), AGE 0
=== test_gbproxy_ptmsi_patching ===
--- Initialise SGSN ---
MESSAGE to SGSN at 0x05060708:32000, msg length 12
02 00 81 01 01 82 01 01 04 82 01 00
PROCESSING RESET_ACK from 0x05060708:32000
03 01 82 01 01 04 82 01 00
MESSAGE to SGSN at 0x05060708:32000, msg length 1
0a
result (RESET_ACK) = 1
PROCESSING ALIVE_ACK from 0x05060708:32000
0b
MESSAGE to SGSN at 0x05060708:32000, msg length 1
06
result (ALIVE_ACK) = 1
PROCESSING UNBLOCK_ACK from 0x05060708:32000
07
==> got signal NS_UNBLOCK, NS-VC 0x0101/5.6.7.8:32000
result (UNBLOCK_ACK) = 0
PROCESSING ALIVE from 0x05060708:32000
0a
MESSAGE to SGSN at 0x05060708:32000, msg length 1
0b
result (ALIVE) = 1
--- Initialise BSS 1 ---
Setup NS-VC: remote 0x01020304:1111, NSVCI 0x1001(4097), NSEI 0x1000(4096)
PROCESSING RESET from 0x01020304:1111
02 00 81 01 01 82 10 01 04 82 10 00
==> got signal NS_RESET, NS-VC 0x1001/1.2.3.4:1111
MESSAGE to BSS at 0x01020304:1111, msg length 9
03 01 82 10 01 04 82 10 00
MESSAGE to BSS at 0x01020304:1111, msg length 1
0a
result (RESET) = 9
PROCESSING ALIVE from 0x01020304:1111
0a
MESSAGE to BSS at 0x01020304:1111, msg length 1
0b
result (ALIVE) = 1
PROCESSING UNBLOCK from 0x01020304:1111
06
==> got signal NS_UNBLOCK, NS-VC 0x1001/1.2.3.4:1111
MESSAGE to BSS at 0x01020304:1111, msg length 1
07
result (UNBLOCK) = 1
PROCESSING ALIVE_ACK from 0x01020304:1111
0b
result (ALIVE_ACK) = 0
Setup BSSGP: remote 0x01020304:1111, BVCI 0x1002(4098)
PROCESSING BVC_RESET from 0x01020304:1111
00 00 00 00 22 04 82 10 02 07 81 08 08 88 11 22 33 40 50 60 10 00
CALLBACK, event 0, msg length 18, bvci 0x0000
00 00 00 00 22 04 82 10 02 07 81 08 08 88 11 22 33 40 50 60 10 00
NS UNITDATA MESSAGE to SGSN, BVCI 0x0000, msg length 18 (gprs_ns_sendmsg)
MESSAGE to SGSN at 0x05060708:32000, msg length 22
00 00 00 00 22 04 82 10 02 07 81 08 08 88 21 63 54 40 50 60 10 00
result (BVC_RESET) = 22
PROCESSING BVC_RESET_ACK from 0x05060708:32000
00 00 00 00 23 04 82 10 02
CALLBACK, event 0, msg length 5, bvci 0x0000
00 00 00 00 23 04 82 10 02
NS UNITDATA MESSAGE to BSS, BVCI 0x0000, msg length 5 (gprs_ns_sendmsg)
MESSAGE to BSS at 0x01020304:1111, msg length 9
00 00 00 00 23 04 82 10 02
result (BVC_RESET_ACK) = 9
PROCESSING BVC_SUSPEND from 0x01020304:1111
00 00 00 00 0b 1f 84 cc d1 75 8b 1b 86 11 22 33 40 50 60
CALLBACK, event 0, msg length 15, bvci 0x0000
00 00 00 00 0b 1f 84 cc d1 75 8b 1b 86 11 22 33 40 50 60
NS UNITDATA MESSAGE to SGSN, BVCI 0x0000, msg length 15 (gprs_ns_sendmsg)
MESSAGE to SGSN at 0x05060708:32000, msg length 19
00 00 00 00 0b 1f 84 cc d1 75 8b 1b 86 21 63 54 40 50 60
result (BVC_SUSPEND) = 19
PROCESSING BVC_SUSPEND_ACK from 0x05060708:32000
00 00 00 00 0c 1f 84 cc d1 75 8b 1b 86 21 63 54 40 50 60 1d 81 01
CALLBACK, event 0, msg length 18, bvci 0x0000
00 00 00 00 0c 1f 84 cc d1 75 8b 1b 86 21 63 54 40 50 60 1d 81 01
NS UNITDATA MESSAGE to BSS, BVCI 0x0000, msg length 18 (gprs_ns_sendmsg)
MESSAGE to BSS at 0x01020304:1111, msg length 22
00 00 00 00 0c 1f 84 cc d1 75 8b 1b 86 11 22 33 40 50 60 1d 81 01
result (BVC_SUSPEND_ACK) = 22
Current NS-VCIs:
VCI 0x1001, NSEI 0x1000, peer 0x01020304:1111
VCI 0x0101, NSEI 0x0100, peer 0x05060708:32000
NS-VC Block count : 1
Gbproxy global:
Peers:
NSEI 4096, BVCI 4098, not blocked, RAI 112-332-16464-96
RAID patched (BSS ): 2
RAID patched (SGSN): 1
TLLI-Cache: 0
--- Send message from BSS 1 to SGSN, BVCI 0x1002 ---
PROCESSING ATTACH REQUEST from 0x01020304:1111
00 00 10 02 01 80 00 de ad 00 00 04 08 88 00 f1 99 00 63 60 12 34 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
CALLBACK, event 0, msg length 75, bvci 0x1002
00 00 10 02 01 80 00 de ad 00 00 04 08 88 00 f1 99 00 63 60 12 34 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 (gprs_ns_sendmsg)
MESSAGE to SGSN at 0x05060708:32000, msg length 79
00 00 10 02 01 7c 69 fb 81 00 00 04 08 88 21 63 54 00 63 60 12 34 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
result (ATTACH REQUEST) = 79
Peers:
NSEI 4096, BVCI 4098, not blocked, RAI 112-332-16464-96
RAID patched (BSS ): 3
RAID patched (SGSN): 1
TLLI patched (BSS ): 1
Attach Request count : 1
TLLI cache size : 1
TLLI-Cache: 1
TLLI 8000dead -> 7c69fb81, IMSI (none), AGE 0
PROCESSING IDENT REQUEST from 0x05060708:32000
00 00 10 02 00 7c 69 fb 81 00 50 20 16 82 02 58 0e 89 41 c0 01 08 15 01 ff 6c ba
CALLBACK, event 0, msg length 23, bvci 0x1002
00 00 10 02 00 7c 69 fb 81 00 50 20 16 82 02 58 0e 89 41 c0 01 08 15 01 ff 6c ba
NS UNITDATA MESSAGE to BSS, BVCI 0x1002, msg length 23 (gprs_ns_sendmsg)
MESSAGE to BSS at 0x01020304:1111, msg length 27
00 00 10 02 00 80 00 de ad 00 50 20 16 82 02 58 0e 89 41 c0 01 08 15 01 ff 6c ba
result (IDENT REQUEST) = 27
Peers:
NSEI 4096, BVCI 4098, not blocked, RAI 112-332-16464-96
RAID patched (BSS ): 3
RAID patched (SGSN): 1
TLLI patched (BSS ): 1
TLLI patched (SGSN): 1
Attach Request count : 1
TLLI cache size : 1
TLLI-Cache: 1
TLLI 8000dead -> 7c69fb81, IMSI (none), AGE 0
PROCESSING IDENT RESPONSE from 0x01020304:1111
00 00 10 02 01 80 00 de ad 00 00 04 08 88 11 22 33 40 50 60 12 34 00 80 0e 00 11 01 c0 05 08 16 08 11 12 13 14 15 16 17 18 ad 05 28
CALLBACK, event 0, msg length 40, bvci 0x1002
00 00 10 02 01 80 00 de ad 00 00 04 08 88 11 22 33 40 50 60 12 34 00 80 0e 00 11 01 c0 05 08 16 08 11 12 13 14 15 16 17 18 ad 05 28
NS UNITDATA MESSAGE to SGSN, BVCI 0x1002, msg length 40 (gprs_ns_sendmsg)
MESSAGE to SGSN at 0x05060708:32000, msg length 44
00 00 10 02 01 7c 69 fb 81 00 00 04 08 88 21 63 54 40 50 60 12 34 00 80 0e 00 11 01 c0 05 08 16 08 11 12 13 14 15 16 17 18 ad 05 28
result (IDENT RESPONSE) = 44
Peers:
NSEI 4096, BVCI 4098, not blocked, RAI 112-332-16464-96
RAID patched (BSS ): 4
RAID patched (SGSN): 1
TLLI patched (BSS ): 2
TLLI patched (SGSN): 1
Attach Request count : 1
TLLI cache size : 1
TLLI-Cache: 1
TLLI 8000dead -> 7c69fb81, IMSI 12131415161718, AGE 0
PROCESSING ATTACH ACCEPT from 0x05060708:32000
00 00 10 02 00 7c 69 fb 81 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 ef e2 b7 00 53 62 f1
CALLBACK, event 0, msg length 88, bvci 0x1002
00 00 10 02 00 7c 69 fb 81 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 ef e2 b7 00 53 62 f1
NS UNITDATA MESSAGE to BSS, BVCI 0x1002, msg length 88 (gprs_ns_sendmsg)
MESSAGE to BSS at 0x01020304:1111, msg length 92
00 00 10 02 00 80 00 de ad 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 c0 0f 73 04 50 22 97
result (ATTACH ACCEPT) = 92
Peers:
NSEI 4096, BVCI 4098, not blocked, RAI 112-332-16464-96
RAID patched (BSS ): 4
RAID patched (SGSN): 2
TLLI patched (BSS ): 2
TLLI patched (SGSN): 2
P-TMSI patched (SGSN): 1
Attach Request count : 1
TLLI cache size : 1
TLLI-Cache: 1
TLLI 8000dead/c00f7304 -> 7c69fb81/efe2b700, IMSI 12131415161718, AGE 0
PROCESSING ATTACH COMPLETE from 0x01020304:1111
00 00 10 02 01 c0 0f 73 04 00 00 04 08 88 11 22 33 40 50 60 12 34 00 80 0e 00 08 01 c0 09 08 03 39 d7 bc
CALLBACK, event 0, msg length 31, bvci 0x1002
00 00 10 02 01 c0 0f 73 04 00 00 04 08 88 11 22 33 40 50 60 12 34 00 80 0e 00 08 01 c0 09 08 03 39 d7 bc
NS UNITDATA MESSAGE to SGSN, BVCI 0x1002, msg length 31 (gprs_ns_sendmsg)
MESSAGE to SGSN at 0x05060708:32000, msg length 35
00 00 10 02 01 ef e2 b7 00 00 00 04 08 88 21 63 54 40 50 60 12 34 00 80 0e 00 08 01 c0 09 08 03 39 d7 bc
result (ATTACH COMPLETE) = 35
Peers:
NSEI 4096, BVCI 4098, not blocked, RAI 112-332-16464-96
RAID patched (BSS ): 5
RAID patched (SGSN): 2
TLLI patched (BSS ): 3
TLLI patched (SGSN): 2
P-TMSI patched (SGSN): 1
Attach Request count : 1
TLLI cache size : 1
TLLI-Cache: 1
TLLI 8000dead/c00f7304 -> 7c69fb81/efe2b700, IMSI 12131415161718, AGE 0
PROCESSING GMM INFO from 0x05060708:32000
00 00 10 02 00 ef e2 b7 00 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 88 41 c0 09 08 21 04 ba 3d
CALLBACK, event 0, msg length 66, bvci 0x1002
00 00 10 02 00 ef e2 b7 00 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 88 41 c0 09 08 21 04 ba 3d
NS UNITDATA MESSAGE to BSS, BVCI 0x1002, msg length 66 (gprs_ns_sendmsg)
MESSAGE to BSS at 0x01020304:1111, msg length 70
00 00 10 02 00 c0 0f 73 04 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 88 41 c0 09 08 21 04 ba 3d
result (GMM INFO) = 70
Peers:
NSEI 4096, BVCI 4098, not blocked, RAI 112-332-16464-96
RAID patched (BSS ): 5
RAID patched (SGSN): 2
TLLI patched (BSS ): 3
TLLI patched (SGSN): 3
P-TMSI patched (SGSN): 1
Attach Request count : 1
TLLI cache size : 1
TLLI-Cache: 1
TLLI c00f7304 -> efe2b700, IMSI 12131415161718, AGE 0
PROCESSING XID (UL) from 0x01020304:1111
00 00 10 02 01 c0 0f 73 04 00 00 04 08 88 11 22 33 40 50 60 12 34 00 80 0e 00 0f 41 fb 01 00 0e 00 64 11 05 16 01 90 66 b3 28
CALLBACK, event 0, msg length 38, bvci 0x1002
00 00 10 02 01 c0 0f 73 04 00 00 04 08 88 11 22 33 40 50 60 12 34 00 80 0e 00 0f 41 fb 01 00 0e 00 64 11 05 16 01 90 66 b3 28
NS UNITDATA MESSAGE to SGSN, BVCI 0x1002, msg length 38 (gprs_ns_sendmsg)
MESSAGE to SGSN at 0x05060708:32000, msg length 42
00 00 10 02 01 ef e2 b7 00 00 00 04 08 88 21 63 54 40 50 60 12 34 00 80 0e 00 0f 41 fb 01 00 0e 00 64 11 05 16 01 90 66 b3 28
result (XID (UL)) = 42
PROCESSING XID (DL) from 0x05060708:32000
00 00 10 02 00 ef e2 b7 00 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 8c 41 fb 30 84 10 61 b6 64 e4 a9 1a 9e
CALLBACK, event 0, msg length 70, bvci 0x1002
00 00 10 02 00 ef e2 b7 00 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 8c 41 fb 30 84 10 61 b6 64 e4 a9 1a 9e
NS UNITDATA MESSAGE to BSS, BVCI 0x1002, msg length 70 (gprs_ns_sendmsg)
MESSAGE to BSS at 0x01020304:1111, msg length 74
00 00 10 02 00 c0 0f 73 04 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 8c 41 fb 30 84 10 61 b6 64 e4 a9 1a 9e
result (XID (DL)) = 74
PROCESSING LL11 DNS QUERY (UL) from 0x01020304:1111
00 00 10 02 01 c0 0f 73 04 00 00 04 08 88 11 22 33 40 50 60 12 34 00 80 0e 00 42 0b c0 01 65 00 00 00 45 00 00 38 95 72 00 00 45 11 20 85 0a c0 07 e4 ac 10 01 0a ad ab 00 35 00 24 0e 1c 3b e0 01 00 00 01 00 00 00 00 00 00 01 6d 05 68 65 69 73 65 02 64 65 00 00 01 00 01 47 8f 07
CALLBACK, event 0, msg length 89, bvci 0x1002
00 00 10 02 01 c0 0f 73 04 00 00 04 08 88 11 22 33 40 50 60 12 34 00 80 0e 00 42 0b c0 01 65 00 00 00 45 00 00 38 95 72 00 00 45 11 20 85 0a c0 07 e4 ac 10 01 0a ad ab 00 35 00 24 0e 1c 3b e0 01 00 00 01 00 00 00 00 00 00 01 6d 05 68 65 69 73 65 02 64 65 00 00 01 00 01 47 8f 07
NS UNITDATA MESSAGE to SGSN, BVCI 0x1002, msg length 89 (gprs_ns_sendmsg)
MESSAGE to SGSN at 0x05060708:32000, msg length 93
00 00 10 02 01 ef e2 b7 00 00 00 04 08 88 21 63 54 40 50 60 12 34 00 80 0e 00 42 0b c0 01 65 00 00 00 45 00 00 38 95 72 00 00 45 11 20 85 0a c0 07 e4 ac 10 01 0a ad ab 00 35 00 24 0e 1c 3b e0 01 00 00 01 00 00 00 00 00 00 01 6d 05 68 65 69 73 65 02 64 65 00 00 01 00 01 47 8f 07
result (LL11 DNS QUERY (UL)) = 93
PROCESSING LL11 DNS RESP (DL) from 0x05060708:32000
00 00 10 02 00 ef e2 b7 00 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 00 d0 4b c0 01 65 00 00 00 45 00 00 c6 00 00 40 00 3e 11 7c 69 ac 10 01 0a 0a c0 07 e4 00 35 ad ab 00 b2 74 4e 3b e0 81 80 00 01 00 01 00 05 00 00 01 6d 05 68 65 69 73 65 02 64 65 00 00 01 00 01 c0 0c 00 01 00 01 00 00 0e 10 00 04 c1 63 90 58 c0 0e 00 02 00 01 00 00 0e 10 00 16 03 6e 73 32 0c 70 6f 70 2d 68 61 6e 6e 6f 76 65 72 03 6e 65 74 00 c0 0e 00 02 00 01 00 00 0e 10 00 10 02 6e 73 01 73 08 70 6c 75 73 6c 69 6e 65 c0 14 c0 0e 00 02 00 01 00 00 0e 10 00 05 02 6e 73 c0 0e c0 0e 00 02 00 01 00 00 0e 10 00 05 02 6e 73 c0 5f c0 0e 00 02 00 01 00 00 0e 10 00 12 02 6e 73 0c 70 6f 70 2d 68 61 6e 6e 6f 76 65 72 c0 14 aa df 31
CALLBACK, event 0, msg length 267, bvci 0x1002
00 00 10 02 00 ef e2 b7 00 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 00 d0 4b c0 01 65 00 00 00 45 00 00 c6 00 00 40 00 3e 11 7c 69 ac 10 01 0a 0a c0 07 e4 00 35 ad ab 00 b2 74 4e 3b e0 81 80 00 01 00 01 00 05 00 00 01 6d 05 68 65 69 73 65 02 64 65 00 00 01 00 01 c0 0c 00 01 00 01 00 00 0e 10 00 04 c1 63 90 58 c0 0e 00 02 00 01 00 00 0e 10 00 16 03 6e 73 32 0c 70 6f 70 2d 68 61 6e 6e 6f 76 65 72 03 6e 65 74 00 c0 0e 00 02 00 01 00 00 0e 10 00 10 02 6e 73 01 73 08 70 6c 75 73 6c 69 6e 65 c0 14 c0 0e 00 02 00 01 00 00 0e 10 00 05 02 6e 73 c0 0e c0 0e 00 02 00 01 00 00 0e 10 00 05 02 6e 73 c0 5f c0 0e 00 02 00 01 00 00 0e 10 00 12 02 6e 73 0c 70 6f 70 2d 68 61 6e 6e 6f 76 65 72 c0 14 aa df 31
NS UNITDATA MESSAGE to BSS, BVCI 0x1002, msg length 267 (gprs_ns_sendmsg)
MESSAGE to BSS at 0x01020304:1111, msg length 271
00 00 10 02 00 c0 0f 73 04 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 00 d0 4b c0 01 65 00 00 00 45 00 00 c6 00 00 40 00 3e 11 7c 69 ac 10 01 0a 0a c0 07 e4 00 35 ad ab 00 b2 74 4e 3b e0 81 80 00 01 00 01 00 05 00 00 01 6d 05 68 65 69 73 65 02 64 65 00 00 01 00 01 c0 0c 00 01 00 01 00 00 0e 10 00 04 c1 63 90 58 c0 0e 00 02 00 01 00 00 0e 10 00 16 03 6e 73 32 0c 70 6f 70 2d 68 61 6e 6e 6f 76 65 72 03 6e 65 74 00 c0 0e 00 02 00 01 00 00 0e 10 00 10 02 6e 73 01 73 08 70 6c 75 73 6c 69 6e 65 c0 14 c0 0e 00 02 00 01 00 00 0e 10 00 05 02 6e 73 c0 0e c0 0e 00 02 00 01 00 00 0e 10 00 05 02 6e 73 c0 5f c0 0e 00 02 00 01 00 00 0e 10 00 12 02 6e 73 0c 70 6f 70 2d 68 61 6e 6e 6f 76 65 72 c0 14 aa df 31
result (LL11 DNS RESP (DL)) = 271
Peers:
NSEI 4096, BVCI 4098, not blocked, RAI 112-332-16464-96
RAID patched (BSS ): 7
RAID patched (SGSN): 2
TLLI patched (BSS ): 5
TLLI patched (SGSN): 5
P-TMSI patched (SGSN): 1
Attach Request count : 1
TLLI cache size : 1
TLLI-Cache: 1
TLLI c00f7304 -> efe2b700, IMSI 12131415161718, AGE 0
PROCESSING DETACH REQ from 0x01020304:1111
00 00 10 02 01 c0 0f 73 04 00 00 04 08 88 11 22 33 40 50 60 12 34 00 80 0e 00 15 01 c0 0d 08 05 01 18 05 f4 ef e2 b7 00 19 03 b9 97 cb 37 67 c6
CALLBACK, event 0, msg length 44, bvci 0x1002
00 00 10 02 01 c0 0f 73 04 00 00 04 08 88 11 22 33 40 50 60 12 34 00 80 0e 00 15 01 c0 0d 08 05 01 18 05 f4 ef e2 b7 00 19 03 b9 97 cb 37 67 c6
NS UNITDATA MESSAGE to SGSN, BVCI 0x1002, msg length 44 (gprs_ns_sendmsg)
MESSAGE to SGSN at 0x05060708:32000, msg length 48
00 00 10 02 01 ef e2 b7 00 00 00 04 08 88 21 63 54 40 50 60 12 34 00 80 0e 00 15 01 c0 0d 08 05 01 18 05 f4 ef e2 b7 00 19 03 b9 97 cb 37 67 c6
result (DETACH REQ) = 48
Peers:
NSEI 4096, BVCI 4098, not blocked, RAI 112-332-16464-96
RAID patched (BSS ): 8
RAID patched (SGSN): 2
TLLI patched (BSS ): 6
TLLI patched (SGSN): 5
P-TMSI patched (SGSN): 1
Attach Request count : 1
TLLI cache size : 1
TLLI-Cache: 1
TLLI c00f7304 -> efe2b700, IMSI 12131415161718, AGE 0
PROCESSING DETACH ACC from 0x05060708:32000
00 00 10 02 00 ef e2 b7 00 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 89 41 c0 0d 08 06 00 aa ab ee
CALLBACK, event 0, msg length 67, bvci 0x1002
00 00 10 02 00 ef e2 b7 00 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 89 41 c0 0d 08 06 00 aa ab ee
NS UNITDATA MESSAGE to BSS, BVCI 0x1002, msg length 67 (gprs_ns_sendmsg)
MESSAGE to BSS at 0x01020304:1111, msg length 71
00 00 10 02 00 c0 0f 73 04 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 89 41 c0 0d 08 06 00 aa ab ee
result (DETACH ACC) = 71
Peers:
NSEI 4096, BVCI 4098, not blocked, RAI 112-332-16464-96
RAID patched (BSS ): 8
RAID patched (SGSN): 2
TLLI patched (BSS ): 6
TLLI patched (SGSN): 6
P-TMSI patched (SGSN): 1
Attach Request count : 1
TLLI-Cache: 0
Gbproxy global:
Test TLLI info expiry
Test TLLI replacement: