diff options
46 files changed, 2943 insertions, 16221 deletions
diff --git a/TODO-RELEASE b/TODO-RELEASE index 6b29a879..1e409b59 100644 --- a/TODO-RELEASE +++ b/TODO-RELEASE @@ -1,2 +1,3 @@ #component what description / commit summary line manual needs common chapter cs7-config.adoc, vty_cpu_sched.adoc from osmo-gsm-manuals > 0.3.0 +configure.ac libosmocore depend on next released libosmocore after 1.4.x with hashtable support diff --git a/configure.ac b/configure.ac index 12af7e64..f1a4ed48 100644 --- a/configure.ac +++ b/configure.ac @@ -39,6 +39,9 @@ m4_ifdef([AX_CHECK_COMPILE_FLAG], [], [ AC_MSG_ERROR([Please install autoconf-archive; re-run 'autoreconf -fi' for it to take effect.]) ]) +dnl use a defined standard across all builds and don't depend on compiler default +CFLAGS="$CFLAGS -std=gnu11" + dnl checks for libraries AC_SEARCH_LIBS([dlopen], [dl dld], [LIBRARY_DL="$LIBS";LIBS=""]) AC_SUBST(LIBRARY_DL) @@ -118,8 +121,8 @@ AC_COMPILE_IFELSE([AC_LANG_SOURCE([char foo;])], CFLAGS="$saved_CFLAGS" AC_SUBST(SYMBOL_VISIBILITY) -CPPFLAGS="$CPPFLAGS -Wall" -CFLAGS="$CFLAGS -Wall" +CPPFLAGS="$CPPFLAGS -Wall -Wno-trigraphs" +CFLAGS="$CFLAGS -Wall -Wno-trigraphs" AX_CHECK_COMPILE_FLAG([-Werror=implicit], [CFLAGS="$CFLAGS -Werror=implicit"]) AX_CHECK_COMPILE_FLAG([-Werror=maybe-uninitialized], [CFLAGS="$CFLAGS -Werror=maybe-uninitialized"]) @@ -172,9 +175,9 @@ AC_ARG_ENABLE([external_tests], [Include the VTY/CTRL tests in make check [default=no]]), [enable_ext_tests="$enableval"],[enable_ext_tests="no"]) if test "x$enable_ext_tests" = "xyes" ; then - AC_CHECK_PROG(PYTHON2_AVAIL,python2,yes) - if test "x$PYTHON2_AVAIL" != "xyes" ; then - AC_MSG_ERROR([Please install python2 to run the VTY/CTRL tests.]) + AC_CHECK_PROG(PYTHON3_AVAIL,python3,yes) + if test "x$PYTHON3_AVAIL" != "xyes" ; then + AC_MSG_ERROR([Please install python3 to run the VTY/CTRL tests.]) fi AC_CHECK_PROG(OSMOTESTEXT_CHECK,osmotestvty.py,yes) if test "x$OSMOTESTEXT_CHECK" != "xyes" ; then @@ -261,7 +264,6 @@ AC_OUTPUT( tests/Makefile tests/atlocal tests/gprs/Makefile - tests/gbproxy/Makefile tests/sgsn/Makefile tests/gtphub/Makefile tests/xid/Makefile diff --git a/contrib/jenkins.sh b/contrib/jenkins.sh index 87d86015..2325897a 100755 --- a/contrib/jenkins.sh +++ b/contrib/jenkins.sh @@ -50,7 +50,6 @@ fi # Additional configure options and depends CONFIG="" if [ "$WITH_MANUALS" = "1" ]; then - osmo-build-dep.sh osmo-gsm-manuals CONFIG="--enable-manuals" fi diff --git a/contrib/osmo-sgsn.spec.in b/contrib/osmo-sgsn.spec.in index d6a80789..ca66e2ea 100644 --- a/contrib/osmo-sgsn.spec.in +++ b/contrib/osmo-sgsn.spec.in @@ -131,7 +131,6 @@ make %{?_smp_mflags} check || (find . -name testsuite.log -exec cat {} +) %files -n osmo-gbproxy %dir %{_docdir}/%{name}/examples %dir %{_docdir}/%{name}/examples/osmo-gbproxy -%{_docdir}/%{name}/examples/osmo-gbproxy/osmo-gbproxy-legacy.cfg %{_docdir}/%{name}/examples/osmo-gbproxy/osmo-gbproxy.cfg %{_bindir}/osmo-gbproxy %dir %{_sysconfdir}/osmocom diff --git a/debian/copyright b/debian/copyright index fa7405fe..5bc764d6 100644 --- a/debian/copyright +++ b/debian/copyright @@ -24,7 +24,6 @@ Files: .gitignore contrib/twisted_ipa.py doc/Makefile.am doc/examples/Makefile.am - doc/examples/osmo-gbproxy/osmo-gbproxy-legacy.cfg doc/examples/osmo-gbproxy/osmo-gbproxy.cfg doc/examples/osmo-gtphub/gtphub-example.txt doc/examples/osmo-gtphub/osmo-gtphub-1iface.cfg @@ -88,9 +87,7 @@ Files: include/osmocom/sgsn/a_reset.h src/gprs/sgsn_ares.c src/gbproxy/gb_proxy.c src/gbproxy/gb_proxy_main.c - src/gbproxy/gb_proxy_patch.c src/gbproxy/gb_proxy_peer.c - src/gbproxy/gb_proxy_tlli.c src/gbproxy/gb_proxy_vty.c src/gtphub/gtphub.c src/gtphub/gtphub_main.c diff --git a/debian/osmo-gbproxy.install b/debian/osmo-gbproxy.install index a8c0dadd..1cb91d5d 100644 --- a/debian/osmo-gbproxy.install +++ b/debian/osmo-gbproxy.install @@ -1,5 +1,4 @@ etc/osmocom/osmo-gbproxy.cfg lib/systemd/system/osmo-gbproxy.service usr/bin/osmo-gbproxy -usr/share/doc/osmo-sgsn/examples/osmo-gbproxy/osmo-gbproxy-legacy.cfg usr/share/doc/osmo-gbproxy/examples usr/share/doc/osmo-sgsn/examples/osmo-gbproxy/osmo-gbproxy.cfg usr/share/doc/osmo-gbproxy/examples diff --git a/doc/examples/osmo-gbproxy/osmo-gbproxy-legacy.cfg b/doc/examples/osmo-gbproxy/osmo-gbproxy-legacy.cfg index c471c38b..e30b9f7f 100644 --- a/doc/examples/osmo-gbproxy/osmo-gbproxy-legacy.cfg +++ b/doc/examples/osmo-gbproxy/osmo-gbproxy-legacy.cfg @@ -22,11 +22,11 @@ line vty no login ! ns - nse 666 nsvci 666 - nse 666 remote-role sgsn -! nse 666 encapsulation framerelay-gre -! nse 666 remote-ip 172.16.1.70 -! nse 666 fr-dlci 666 + bind udp local + listen 127.0.0.1 23000 + accept-ipaccess + nse 666 + nsvc ipa local 127.0.0.1 23001 nsvci 666 timer tns-block 3 timer tns-block-retries 3 timer tns-reset 3 @@ -34,8 +34,6 @@ ns timer tns-test 30 timer tns-alive 3 timer tns-alive-retries 10 - encapsulation udp local-port 23000 -! encapsulation framerelay-gre enabled 1 gbproxy sgsn nsei 666 core-mobile-country-code 666 diff --git a/doc/examples/osmo-gbproxy/osmo-gbproxy-pool.cfg b/doc/examples/osmo-gbproxy/osmo-gbproxy-pool.cfg new file mode 100644 index 00000000..bbc8a1b7 --- /dev/null +++ b/doc/examples/osmo-gbproxy/osmo-gbproxy-pool.cfg @@ -0,0 +1,32 @@ +! +! Osmocom Gb Proxy (0.9.0.404-6463) configuration saved from vty +!! +! +line vty + no login +! +gbproxy + nri bitlen 4 + nri null add 0 4 +sgsn nsei 101 + name main + nri add 1 + nri add 11 +sgsn nsei 102 + nri add 2 + nri add 12 +ns + bind udp local + listen 127.0.0.100 23000 + accept-ipaccess + nse 101 + nsvc ipa local 192.168.100.239 7777 nsvci 101 + nse 102 + nsvc ipa local 192.168.100.239 7778 nsvci 102 + timer tns-block 3 + timer tns-block-retries 3 + timer tns-reset 3 + timer tns-reset-retries 3 + timer tns-test 30 + timer tns-alive 3 + timer tns-alive-retries 10 diff --git a/doc/examples/osmo-gbproxy/osmo-gbproxy.cfg b/doc/examples/osmo-gbproxy/osmo-gbproxy.cfg index 29f698f3..777d0b0f 100644 --- a/doc/examples/osmo-gbproxy/osmo-gbproxy.cfg +++ b/doc/examples/osmo-gbproxy/osmo-gbproxy.cfg @@ -6,13 +6,14 @@ line vty no login ! gbproxy - sgsn nsei 101 +sgsn nsei 101 + name main ns - nse 101 nsvci 101 - nse 101 remote-role sgsn - nse 101 encapsulation udp - nse 101 remote-ip 192.168.100.239 - nse 101 remote-port 7777 + bind udp local + listen 127.0.0.100 23000 + accept-ipaccess + nse 101 + nsvc ipa local 192.168.100.239 7777 nsvci 101 timer tns-block 3 timer tns-block-retries 3 timer tns-reset 3 @@ -20,7 +21,3 @@ ns timer tns-test 30 timer tns-alive 3 timer tns-alive-retries 10 - encapsulation framerelay-gre enabled 0 - encapsulation framerelay-gre local-ip 0.0.0.0 - encapsulation udp local-ip 127.0.0.100 - encapsulation udp local-port 23000 diff --git a/doc/manuals/chapters/gbproxy-configuration.adoc b/doc/manuals/chapters/gbproxy-configuration.adoc index 599b3f7b..e61af48b 100644 --- a/doc/manuals/chapters/gbproxy-configuration.adoc +++ b/doc/manuals/chapters/gbproxy-configuration.adoc @@ -4,3 +4,29 @@ TBD. Unfortunately this chapter of the manual still needs to be written. Osmocom has very limited funding and support resources; Feel free to help us completing this documentation by contributing with code, documentation or by supporting the developers financially. + + +=== SGSN pool support + +In a SGSN pool, osmo-gbproxy is facing the problem of dividing the downlink +capacity of a cell towards the SGSN. The BSS advertises the per-BVC capacity +by means of the BSSGP FLOW-CONTROL-BVC messages, but as there are multiple +SGSN in a pool, they all have to share / divide that total capacity. + +By default, osmo-gbproxy advertises the full capacity to _each_ of the SGSN +pool members, which results in significant over-provisioning and can lead to +overload situations. + +The administrator can configure the _percentage_ of the overall BSS-advertised +capacity that shall be reported to each pool member SGSN using the +`pool bvc-flow-control-ratio <1-100>` configuration command. + +A setting of 100 means that each pool member is informed of 100% of the +BSS side capacity. + +A setting of 25 means that each pool member is informed of 25% of the +BSS side capacity. This would make most sense in a set-up with four +SGSN of equal share. + +More complex capacity division schemes are so far not supported by +osmo-gbproxy. diff --git a/include/osmocom/sgsn/debug.h b/include/osmocom/sgsn/debug.h index 29d500da..9a686cb6 100644 --- a/include/osmocom/sgsn/debug.h +++ b/include/osmocom/sgsn/debug.h @@ -8,38 +8,25 @@ /* Debug Areas of the code */ enum { - DRLL, - DCC, DMM, - DRR, - DRSL, - DNM, - DMNCC, DPAG, DMEAS, - DSCCP, - DMSC, - DHO, - DDB, DREF, DGPRS, DNS, - DBSSGP, DLLC, DSNDCP, DSLHC, - DNAT, DCTRL, DFILTER, DGTPHUB, DRANAP, DSUA, DV42BIS, - DPCU, - DVLR, DIUCS, DSIGTRAN, DGTP, + DOBJ, Debug_LastEntry, }; diff --git a/include/osmocom/sgsn/gb_proxy.h b/include/osmocom/sgsn/gb_proxy.h index 1e8fb253..d988cae7 100644 --- a/include/osmocom/sgsn/gb_proxy.h +++ b/include/osmocom/sgsn/gb_proxy.h @@ -3,9 +3,14 @@ #include <osmocom/core/msgb.h> +#include <osmocom/core/timer.h> +#include <osmocom/core/fsm.h> +#include <osmocom/core/hashtable.h> #include <osmocom/gsm/gsm23003.h> +#include <osmocom/gsm/gsm23236.h> +#include <osmocom/gsm/protocol/gsm_23_003.h> -#include <osmocom/gprs/gprs_ns.h> +#include <osmocom/gprs/gprs_ns2.h> #include <osmocom/vty/command.h> #include <sys/types.h> @@ -13,6 +18,10 @@ #include <stdbool.h> #define GBPROXY_INIT_VU_GEN_TX 256 +#define GBPROXY_MAX_NR_SGSN 16 + +/* BVCI uses 16 bits */ +#define BVC_LOG_CTX_FLAG (1<<17) struct rate_ctr_group; struct gprs_gb_parse_context; @@ -30,198 +39,196 @@ enum gbproxy_global_ctr { 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 { +enum gbproxy_bvc_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_ATTACH_ACKS, - GBPROX_PEER_CTR_ATTACH_COMPLS, - GBPROX_PEER_CTR_RA_UPD_REQS, - GBPROX_PEER_CTR_RA_UPD_REJS, - GBPROX_PEER_CTR_RA_UPD_ACKS, - GBPROX_PEER_CTR_RA_UPD_COMPLS, - GBPROX_PEER_CTR_GMM_STATUS_BSS, - GBPROX_PEER_CTR_GMM_STATUS_SGSN, - GBPROX_PEER_CTR_DETACH_REQS, - GBPROX_PEER_CTR_DETACH_ACKS, - GBPROX_PEER_CTR_PDP_ACT_REQS, - GBPROX_PEER_CTR_PDP_ACT_REJS, - GBPROX_PEER_CTR_PDP_ACT_ACKS, - GBPROX_PEER_CTR_PDP_DEACT_REQS, - GBPROX_PEER_CTR_PDP_DEACT_ACKS, - GBPROX_PEER_CTR_TLLI_UNKNOWN, - GBPROX_PEER_CTR_TLLI_CACHE_SIZE, GBPROX_PEER_CTR_LAST, }; -enum gbproxy_keep_mode { - GBPROX_KEEP_NEVER, /* don't ever keep TLLI/IMSI state of de-registered subscribers */ - GBPROX_KEEP_REATTACH, /* keep if re-attach has been requested by SGSN */ - GBPROX_KEEP_IDENTIFIED, /* keep if we had resolved an IMSI */ - GBPROX_KEEP_ALWAYS, /* always keep */ -}; - -enum gbproxy_match_id { - GBPROX_MATCH_PATCHING, /* match rule on whether or not we should patch */ - GBPROX_MATCH_ROUTING, /* match rule on whether or not we should route (2-SGSN) */ - GBPROX_MATCH_LAST -}; - -struct gbproxy_match { - bool enable; /* is this match enabled? */ - char *re_str; /* regular expression (for IMSI) in string format */ - regex_t re_comp; /* compiled regular expression (for IMSI) */ -}; - /* global gb-proxy configuration */ struct gbproxy_config { - /* parsed from config file */ - uint16_t nsip_sgsn_nsei; - /* NS instance of libosmogb */ - struct gprs_ns_inst *nsi; - - /* Linked list of all Gb peers (except SGSN) */ - struct llist_head bts_peers; + struct gprs_ns2_inst *nsi; + + struct { + /* percentage of BVC flow control advertised to each SGSN in the pool */ + uint8_t bvc_fc_ratio; + /* NRI bitlen and usable NULL-NRI ranges */ + uint8_t nri_bitlen; + struct osmo_nri_ranges *null_nri_ranges; + + /* Used for testing: If not NULL then this SGSN is returned by + * gbproxy_sgsn_by_tlli() */ + struct gbproxy_sgsn *nsf_override; + } pool; + + /* hash table of all BSS side Gb peers */ + DECLARE_HASHTABLE(bss_nses, 8); + + /* hash table of all SGSN-side Gb peers */ + DECLARE_HASHTABLE(sgsn_nses, 8); + + /* hash table of all gbproxy_cell */ + DECLARE_HASHTABLE(cells, 8); + + /* tlli<->nse cache used to map SUSPEND/RESUME (N)ACKS */ + struct { + DECLARE_HASHTABLE(entries, 10); + struct osmo_timer_list timer; + /* Time in seconds that the entries should be valid */ + uint8_t timeout; + } tlli_cache; + + /* imsi<->nse cache used for PAGING REJECT */ + struct { + DECLARE_HASHTABLE(entries, 10); + struct osmo_timer_list timer; + /* Time in seconds that the entries should be valid */ + uint8_t timeout; + } imsi_cache; + + /* List of all SGSNs */ + struct llist_head sgsns; /* Counter */ struct rate_ctr_group *ctrg; - - /* MCC/MNC to be patched into RA-ID on the way from BSS to SGSN? */ - struct osmo_plmn_id core_plmn; - - /* APN to be patched into PDP CTX ACT REQ on the way from BSS to SGSN */ - uint8_t* core_apn; - size_t core_apn_size; - - /* Frequency (sec) at which timer to clean stale links is fired (0 disabled) */ - unsigned int clean_stale_timer_freq; - /* If !0, Max age to consider a struct gbproxy_link_info as stale */ - int tlli_max_age; - /* If !0, Max len of gbproxy_peer->list (list of struct gbproxy_link_info) */ - int tlli_max_len; - /* If !0, Max len of gbproxy_link_info->stored_msgs (list of msgb) */ - uint32_t stored_msgs_max_len; - - /* Should the P-TMSI be patched on the fly (required for 2-SGSN config) */ - bool patch_ptmsi; - /* Should the IMSI be acquired by the proxy (required for 2-SGSN config) */ - bool acquire_imsi; - /* Should we route subscribers to two different SGSNs? */ - bool route_to_sgsn2; - /* NSEI of the second SGSN */ - uint16_t nsip_sgsn2_nsei; - /* should we keep a cache of per-subscriber state even after de-registration? */ - enum gbproxy_keep_mode keep_link_infos; - - /* IMSI checking/matching for 2-SGSN routing and patching */ - struct gbproxy_match matches[GBPROX_MATCH_LAST]; }; -struct gbproxy_patch_state { - struct osmo_plmn_id local_plmn; - - /* List of TLLIs for which patching is enabled */ - struct llist_head logical_links; - int logical_link_count; -}; - -/* one peer at NS level that we interact with (BSS/PCU) */ -struct gbproxy_peer { - /* linked to gbproxy_config.bts_peers */ - struct llist_head list; +/* One Cell within the BSS: Links BSS-side BVC to SGSN-side BVCs */ +struct gbproxy_cell { + /* linked to gbproxy_config.cells hashtable */ + struct hlist_node list; /* point back to the config */ struct gbproxy_config *cfg; - /* NSEI of the peer entity */ - uint16_t nsei; + /* BVCI of PTP BVCs associated to this cell */ + uint16_t bvci; + + /* Routing Area that this BVC is part of (raw 04.08 encoding) */ + uint8_t ra[6]; - /* BVCI used for Point-to-Point to this peer */ + /* pointer to the BSS-side BVC */ + struct gbproxy_bvc *bss_bvc; + + /* pointers to SGSN-side BVC (one for each pool member) */ + struct gbproxy_bvc *sgsn_bvc[GBPROXY_MAX_NR_SGSN]; +}; + +/* One BVC inside an NSE */ +struct gbproxy_bvc { + /* linked to gbproxy_nse.bvcs */ + struct hlist_node list; + + /* The NSE this BVC belongs to */ + struct gbproxy_nse *nse; + + /* PTP BVCI of this BVC */ uint16_t bvci; - bool blocked; - /* Routeing Area that this peer is part of (raw 04.08 encoding) */ + /* Routing Area that this BVC is part of (raw 04.08 encoding) */ uint8_t ra[6]; /* Counter */ struct rate_ctr_group *ctrg; - /* State related to on-the-fly patching of certain messages */ - struct gbproxy_patch_state patch_state; + /* the cell to which this BVC belongs */ + struct gbproxy_cell *cell; - /* Fired periodically to clean up stale links from list */ - struct osmo_timer_list clean_stale_timer; + /* per-BVC FSM instance */ + struct osmo_fsm_inst *fi; }; -struct gbproxy_tlli_state { - /* currently active TLLI */ - uint32_t current; - /* newly-assigned TLLI (e.g. during P-TMSI allocation procedure) */ - uint32_t assigned; - /* has the BSS side validated (confirmed) the new TLLI? */ - bool bss_validated; - /* has the SGSN side validated (confirmed) the new TLLI? */ - bool net_validated; - /* NOTE: once both are validated, we set current = assigned and assigned = 0 */ - - /* The P-TMSI for this subscriber */ - uint32_t ptmsi; -}; +/* one NS Entity that we interact with (BSS/PCU) */ +struct gbproxy_nse { + /* linked to gbproxy_config.bss_nses */ + struct hlist_node list; -/* One TLLI (= UE, = Subscriber) served via this proxy */ -struct gbproxy_link_info { - /* link to gbproxy_peer.patch_state.logical_links */ - struct llist_head list; + /* point back to the config */ + struct gbproxy_config *cfg; - /* TLLI on the BSS/PCU side */ - struct gbproxy_tlli_state tlli; - /* TLLI on the SGSN side (can be different in case of P-TMSI patching) */ - struct gbproxy_tlli_state sgsn_tlli; - /* NSEI of the SGSN serving this link */ - uint32_t sgsn_nsei; + /* NSEI of the NSE */ + uint16_t nsei; + + /* Are we facing towards a SGSN (true) or BSS (false) */ + bool sgsn_facing; - /* timestamp when we last had any contact with this UE */ - time_t timestamp; + /* List of all BVCs in this NSE */ + DECLARE_HASHTABLE(bvcs, 10); +}; - /* IMSI of the subscriber (if/once known) */ - uint8_t *imsi; - size_t imsi_len; +/* SGSN configuration such as pool options (only for NSE where sgsn_facing == true) */ +struct gbproxy_sgsn { + /* linked to gbproxy_config.sgsns */ + struct llist_head list; - /* is the IMSI acquisition still pending? */ - bool imsi_acq_pending; + /* The NSE belonging to this SGSN */ + struct gbproxy_nse *nse; - /* queue of stored UL messages (until IMSI acquisition completes and we can - * determine which of the SGSNs we should route this to */ - struct llist_head stored_msgs; - uint32_t stored_msgs_len; + /* Name of the SGSN */ + char *name; - /* generated N(U) we use (required due to IMSI acquisition */ - unsigned vu_gen_tx_bss; + /* Pool configuration for the sgsn (only valid if sgsn_facing == true) */ + struct { + bool allow_attach; + struct osmo_nri_ranges *nri_ranges; + } pool; +}; - /* is this subscriber deregistered (TLLI invalidated)? */ - bool is_deregistered; +/* TLLI cache */ +struct gbproxy_tlli_cache_entry { + /* linked to gbproxy_config.tlli_cache.entries */ + struct hlist_node list; + + /* TLLI of the entry */ + uint32_t tlli; + /* When was this entry last seen */ + time_t tstamp; + /* The Cell this TLLI was last seen */ + struct gbproxy_nse *nse; +}; - /* does this link match either the (2-SGSN) routing or the patching rule? */ - bool is_matching[GBPROX_MATCH_LAST]; +/* IMSI cache */ +struct gbproxy_imsi_cache_entry { + /* linked to gbproxy_config.imsi_cache.entries */ + struct hlist_node list; + + /* IMSI of the entry */ + char imsi[OSMO_IMSI_BUF_SIZE]; + /* When was this entry last seen */ + time_t tstamp; + /* The SGSN where the request came from */ + struct gbproxy_nse *nse; }; +/* Convenience logging macros for NSE/BVC */ +#define LOGPNSE_CAT(NSE, SUBSYS, LEVEL, FMT, ARGS...) \ + LOGP(SUBSYS, LEVEL, "NSE(%05u/%s) " FMT, (NSE)->nsei, \ + (NSE)->sgsn_facing ? "SGSN" : "BSS", ## ARGS) +#define LOGPNSE(NSE, LEVEL, FMT, ARGS...) \ + LOGPNSE_CAT(NSE, DGPRS, LEVEL, FMT, ## ARGS) + +#define LOGPBVC_CAT(BVC, SUBSYS, LEVEL, FMT, ARGS...) \ + LOGP(SUBSYS, LEVEL, "NSE(%05u/%s)-BVC(%05u/%s) " FMT, (BVC)->nse->nsei, \ + (BVC)->nse->sgsn_facing ? "SGSN" : "BSS", (BVC)->bvci, \ + osmo_fsm_inst_state_name((BVC)->fi), ## ARGS) +#define LOGPBVC(BVC, LEVEL, FMT, ARGS...) \ + LOGPBVC_CAT(BVC, DGPRS, LEVEL, FMT, ## ARGS) + +#define LOGPCELL_CAT(CELL, SUBSYS, LEVEL, FMT, ARGS...) \ + LOGP(SUBSYS, LEVEL, "CELL(%05u) " FMT, (CELL)->bvci, ## ARGS) +#define LOGPCELL(CELL, LEVEL, FMT, ARGS...) \ + LOGPCELL_CAT(CELL, DGPRS, LEVEL, FMT, ## ARGS) + +#define LOGPSGSN_CAT(SGSN, SUBSYS, LEVEL, FMT, ARGS...) \ + LOGP(SUBSYS, LEVEL, "NSE(%05u)-SGSN(%s) " FMT, (SGSN)->nse->nsei, (SGSN)->name, ## ARGS) +#define LOGPSGSN(SGSN, LEVEL, FMT, ARGS...) \ + LOGPSGSN_CAT(SGSN, DGPRS, LEVEL, FMT, ## ARGS) /* gb_proxy_vty .c */ @@ -236,99 +243,56 @@ int gb_ctrl_cmds_install(void); int gbproxy_init_config(struct gbproxy_config *cfg); /* Main input function for Gb proxy */ -int gbprox_rcvmsg(struct gbproxy_config *cfg, struct msgb *msg, uint16_t nsei, uint16_t ns_bvci, uint16_t nsvci); +int gbprox_rcvmsg(void *ctx, struct msgb *msg); int gbprox_signal(unsigned int subsys, unsigned int signal, void *handler_data, void *signal_data); -/* Reset all persistent NS-VC's */ -int gbprox_reset_persistent_nsvcs(struct gprs_ns_inst *nsi); -void gbprox_reset(struct gbproxy_config *cfg); +int gprs_ns2_prim_cb(struct osmo_prim_hdr *oph, void *ctx); -/* TLLI info handling */ -void gbproxy_delete_link_infos(struct gbproxy_peer *peer); -struct gbproxy_link_info *gbproxy_update_link_state_ul( - struct gbproxy_peer *peer, time_t now, - struct gprs_gb_parse_context *parse_ctx); -struct gbproxy_link_info *gbproxy_update_link_state_dl( - struct gbproxy_peer *peer, time_t now, - struct gprs_gb_parse_context *parse_ctx); -int gbproxy_update_link_state_after( - struct gbproxy_peer *peer, struct gbproxy_link_info *link_info, - time_t now, struct gprs_gb_parse_context *parse_ctx); -int gbproxy_remove_stale_link_infos(struct gbproxy_peer *peer, time_t now); -void gbproxy_delete_link_info(struct gbproxy_peer *peer, - struct gbproxy_link_info *link_info); -void gbproxy_link_info_discard_messages(struct gbproxy_link_info *link_info); - -void gbproxy_attach_link_info(struct gbproxy_peer *peer, time_t now, - struct gbproxy_link_info *link_info); -void gbproxy_update_link_info(struct gbproxy_link_info *link_info, - const uint8_t *imsi, size_t imsi_len); -void gbproxy_detach_link_info(struct gbproxy_peer *peer, - struct gbproxy_link_info *link_info); -struct gbproxy_link_info *gbproxy_link_info_alloc( struct gbproxy_peer *peer); - -struct gbproxy_link_info *gbproxy_link_info_by_tlli( - struct gbproxy_peer *peer, uint32_t tlli); -struct gbproxy_link_info *gbproxy_link_info_by_imsi( - struct gbproxy_peer *peer, const uint8_t *imsi, size_t imsi_len); -struct gbproxy_link_info *gbproxy_link_info_by_any_sgsn_tlli( - struct gbproxy_peer *peer, uint32_t tlli); -struct gbproxy_link_info *gbproxy_link_info_by_sgsn_tlli( - struct gbproxy_peer *peer, - uint32_t tlli, uint32_t sgsn_nsei); -struct gbproxy_link_info *gbproxy_link_info_by_ptmsi( - struct gbproxy_peer *peer, - uint32_t ptmsi); - -int gbproxy_imsi_matches( - struct gbproxy_config *cfg, - enum gbproxy_match_id match_id, - struct gbproxy_link_info *link_info); -uint32_t gbproxy_map_tlli( - uint32_t other_tlli, struct gbproxy_link_info *link_info, int to_bss); - -/* 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_link_info *link_info, - uint32_t bss_tlli); -void gbproxy_reset_link(struct gbproxy_link_info *link_info); -int gbproxy_check_imsi( - struct gbproxy_match *match, 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_link_info *link_info, - int *len_change, struct gprs_gb_parse_context *parse_ctx); - -int gbproxy_patch_llc( - struct msgb *msg, uint8_t *llc, size_t llc_len, - struct gbproxy_peer *peer, struct gbproxy_link_info *link_info, - int *len_change, struct gprs_gb_parse_context *parse_ctx); - -int gbproxy_set_patch_filter( - struct gbproxy_match *match, const char *filter, const char **err_msg); -void gbproxy_clear_patch_filter(struct gbproxy_match *match); +void gbprox_reset(struct gbproxy_config *cfg); /* Peer handling */ -struct gbproxy_peer *gbproxy_peer_by_bvci( - struct gbproxy_config *cfg, uint16_t bvci); -struct gbproxy_peer *gbproxy_peer_by_nsei( - struct gbproxy_config *cfg, uint16_t nsei); -struct gbproxy_peer *gbproxy_peer_by_rai( - struct gbproxy_config *cfg, const uint8_t *ra); -struct gbproxy_peer *gbproxy_peer_by_lai( - struct gbproxy_config *cfg, const uint8_t *la); -struct gbproxy_peer *gbproxy_peer_by_lac( - struct gbproxy_config *cfg, const uint8_t *la); -struct gbproxy_peer *gbproxy_peer_by_bssgp_tlv( - struct gbproxy_config *cfg, struct tlv_parsed *tp); -struct gbproxy_peer *gbproxy_peer_alloc(struct gbproxy_config *cfg, uint16_t bvci); -void gbproxy_peer_free(struct gbproxy_peer *peer); -int gbproxy_cleanup_peers(struct gbproxy_config *cfg, uint16_t nsei, uint16_t bvci); +#define NSE_F_SGSN 0x0001 +#define NSE_F_BSS 0x0002 + +struct gbproxy_bvc *gbproxy_bvc_by_bvci(struct gbproxy_nse *nse, uint16_t bvci); +struct gbproxy_bvc *gbproxy_bvc_alloc(struct gbproxy_nse *nse, uint16_t bvci); +void gbproxy_bvc_free(struct gbproxy_bvc *bvc); +int gbproxy_cleanup_bvcs(struct gbproxy_nse *nse, uint16_t bvci); + +struct gbproxy_cell *gbproxy_cell_alloc(struct gbproxy_config *cfg, uint16_t bvci); +struct gbproxy_cell *gbproxy_cell_by_bvci(struct gbproxy_config *cfg, uint16_t bvci); +void gbproxy_cell_free(struct gbproxy_cell *cell); +bool gbproxy_cell_add_sgsn_bvc(struct gbproxy_cell *cell, struct gbproxy_bvc *bvc); + +/* NSE handling */ +struct gbproxy_nse *gbproxy_nse_alloc(struct gbproxy_config *cfg, uint16_t nsei, bool sgsn_facing); +void gbproxy_nse_free(struct gbproxy_nse *nse); +struct gbproxy_nse *gbproxy_nse_by_nsei(struct gbproxy_config *cfg, uint16_t nsei, uint32_t flags); +struct gbproxy_nse *gbproxy_nse_by_nsei_or_new(struct gbproxy_config *cfg, uint16_t nsei, bool sgsn_facing); +struct gbproxy_nse *gbproxy_nse_by_tlli(struct gbproxy_config *cfg, uint32_t tlli); +struct gbproxy_nse *gbproxy_nse_by_imsi(struct gbproxy_config *cfg, const char *imsi); + +/* TLLI cache */ +void gbproxy_tlli_cache_update(struct gbproxy_nse *nse, uint32_t tlli); +void gbproxy_tlli_cache_remove(struct gbproxy_config *cfg, uint32_t tlli); +int gbproxy_tlli_cache_cleanup(struct gbproxy_config *cfg); + +/* IMSI cache */ +void gbproxy_imsi_cache_update(struct gbproxy_nse *nse, const char *imsi); +void gbproxy_imsi_cache_remove(struct gbproxy_config *cfg, const char *imsi); +int gbproxy_imsi_cache_cleanup(struct gbproxy_config *cfg); + +/* SGSN handling */ +struct gbproxy_sgsn *gbproxy_sgsn_alloc(struct gbproxy_config *cfg, uint16_t nsei, const char *name); +void gbproxy_sgsn_free(struct gbproxy_sgsn *sgsn); +struct gbproxy_sgsn *gbproxy_sgsn_by_name(struct gbproxy_config *cfg, const char *name); +struct gbproxy_sgsn *gbproxy_sgsn_by_nsei(struct gbproxy_config *cfg, uint16_t nsei); +struct gbproxy_sgsn *gbproxy_sgsn_by_nsei_or_new(struct gbproxy_config *cfg, uint16_t nsei); +struct gbproxy_sgsn *gbproxy_sgsn_by_nri(struct gbproxy_config *cfg, uint16_t nri, bool *null_nri); +struct gbproxy_sgsn *gbproxy_sgsn_by_tlli(struct gbproxy_config *cfg, struct gbproxy_sgsn *sgsn_avoid, + uint32_t tlli); #endif diff --git a/include/osmocom/sgsn/gprs_gb.h b/include/osmocom/sgsn/gprs_gb.h index 461eee31..c98dd344 100644 --- a/include/osmocom/sgsn/gprs_gb.h +++ b/include/osmocom/sgsn/gprs_gb.h @@ -12,3 +12,9 @@ void gprs_gb_recv_pdu(struct sgsn_mm_ctx *mmctx); /* page a MS in its routing area */ int gprs_gb_page_ps_ra(struct sgsn_mm_ctx *mmctx); + +/* called by the bssgp layer to send NS PDUs */ +int gprs_gb_send_cb(void *ctx, struct msgb *msg); + +/* called by the ns layer */ +int gprs_ns_prim_cb(struct osmo_prim_hdr *oph, void *ctx); diff --git a/include/osmocom/sgsn/gprs_gb_parse.h b/include/osmocom/sgsn/gprs_gb_parse.h index 9f43faed..58de17f8 100644 --- a/include/osmocom/sgsn/gprs_gb_parse.h +++ b/include/osmocom/sgsn/gprs_gb_parse.h @@ -51,6 +51,8 @@ int gprs_gb_parse_llc(uint8_t *llc, size_t llc_len, int gprs_gb_parse_bssgp(uint8_t *bssgp, size_t bssgp_len, struct gprs_gb_parse_context *parse_ctx); +int gprs_gb_parse_tlli(const uint8_t *bssgp, size_t bssgp_len, uint32_t *tlli); + const char *gprs_gb_message_name(const struct gprs_gb_parse_context *parse_ctx, const char *default_msg_name); diff --git a/include/osmocom/sgsn/sgsn.h b/include/osmocom/sgsn/sgsn.h index f5ff524d..d9ef938f 100644 --- a/include/osmocom/sgsn/sgsn.h +++ b/include/osmocom/sgsn/sgsn.h @@ -3,8 +3,9 @@ #include <osmocom/core/msgb.h> +#include <osmocom/core/select.h> #include <osmocom/crypt/gprs_cipher.h> -#include <osmocom/gprs/gprs_ns.h> +#include <osmocom/gprs/gprs_ns2.h> #include <osmocom/sgsn/gprs_sgsn.h> #include <osmocom/gsm/oap_client.h> #include <osmocom/gsupclient/gsup_client.h> @@ -69,7 +70,7 @@ struct sgsn_config { struct sockaddr_in gtp_listenaddr; /* misc */ - struct gprs_ns_inst *nsi; + struct gprs_ns2_inst *nsi; enum sgsn_auth_policy auth_policy; enum gprs_ciph_algo cipher; @@ -157,7 +158,7 @@ char *sgsn_gtp_ntoa(struct ul16_t *ul); /* sgsn.c */ /* Main input function for Gb proxy */ -int sgsn_rcvmsg(struct msgb *msg, struct gprs_nsvc *nsvc, uint16_t ns_bvci); +int sgsn_rcvmsg(struct msgb *msg, struct gprs_ns2_vc *nsvc, uint16_t ns_bvci); /* sgsn_libgtp.c */ struct sgsn_pdp_ctx *sgsn_create_pdp_ctx(struct sgsn_ggsn_ctx *ggsn, diff --git a/osmoappdesc.py b/osmoappdesc.py index e91043f9..1fccafd7 100644 --- a/osmoappdesc.py +++ b/osmoappdesc.py @@ -16,8 +16,7 @@ app_configs = { - "gbproxy": ["doc/examples/osmo-gbproxy/osmo-gbproxy.cfg", - "doc/examples/osmo-gbproxy/osmo-gbproxy-legacy.cfg"], + "gbproxy": ["doc/examples/osmo-gbproxy/osmo-gbproxy.cfg"], "sgsn": ["doc/examples/osmo-sgsn/osmo-sgsn.cfg"], "gtphub": ["doc/examples/osmo-gtphub/osmo-gtphub-1iface.cfg"] } diff --git a/src/gbproxy/Makefile.am b/src/gbproxy/Makefile.am index 6876f68a..f8a87732 100644 --- a/src/gbproxy/Makefile.am +++ b/src/gbproxy/Makefile.am @@ -27,8 +27,6 @@ osmo_gbproxy_SOURCES = \ gb_proxy_main.c \ gb_proxy_vty.c \ gb_proxy_ctrl.c \ - gb_proxy_patch.c \ - gb_proxy_tlli.c \ gb_proxy_peer.c \ $(NULL) osmo_gbproxy_LDADD = \ diff --git a/src/gbproxy/gb_proxy.c b/src/gbproxy/gb_proxy.c index 3f471ff8..1dc3114b 100644 --- a/src/gbproxy/gb_proxy.c +++ b/src/gbproxy/gb_proxy.c @@ -1,6 +1,6 @@ /* NS-over-IP proxy */ -/* (C) 2010 by Harald Welte <laforge@gnumonks.org> +/* (C) 2010-2020 by Harald Welte <laforge@gnumonks.org> * (C) 2010-2013 by On-Waves * (C) 2013 by Holger Hans Peter Freyther * All Rights Reserved @@ -31,14 +31,22 @@ #include <arpa/inet.h> #include <time.h> +#include <osmocom/core/hashtable.h> +#include <osmocom/core/logging.h> +#include <osmocom/core/linuxlist.h> #include <osmocom/core/talloc.h> #include <osmocom/core/select.h> #include <osmocom/core/rate_ctr.h> #include <osmocom/core/stats.h> +#include <osmocom/core/utils.h> -#include <osmocom/gprs/gprs_ns.h> +#include <osmocom/gprs/gprs_ns2.h> #include <osmocom/gprs/gprs_bssgp.h> +#include <osmocom/gprs/gprs_bssgp2.h> +#include <osmocom/gprs/gprs_bssgp_bss.h> +#include <osmocom/gprs/bssgp_bvc_fsm.h> +#include <osmocom/gsm/gsm23236.h> #include <osmocom/gsm/gsm_utils.h> #include <osmocom/sgsn/signal.h> @@ -75,23 +83,22 @@ static const struct rate_ctr_group_desc global_ctrg_desc = { .class_id = OSMO_STATS_CLASS_GLOBAL, }; -static int gbprox_relay2peer(struct msgb *old_msg, struct gbproxy_peer *peer, - uint16_t ns_bvci); -static int gbprox_relay2sgsn(struct gbproxy_config *cfg, struct msgb *old_msg, - uint16_t ns_bvci, uint16_t sgsn_nsei); -static void gbproxy_reset_imsi_acquisition(struct gbproxy_link_info* link_info); +static int gbprox_relay2peer(struct msgb *old_msg, struct gbproxy_bvc *bvc, + uint16_t ns_bvci); + -static int check_peer_nsei(struct gbproxy_peer *peer, uint16_t nsei) +/* generate BVC-STATUS message with cause value derived from TLV-parser error */ +static int tx_status_from_tlvp(enum osmo_tlv_parser_error tlv_p_err, struct msgb *orig_msg) { - if (peer->nsei != nsei) { - LOGP(DGPRS, LOGL_NOTICE, "Peer entry doesn't match current NSEI " - "BVCI=%u via NSEI=%u (expected NSEI=%u)\n", - peer->bvci, nsei, peer->nsei); - rate_ctr_inc(&peer->ctrg->ctr[GBPROX_PEER_CTR_INV_NSEI]); - return 0; + uint8_t bssgp_cause; + switch (tlv_p_err) { + case OSMO_TLVP_ERR_MAND_IE_MISSING: + bssgp_cause = BSSGP_CAUSE_MISSING_MAND_IE; + break; + default: + bssgp_cause = BSSGP_CAUSE_PROTO_ERR_UNSPEC; } - - return 1; + return bssgp_tx_status(bssgp_cause, NULL, orig_msg); } /* strip off the NS header */ @@ -101,1145 +108,1107 @@ static void strip_ns_hdr(struct msgb *msg) msgb_pull(msg, strip_len); } -/* Transmit Chapter 9.2.10 Identity Request */ -static void gprs_put_identity_req(struct msgb *msg, uint8_t id_type) +#if 0 +/* feed a message down the NS-VC associated with the specified bvc */ +static int gbprox_relay2sgsn(struct gbproxy_config *cfg, struct msgb *old_msg, + uint16_t ns_bvci, uint16_t sgsn_nsei) { - struct gsm48_hdr *gh; - - id_type &= GSM_MI_TYPE_MASK; - - gh = (struct gsm48_hdr *) msgb_put(msg, sizeof(*gh) + 1); - gh->proto_discr = GSM48_PDISC_MM_GPRS; - gh->msg_type = GSM48_MT_GMM_ID_REQ; - gh->data[0] = id_type; -} + /* create a copy of the message so the old one can + * be free()d safely when we return from gbprox_rcvmsg() */ + struct gprs_ns2_inst *nsi = cfg->nsi; + struct osmo_gprs_ns2_prim nsp = {}; + struct msgb *msg = bssgp_msgb_copy(old_msg, "msgb_relay2sgsn"); + int rc; -/* Transmit Chapter 9.4.6.2 Detach Accept (mobile originated detach) */ -static void gprs_put_mo_detach_acc(struct msgb *msg) -{ - struct gsm48_hdr *gh; + DEBUGP(DGPRS, "NSE(%05u/BSS)-BVC(%05u) proxying BTS->SGSN NSE(%05u/SGSN)\n", + msgb_nsei(msg), ns_bvci, sgsn_nsei); - gh = (struct gsm48_hdr *) msgb_put(msg, sizeof(*gh) + 1); - gh->proto_discr = GSM48_PDISC_MM_GPRS; - gh->msg_type = GSM48_MT_GMM_DETACH_ACK; - gh->data[0] = 0; /* no force to standby */ -} + nsp.bvci = ns_bvci; + nsp.nsei = sgsn_nsei; -static void gprs_push_llc_ui(struct msgb *msg, - int is_uplink, unsigned sapi, unsigned nu) -{ - const uint8_t e_bit = 0; - const uint8_t pm_bit = 1; - const uint8_t cr_bit = is_uplink ? 0 : 1; - uint8_t *llc; - uint8_t *fcs_field; - uint32_t fcs; - - nu &= 0x01ff; /* 9 Bit */ - - llc = msgb_push(msg, 3); - llc[0] = (cr_bit << 6) | (sapi & 0x0f); - llc[1] = 0xc0 | (nu >> 6); /* UI frame */ - llc[2] = (nu << 2) | ((e_bit & 1) << 1) | (pm_bit & 1); - - fcs = gprs_llc_fcs(llc, msgb_length(msg)); - fcs_field = msgb_put(msg, 3); - fcs_field[0] = (uint8_t)(fcs >> 0); - fcs_field[1] = (uint8_t)(fcs >> 8); - fcs_field[2] = (uint8_t)(fcs >> 16); + strip_ns_hdr(msg); + osmo_prim_init(&nsp.oph, SAP_NS, PRIM_NS_UNIT_DATA, + PRIM_OP_REQUEST, msg); + rc = gprs_ns2_recv_prim(nsi, &nsp.oph); + if (rc < 0) + rate_ctr_inc(&cfg->ctrg->ctr[GBPROX_GLOB_CTR_TX_ERR_SGSN]); + return rc; } +#endif -static void gprs_push_bssgp_dl_unitdata(struct msgb *msg, - uint32_t tlli) +/* feed a message down the NSE */ +static int gbprox_relay2nse(struct msgb *old_msg, struct gbproxy_nse *nse, + uint16_t ns_bvci) { - struct bssgp_ud_hdr *budh; - uint8_t *llc = msgb_data(msg); - size_t llc_size = msgb_length(msg); - const size_t llc_ie_hdr_size = 3; - const uint8_t qos_profile[] = {0x00, 0x50, 0x20}; /* hard-coded */ - const uint8_t lifetime[] = {0x02, 0x58}; /* 6s hard-coded */ - - const size_t bssgp_overhead = sizeof(*budh) + - TVLV_GROSS_LEN(sizeof(lifetime)) + llc_ie_hdr_size; - uint8_t *ie; - uint32_t tlli_be = htonl(tlli); + OSMO_ASSERT(nse); + OSMO_ASSERT(nse->cfg); - budh = (struct bssgp_ud_hdr *)msgb_push(msg, bssgp_overhead); - - budh->pdu_type = BSSGP_PDUT_DL_UNITDATA; - memcpy(&budh->tlli, &tlli_be, sizeof(budh->tlli)); - memcpy(&budh->qos_profile, qos_profile, sizeof(budh->qos_profile)); + /* create a copy of the message so the old one can + * be free()d safely when we return from gbprox_rcvmsg() */ + struct gprs_ns2_inst *nsi = nse->cfg->nsi; + struct osmo_gprs_ns2_prim nsp = {}; + struct msgb *msg = bssgp_msgb_copy(old_msg, "msgb_relay2nse"); + uint32_t tlli; + int rc; - ie = budh->data; - tvlv_put(ie, BSSGP_IE_PDU_LIFETIME, sizeof(lifetime), lifetime); - ie += TVLV_GROSS_LEN(sizeof(lifetime)); + DEBUGP(DGPRS, "NSE(%05u/%s)-BVC(%05u/??) proxying to NSE(%05u/%s)\n", msgb_nsei(msg), + !nse->sgsn_facing ? "SGSN" : "BSS", ns_bvci, nse->nsei, nse->sgsn_facing ? "SGSN" : "BSS"); - /* Note: Add alignment before the LLC IE if inserting other IE */ + nsp.bvci = ns_bvci; + nsp.nsei = nse->nsei; - *(ie++) = BSSGP_IE_LLC_PDU; - *(ie++) = llc_size / 256; - *(ie++) = llc_size % 256; + /* Strip the old NS header, it will be replaced with a new one */ + strip_ns_hdr(msg); - OSMO_ASSERT(ie == llc); + /* TS 48.018 Section 5.4.2: The link selector parameter is + * defined in 3GPP TS 48.016. At one side of the Gb interface, + * all BSSGP UNITDATA PDUs related to an MS shall be passed with + * the same LSP, e.g. the LSP contains the MS's TLLI, to the + * underlying network service. */ + if (gprs_gb_parse_tlli(msgb_data(msg), msgb_length(msg), &tlli) == 1) + nsp.u.unitdata.link_selector = tlli; + + osmo_prim_init(&nsp.oph, SAP_NS, PRIM_NS_UNIT_DATA, + PRIM_OP_REQUEST, msg); + rc = gprs_ns2_recv_prim(nsi, &nsp.oph); + /* FIXME: We need a counter group for gbproxy_nse */ + //if (rc < 0) + // rate_ctr_inc(&bvc->ctrg->ctr[GBPROX_PEER_CTR_TX_ERR]); - msgb_bssgph(msg) = (uint8_t *)budh; - msgb_tlli(msg) = tlli; + return rc; } -/* update peer according to the BSS message */ -static void gbprox_update_current_raid(uint8_t *raid_enc, - struct gbproxy_peer *peer, - const char *log_text) +/* feed a message down the NS-VC associated with the specified bvc */ +static int gbprox_relay2peer(struct msgb *old_msg, struct gbproxy_bvc *bvc, + uint16_t ns_bvci) { - struct gbproxy_patch_state *state = &peer->patch_state; - const struct osmo_plmn_id old_plmn = state->local_plmn; - struct gprs_ra_id raid; + int rc; + struct gbproxy_nse *nse = bvc->nse; + OSMO_ASSERT(nse); - if (!raid_enc) - return; + rc = gbprox_relay2nse(old_msg, nse, ns_bvci); + if (rc < 0) + rate_ctr_inc(&bvc->ctrg->ctr[GBPROX_PEER_CTR_TX_ERR]); - gsm48_parse_ra(&raid, raid_enc); + return rc; +} - /* save source side MCC/MNC */ - if (!peer->cfg->core_plmn.mcc || raid.mcc == peer->cfg->core_plmn.mcc) { - state->local_plmn.mcc = 0; - } else { - state->local_plmn.mcc = raid.mcc; - } +int bssgp_prim_cb(struct osmo_prim_hdr *oph, void *ctx) +{ + return 0; +} - if (!peer->cfg->core_plmn.mnc - || !osmo_mnc_cmp(raid.mnc, raid.mnc_3_digits, - peer->cfg->core_plmn.mnc, peer->cfg->core_plmn.mnc_3_digits)) { - state->local_plmn.mnc = 0; - state->local_plmn.mnc_3_digits = false; - } else { - state->local_plmn.mnc = raid.mnc; - state->local_plmn.mnc_3_digits = raid.mnc_3_digits; - } - if (osmo_plmn_cmp(&old_plmn, &state->local_plmn)) - LOGP(DGPRS, LOGL_NOTICE, - "Patching RAID %sactivated, msg: %s, " - "local: %s, core: %s\n", - state->local_plmn.mcc || state->local_plmn.mnc ? - "" : "de", - log_text, - osmo_plmn_name(&state->local_plmn), - osmo_plmn_name2(&peer->cfg->core_plmn)); -} +/*********************************************************************** + * PTP BVC handling + ***********************************************************************/ -uint32_t gbproxy_make_bss_ptmsi(struct gbproxy_peer *peer, - uint32_t sgsn_ptmsi) +/* FIXME: Handle the tlli NULL case correctly, + * This function should take a generic selector + * and choose an sgsn based on that + */ +static struct gbproxy_sgsn *gbproxy_select_sgsn(struct gbproxy_config *cfg, const uint32_t *tlli) { - uint32_t bss_ptmsi; - int max_retries = 23, rc = 0; - if (!peer->cfg->patch_ptmsi) { - bss_ptmsi = sgsn_ptmsi; - } else { - do { - rc = osmo_get_rand_id((uint8_t *) &bss_ptmsi, sizeof(bss_ptmsi)); - if (rc < 0) { - bss_ptmsi = GSM_RESERVED_TMSI; - break; - } + struct gbproxy_sgsn *sgsn = NULL; + struct gbproxy_sgsn *sgsn_avoid = NULL; - bss_ptmsi = bss_ptmsi | GSM23003_TMSI_SGSN_MASK; + int tlli_type; + int16_t nri; + bool null_nri = false; - if (gbproxy_link_info_by_ptmsi(peer, bss_ptmsi)) - bss_ptmsi = GSM_RESERVED_TMSI; - } while (bss_ptmsi == GSM_RESERVED_TMSI && max_retries--); + if (!tlli) { + sgsn = llist_first_entry(&cfg->sgsns, struct gbproxy_sgsn, list); + if (!sgsn) { + return NULL; + } + LOGPSGSN(sgsn, LOGL_INFO, "Could not get TLLI, using first SGSN\n"); + return sgsn; } - if (bss_ptmsi == GSM_RESERVED_TMSI) - LOGP(DGPRS, LOGL_ERROR, "Failed to allocate a BSS P-TMSI: %d (%s)\n", rc, strerror(-rc)); - - return bss_ptmsi; -} + if (cfg->pool.nri_bitlen == 0) { + /* Pooling is disabled */ + sgsn = llist_first_entry(&cfg->sgsns, struct gbproxy_sgsn, list); + if (!sgsn) { + return NULL; + } -uint32_t gbproxy_make_sgsn_tlli(struct gbproxy_peer *peer, - struct gbproxy_link_info *link_info, - uint32_t bss_tlli) -{ - uint32_t sgsn_tlli; - int max_retries = 23, rc = 0; - if (!peer->cfg->patch_ptmsi) { - sgsn_tlli = bss_tlli; - } else if (link_info->sgsn_tlli.ptmsi != GSM_RESERVED_TMSI && - gprs_tlli_type(bss_tlli) == TLLI_FOREIGN) { - sgsn_tlli = gprs_tmsi2tlli(link_info->sgsn_tlli.ptmsi, - TLLI_FOREIGN); - } else if (link_info->sgsn_tlli.ptmsi != GSM_RESERVED_TMSI && - gprs_tlli_type(bss_tlli) == TLLI_LOCAL) { - sgsn_tlli = gprs_tmsi2tlli(link_info->sgsn_tlli.ptmsi, - TLLI_LOCAL); + LOGPSGSN(sgsn, LOGL_INFO, "Pooling disabled, using first configured SGSN\n"); } else { - do { - /* create random TLLI, 0b01111xxx... */ - rc = osmo_get_rand_id((uint8_t *) &sgsn_tlli, sizeof(sgsn_tlli)); - if (rc < 0) { - sgsn_tlli = 0; - break; + /* Pooling is enabled, try to use the NRI for routing to an SGSN + * See 3GPP TS 23.236 Ch. 5.3.2 */ + tlli_type = gprs_tlli_type(*tlli); + if (tlli_type == TLLI_LOCAL || tlli_type == TLLI_FOREIGN) { + /* Only get/use the NRI if tlli type is local */ + osmo_tmsi_nri_v_get(&nri, *tlli, cfg->pool.nri_bitlen); + if (nri >= 0) { + /* Get the SGSN for the NRI */ + sgsn = gbproxy_sgsn_by_nri(cfg, nri, &null_nri); + if (sgsn && !null_nri) + return sgsn; + /* If the NRI is the null NRI, we need to avoid the chosen SGSN */ + if (null_nri && sgsn) { + sgsn_avoid = sgsn; + } + } else { + /* We couldn't get the NRI from the TLLI */ + LOGP(DGPRS, LOGL_ERROR, "Could not extract NRI from local TLLI %08x\n", *tlli); } - - sgsn_tlli = (sgsn_tlli & 0x7fffffff) | 0x78000000; - - if (gbproxy_link_info_by_any_sgsn_tlli(peer, sgsn_tlli)) - sgsn_tlli = 0; - } while (!sgsn_tlli && max_retries--); + } else { + LOGP(DGPRS, LOGL_INFO, "TLLI %08x is neither local nor foreign, not routing by NRI\n", *tlli); + } } - if (!sgsn_tlli) - LOGP(DGPRS, LOGL_ERROR, "Failed to allocate an SGSN TLLI: %d (%s)\n", rc, strerror(-rc)); - - return sgsn_tlli; -} + /* If we haven't found an SGSN yet we need to choose one, but avoid the one in sgsn_avoid + * NOTE: This function is not stable if the number of SGSNs or allow_attach changes + * We could implement TLLI tracking here, but 3GPP TS 23.236 Ch. 5.3.2 (see NOTE) argues that + * we can just wait for the MS to reattempt the procedure. + */ + if (!sgsn) + sgsn = gbproxy_sgsn_by_tlli(cfg, sgsn_avoid, *tlli); + + if (!sgsn) { + LOGP(DGPRS, LOGL_ERROR, "No suitable SGSN found for TLLI %u\n", *tlli); + return NULL; + } -void gbproxy_reset_link(struct gbproxy_link_info *link_info) -{ - gbproxy_reset_imsi_acquisition(link_info); + return sgsn; } -/* Returns != 0 iff IMSI acquisition was in progress */ -static int gbproxy_restart_imsi_acquisition(struct gbproxy_link_info* link_info) +/*! Find the correct gbproxy_bvc given a cell and an SGSN + * \param[in] cfg The gbproxy configuration + * \param[in] cell The cell the message belongs to + * \param[in] tlli An optional TLLI used for tracking + * \return Returns 0 on success, otherwise a negative value + */ +static struct gbproxy_bvc *gbproxy_select_sgsn_bvc(struct gbproxy_config *cfg, struct gbproxy_cell *cell, const uint32_t *tlli) { - int in_progress = 0; - if (!link_info) - return 0; - - if (link_info->imsi_acq_pending) - in_progress = 1; + struct gbproxy_sgsn *sgsn; + struct gbproxy_bvc *sgsn_bvc = NULL; + int i; + + sgsn = gbproxy_select_sgsn(cfg, tlli); + if (!sgsn) { + LOGPCELL(cell, LOGL_ERROR, "Could not find any SGSN, dropping message!\n"); + return NULL; + } - gbproxy_link_info_discard_messages(link_info); - link_info->imsi_acq_pending = false; + /* Get the BVC for this SGSN/NSE */ + for (i = 0; i < ARRAY_SIZE(cell->sgsn_bvc); i++) { + sgsn_bvc = cell->sgsn_bvc[i]; + if (!sgsn_bvc) + continue; + if (sgsn->nse != sgsn_bvc->nse) + continue; - return in_progress; -} + return sgsn_bvc; + } -static void gbproxy_reset_imsi_acquisition(struct gbproxy_link_info* link_info) -{ - gbproxy_restart_imsi_acquisition(link_info); - link_info->vu_gen_tx_bss = GBPROXY_INIT_VU_GEN_TX; + /* This shouldn't happen */ + LOGPCELL(cell, LOGL_ERROR, "Could not find matching BVC for SGSN %s, dropping message!\n", sgsn->name); + return NULL; } -/* Got identity response with IMSI, assuming the request had - * been generated by the gbproxy */ -static int gbproxy_flush_stored_messages(struct gbproxy_peer *peer, - time_t now, - struct gbproxy_link_info* link_info) +/*! Send a message to the next SGSN, possibly ignoring the null SGSN + * route an uplink message on a PTP-BVC to a SGSN using the TLLI + * \param[in] cell The cell the message belongs to + * \param[in] msg The BSSGP message + * \param[in] null_sgsn If not NULL then avoid this SGSN (because this message contains its null NRI) + * \param[in] tlli An optional TLLI used for tracking + * \return Returns 0 on success, otherwise a negative value + */ +static int gbprox_bss2sgsn_tlli(struct gbproxy_cell *cell, struct msgb *msg, const uint32_t *tlli, + bool sig_bvci) { - int rc; - struct msgb *stored_msg; - - /* Patch and flush stored messages towards the SGSN */ - while ((stored_msg = msgb_dequeue_count(&link_info->stored_msgs, - &link_info->stored_msgs_len))) { - struct gprs_gb_parse_context tmp_parse_ctx = {0}; - tmp_parse_ctx.to_bss = 0; - tmp_parse_ctx.peer_nsei = msgb_nsei(stored_msg); - int len_change = 0; - - gprs_gb_parse_bssgp(msgb_bssgph(stored_msg), - msgb_bssgp_len(stored_msg), - &tmp_parse_ctx); - gbproxy_patch_bssgp(stored_msg, msgb_bssgph(stored_msg), - msgb_bssgp_len(stored_msg), - peer, link_info, &len_change, - &tmp_parse_ctx); - - rc = gbproxy_update_link_state_after(peer, link_info, now, - &tmp_parse_ctx); - if (rc == 1) { - LOGP(DLLC, LOGL_NOTICE, "link_info deleted while flushing stored messages\n"); - msgb_free(stored_msg); - return -1; - } + struct gbproxy_config *cfg = cell->cfg; + struct gbproxy_bvc *sgsn_bvc; - rc = gbprox_relay2sgsn(peer->cfg, stored_msg, - msgb_bvci(stored_msg), link_info->sgsn_nsei); - - if (rc < 0) - LOGP(DLLC, LOGL_ERROR, - "NSEI=%d(BSS) failed to send stored message " - "(%s)\n", - tmp_parse_ctx.peer_nsei, - tmp_parse_ctx.llc_msg_name ? - tmp_parse_ctx.llc_msg_name : "BSSGP"); - msgb_free(stored_msg); + sgsn_bvc = gbproxy_select_sgsn_bvc(cfg, cell, tlli); + if (!sgsn_bvc) { + LOGPCELL(cell, LOGL_NOTICE, "Could not find any SGSN for TLLI %u, dropping message!\n", *tlli); + return -EINVAL; } - return 0; + return gbprox_relay2peer(msg, sgsn_bvc, sig_bvci ? 0 : sgsn_bvc->bvci); } -static int gbproxy_gsm48_to_peer(struct gbproxy_peer *peer, - struct gbproxy_link_info* link_info, - uint16_t bvci, - struct msgb *msg /* Takes msg ownership */) +/* Receive an incoming PTP message from a BSS-side NS-VC */ +static int gbprox_rx_ptp_from_bss(struct gbproxy_nse *nse, struct msgb *msg, uint16_t ns_bvci) { + struct bssgp_normal_hdr *bgph = (struct bssgp_normal_hdr *) msgb_bssgph(msg); + const char *pdut_name = osmo_tlv_prot_msg_name(&osmo_pdef_bssgp, bgph->pdu_type); + struct gbproxy_bvc *bss_bvc; + struct tlv_parsed tp; + char log_pfx[32]; + uint32_t tlli; int rc; - /* Workaround to avoid N(U) collisions and to enable a restart - * of the IMSI acquisition procedure. This will work unless the - * SGSN has an initial V(UT) within [256-32, 256+n_retries] - * (see GSM 04.64, 8.4.2). */ - gprs_push_llc_ui(msg, 0, GPRS_SAPI_GMM, link_info->vu_gen_tx_bss); - link_info->vu_gen_tx_bss = (link_info->vu_gen_tx_bss + 1) % 512; - - gprs_push_bssgp_dl_unitdata(msg, link_info->tlli.current); - rc = gbprox_relay2peer(msg, peer, bvci); - msgb_free(msg); - return rc; -} - -static void gbproxy_acquire_imsi(struct gbproxy_peer *peer, - struct gbproxy_link_info* link_info, - uint16_t bvci) -{ - struct msgb *idreq_msg; - - /* Send IDENT REQ */ - idreq_msg = gsm48_msgb_alloc_name("GSM 04.08 ACQ IMSI"); - gprs_put_identity_req(idreq_msg, GSM_MI_TYPE_IMSI); - gbproxy_gsm48_to_peer(peer, link_info, bvci, idreq_msg); -} - -static void gbproxy_tx_detach_acc(struct gbproxy_peer *peer, - struct gbproxy_link_info* link_info, - uint16_t bvci) -{ - struct msgb *detacc_msg; + snprintf(log_pfx, sizeof(log_pfx), "NSE(%05u/BSS)-BVC(%05u/??)", nse->nsei, ns_bvci); - /* Send DETACH ACC */ - detacc_msg = gsm48_msgb_alloc_name("GSM 04.08 DET ACC"); - gprs_put_mo_detach_acc(detacc_msg); - gbproxy_gsm48_to_peer(peer, link_info, bvci, detacc_msg); -} - -/* Return != 0 iff msg still needs to be processed */ -static int gbproxy_imsi_acquisition(struct gbproxy_peer *peer, - struct msgb *msg, - time_t now, - struct gbproxy_link_info* link_info, - struct gprs_gb_parse_context *parse_ctx) -{ - struct msgb *stored_msg; - - if (!link_info) - return 1; - - if (!link_info->imsi_acq_pending && link_info->imsi_len > 0) - return 1; - - if (parse_ctx->g48_hdr) - switch (parse_ctx->g48_hdr->msg_type) - { - case GSM48_MT_GMM_RA_UPD_REQ: - case GSM48_MT_GMM_ATTACH_REQ: - if (gbproxy_restart_imsi_acquisition(link_info)) { - LOGP(DLLC, LOGL_INFO, - "NSEI=%d(BSS) IMSI acquisition was in progress " - "when receiving an %s.\n", - msgb_nsei(msg), parse_ctx->llc_msg_name); - } - break; - case GSM48_MT_GMM_DETACH_REQ: - /* Nothing has been sent to the SGSN yet */ - if (link_info->imsi_acq_pending) { - LOGP(DLLC, LOGL_INFO, - "NSEI=%d(BSS) IMSI acquisition was in progress " - "when receiving a DETACH_REQ.\n", - msgb_nsei(msg)); - } - if (!parse_ctx->invalidate_tlli) { - LOGP(DLLC, LOGL_INFO, - "NSEI=%d(BSS) IMSI not yet acquired, " - "faking a DETACH_ACC.\n", - msgb_nsei(msg)); - gbproxy_tx_detach_acc(peer, link_info, msgb_bvci(msg)); - parse_ctx->invalidate_tlli = 1; - } - gbproxy_reset_imsi_acquisition(link_info); - gbproxy_update_link_state_after(peer, link_info, now, - parse_ctx); - return 0; - } + LOGP(DGPRS, LOGL_DEBUG, "%s Rx %s\n", log_pfx, pdut_name); - if (link_info->imsi_acq_pending && link_info->imsi_len > 0) { - int is_ident_resp = - parse_ctx->g48_hdr && - gsm48_hdr_pdisc(parse_ctx->g48_hdr) == GSM48_PDISC_MM_GPRS && - gsm48_hdr_msg_type(parse_ctx->g48_hdr) == GSM48_MT_GMM_ID_RESP; - - LOGP(DLLC, LOGL_DEBUG, - "NSEI=%d(BSS) IMSI acquisition succeeded, " - "flushing stored messages\n", - msgb_nsei(msg)); - /* The IMSI is now available. If flushing the messages fails, - * then link_info has been deleted and we should return - * immediately. */ - if (gbproxy_flush_stored_messages(peer, now, link_info) < 0) - return 0; - - gbproxy_reset_imsi_acquisition(link_info); - - /* This message is most probably the response to the ident - * request sent by gbproxy_acquire_imsi(). Don't forward it to - * the SGSN. */ - return !is_ident_resp; + if (ns_bvci == 0 || ns_bvci == 1) { + LOGP(DGPRS, LOGL_NOTICE, "%s BVCI=%05u is not PTP\n", log_pfx, ns_bvci); + return bssgp_tx_status(BSSGP_CAUSE_PROTO_ERR_UNSPEC, NULL, msg); } - /* The message cannot be processed since the IMSI is still missing */ + if (!(bssgp_pdu_type_flags(bgph->pdu_type) & BSSGP_PDUF_PTP)) { + LOGP(DGPRS, LOGL_NOTICE, "%s %s not allowed in PTP BVC\n", log_pfx, pdut_name); + return bssgp_tx_status(BSSGP_CAUSE_PROTO_ERR_UNSPEC, NULL, msg); + } - /* If queue is getting too large, drop oldest msgb before adding new one */ - if (peer->cfg->stored_msgs_max_len > 0) { - int exceeded_max_len = link_info->stored_msgs_len - + 1 - peer->cfg->stored_msgs_max_len; + if (!(bssgp_pdu_type_flags(bgph->pdu_type) & BSSGP_PDUF_UL)) { + LOGP(DGPRS, LOGL_NOTICE, "%s %s not allowed in uplink direction\n", log_pfx, pdut_name); + return bssgp_tx_status(BSSGP_CAUSE_PROTO_ERR_UNSPEC, NULL, msg); + } - for (; exceeded_max_len > 0; exceeded_max_len--) { - struct msgb *msgb_drop; - msgb_drop = msgb_dequeue_count(&link_info->stored_msgs, - &link_info->stored_msgs_len); - LOGP(DLLC, LOGL_INFO, - "NSEI=%d(BSS) Dropping stored msgb from list " - "(!acq imsi, length %d, max_len exceeded)\n", - msgb_nsei(msgb_drop), link_info->stored_msgs_len); + bss_bvc = gbproxy_bvc_by_bvci(nse, ns_bvci); + if (!bss_bvc) { + LOGP(DGPRS, LOGL_NOTICE, "%s %s - Didn't find BVC for PTP message, discarding\n", + log_pfx, pdut_name); + return bssgp_tx_status(BSSGP_CAUSE_UNKNOWN_BVCI, &ns_bvci, msg); + } - msgb_free(msgb_drop); + /* UL_UNITDATA has a different header than all other uplink PDUs */ + if (bgph->pdu_type == BSSGP_PDUT_UL_UNITDATA) { + const struct bssgp_ud_hdr *budh = (struct bssgp_ud_hdr *) msgb_bssgph(msg); + if (msgb_bssgp_len(msg) < sizeof(*budh)) + return bssgp_tx_status(BSSGP_CAUSE_INV_MAND_INF, NULL, msg); + rc = osmo_tlv_prot_parse(&osmo_pdef_bssgp, &tp, 1, bgph->pdu_type, budh->data, + msgb_bssgp_len(msg) - sizeof(*budh), 0, 0, DGPRS, log_pfx); + /* populate TLLI from the fixed headser into the TLV-parsed array so later code + * doesn't have to worry where the TLLI came from */ + tp.lv[BSSGP_IE_TLLI].len = 4; + tp.lv[BSSGP_IE_TLLI].val = (const uint8_t *) &budh->tlli; + } else { + rc = osmo_tlv_prot_parse(&osmo_pdef_bssgp, &tp, 1, bgph->pdu_type, bgph->data, + msgb_bssgp_len(msg) - sizeof(*bgph), 0, 0, DGPRS, log_pfx); + } + if (rc < 0) { + rate_ctr_inc(&nse->cfg->ctrg->ctr[GBPROX_GLOB_CTR_PROTO_ERR_BSS]); + return tx_status_from_tlvp(rc, msg); + } + /* hack to get both msg + tlv_parsed passed via osmo_fsm_inst_dispatch */ + msgb_bcid(msg) = (void *)&tp; + + switch (bgph->pdu_type) { + case BSSGP_PDUT_UL_UNITDATA: + case BSSGP_PDUT_RA_CAPA_UPDATE: + case BSSGP_PDUT_FLOW_CONTROL_MS: + case BSSGP_PDUT_DOWNLOAD_BSS_PFC: + case BSSGP_PDUT_CREATE_BSS_PFC_ACK: + case BSSGP_PDUT_CREATE_BSS_PFC_NACK: + case BSSGP_PDUT_MODIFY_BSS_PFC_ACK: + case BSSGP_PDUT_DELETE_BSS_PFC_ACK: + case BSSGP_PDUT_FLOW_CONTROL_PFC: + case BSSGP_PDUT_DELETE_BSS_PFC_REQ: + case BSSGP_PDUT_PS_HO_REQUIRED: + case BSSGP_PDUT_PS_HO_REQUEST_ACK: + case BSSGP_PDUT_PS_HO_REQUEST_NACK: + case BSSGP_PDUT_PS_HO_COMPLETE: + case BSSGP_PDUT_PS_HO_CANCEL: + /* We can route based on TLLI-NRI */ + tlli = osmo_load32be(TLVP_VAL(&tp, BSSGP_IE_TLLI)); + rc = gbprox_bss2sgsn_tlli(bss_bvc->cell, msg, &tlli, false); + break; + case BSSGP_PDUT_RADIO_STATUS: + if (TLVP_PRESENT(&tp, BSSGP_IE_TLLI)) { + tlli = osmo_load32be(TLVP_VAL(&tp, BSSGP_IE_TLLI)); + rc = gbprox_bss2sgsn_tlli(bss_bvc->cell, msg, &tlli, false); + } else if (TLVP_PRESENT(&tp, BSSGP_IE_TMSI)) { + /* we treat the TMSI like a TLLI and extract the NRI from it */ + tlli = osmo_load32be(TLVP_VAL(&tp, BSSGP_IE_TMSI)); + /* Convert the TMSI into a FOREIGN TLLI so it is routed appropriately */ + tlli = gprs_tmsi2tlli(tlli, TLLI_FOREIGN); + rc = gbprox_bss2sgsn_tlli(bss_bvc->cell, msg, &tlli, false); + } else if (TLVP_PRESENT(&tp, BSSGP_IE_IMSI)) { + /* FIXME: Use the IMSI as selector? */ + rc = gbprox_bss2sgsn_tlli(bss_bvc->cell, msg, NULL, false); + /* rc = gbprox_bss2sgsn_hashed(bss_bvc->cell, msg, NULL); */ + } else + LOGPBVC(bss_bvc, LOGL_ERROR, "Rx RADIO-STATUS without any of the conditional IEs\n"); + break; + case BSSGP_PDUT_DUMMY_PAGING_PS_RESP: + case BSSGP_PDUT_PAGING_PS_REJECT: + { + /* Route according to IMSI<->NSE cache entry */ + struct osmo_mobile_identity mi; + const uint8_t *mi_data = TLVP_VAL(&tp, BSSGP_IE_IMSI); + uint8_t mi_len = TLVP_LEN(&tp, BSSGP_IE_IMSI); + osmo_mobile_identity_decode(&mi, mi_data, mi_len, false); + nse = gbproxy_nse_by_imsi(nse->cfg, mi.imsi); + if (nse) { + OSMO_ASSERT(nse->sgsn_facing); + rc = gbprox_relay2nse(msg, nse, ns_bvci); + } else { + LOGPBVC(bss_bvc, LOGL_ERROR, "Rx unmatched %s with IMSI %s\n", pdut_name, mi.imsi); } + break; } - - /* Enqueue unpatched messages */ - LOGP(DLLC, LOGL_INFO, - "NSEI=%d(BSS) IMSI acquisition in progress, " - "storing message (%s)\n", - msgb_nsei(msg), - parse_ctx->llc_msg_name ? parse_ctx->llc_msg_name : "BSSGP"); - - stored_msg = bssgp_msgb_copy(msg, "process_bssgp_ul"); - msgb_enqueue_count(&link_info->stored_msgs, stored_msg, - &link_info->stored_msgs_len); - - if (!link_info->imsi_acq_pending) { - LOGP(DLLC, LOGL_INFO, - "NSEI=%d(BSS) IMSI is required but not available, " - "initiating identification procedure (%s)\n", - msgb_nsei(msg), - parse_ctx->llc_msg_name ? parse_ctx->llc_msg_name : "BSSGP"); - - gbproxy_acquire_imsi(peer, link_info, msgb_bvci(msg)); - - /* There is no explicit retransmission handling, the - * implementation relies on the MS doing proper retransmissions - * of the triggering message instead */ - - link_info->imsi_acq_pending = true; + case BSSGP_PDUT_FLOW_CONTROL_BVC: + osmo_fsm_inst_dispatch(bss_bvc->fi, BSSGP_BVCFSM_E_RX_FC_BVC, msg); + break; + case BSSGP_PDUT_STATUS: + /* TODO: Implement by inspecting the contained PDU */ + if (!TLVP_PRESENT(&tp, BSSGP_IE_PDU_IN_ERROR)) + break; + LOGPBVC(bss_bvc, LOGL_ERROR, "Rx %s: Implementation missing\n", pdut_name); + break; } return 0; } -struct gbproxy_peer *gbproxy_find_peer(struct gbproxy_config *cfg, - struct msgb *msg, - struct gprs_gb_parse_context *parse_ctx) +/* Receive an incoming PTP message from a SGSN-side NS-VC */ +static int gbprox_rx_ptp_from_sgsn(struct gbproxy_nse *nse, struct msgb *msg, uint16_t ns_bvci) { - struct gbproxy_peer *peer = NULL; - - if (msgb_bvci(msg) >= 2) - peer = gbproxy_peer_by_bvci(cfg, msgb_bvci(msg)); + struct bssgp_normal_hdr *bgph = (struct bssgp_normal_hdr *) msgb_bssgph(msg); + const char *pdut_name = osmo_tlv_prot_msg_name(&osmo_pdef_bssgp, bgph->pdu_type); + struct gbproxy_bvc *sgsn_bvc, *bss_bvc; + struct tlv_parsed tp; + char log_pfx[32]; + int rc; - if (!peer && !parse_ctx->to_bss) - peer = gbproxy_peer_by_nsei(cfg, msgb_nsei(msg)); + snprintf(log_pfx, sizeof(log_pfx), "NSE(%05u/SGSN)-BVC(%05u/??)", nse->nsei, ns_bvci); - if (!peer) - peer = gbproxy_peer_by_bssgp_tlv(cfg, &parse_ctx->bssgp_tp); + LOGP(DGPRS, LOGL_DEBUG, "%s Rx %s\n", log_pfx, pdut_name); - if (!peer) { - LOGP(DLLC, LOGL_INFO, - "NSEI=%d(%s) patching: didn't find peer for message, " - "PDU %d\n", - msgb_nsei(msg), parse_ctx->to_bss ? "BSS" : "SGSN", - parse_ctx->pdu_type); - /* Increment counter */ - rate_ctr_inc(&cfg->ctrg->ctr[GBPROX_GLOB_CTR_PATCH_PEER_ERR]); + if (ns_bvci == 0 || ns_bvci == 1) { + LOGP(DGPRS, LOGL_NOTICE, "%s BVCI is not PTP\n", log_pfx); + return bssgp_tx_status(BSSGP_CAUSE_PROTO_ERR_UNSPEC, NULL, msg); } - return peer; -} -/* patch BSSGP message */ -static int gbprox_process_bssgp_ul(struct gbproxy_config *cfg, - struct msgb *msg, - struct gbproxy_peer *peer) -{ - struct gprs_gb_parse_context parse_ctx = {0}; - int rc; - int len_change = 0; - time_t now; - struct timespec ts = {0,}; - struct gbproxy_link_info *link_info = NULL; - uint32_t sgsn_nsei = cfg->nsip_sgsn_nsei; - - if (!cfg->core_plmn.mcc && !cfg->core_plmn.mnc && !cfg->core_apn && - !cfg->acquire_imsi && !cfg->patch_ptmsi && !cfg->route_to_sgsn2) - return 1; - - parse_ctx.to_bss = 0; - parse_ctx.peer_nsei = msgb_nsei(msg); - - /* Parse BSSGP/LLC */ - rc = gprs_gb_parse_bssgp(msgb_bssgph(msg), msgb_bssgp_len(msg), - &parse_ctx); - - if (!rc && !parse_ctx.need_decryption) { - LOGP(DGPRS, LOGL_ERROR, - "NSEI=%u(BSS) patching: failed to parse invalid %s message\n", - msgb_nsei(msg), gprs_gb_message_name(&parse_ctx, "NS_UNITDATA")); - gprs_gb_log_parse_context(LOGL_NOTICE, &parse_ctx, "NS_UNITDATA"); - LOGP(DGPRS, LOGL_NOTICE, - "NSEI=%u(BSS) invalid message was: %s\n", - msgb_nsei(msg), msgb_hexdump(msg)); - return 0; + if (!(bssgp_pdu_type_flags(bgph->pdu_type) & BSSGP_PDUF_PTP)) { + LOGP(DGPRS, LOGL_NOTICE, "%s %s not allowed in PTP BVC\n", log_pfx, pdut_name); + return bssgp_tx_status(BSSGP_CAUSE_PROTO_ERR_UNSPEC, NULL, msg); } - /* Get peer */ - if (!peer) - peer = gbproxy_find_peer(cfg, msg, &parse_ctx); - - if (!peer) - return 0; - - - osmo_clock_gettime(CLOCK_MONOTONIC, &ts); - now = ts.tv_sec; - - gbprox_update_current_raid(parse_ctx.bssgp_raid_enc, peer, - parse_ctx.llc_msg_name); - - gprs_gb_log_parse_context(LOGL_DEBUG, &parse_ctx, "NS_UNITDATA"); - - link_info = gbproxy_update_link_state_ul(peer, now, &parse_ctx); - - if (parse_ctx.g48_hdr) { - switch (parse_ctx.g48_hdr->msg_type) { - case GSM48_MT_GMM_ATTACH_REQ: - rate_ctr_inc(&peer->ctrg->ctr[GBPROX_PEER_CTR_ATTACH_REQS]); - break; - case GSM48_MT_GMM_DETACH_REQ: - rate_ctr_inc(&peer->ctrg->ctr[GBPROX_PEER_CTR_DETACH_REQS]); - break; - case GSM48_MT_GMM_ATTACH_COMPL: - rate_ctr_inc(&peer->ctrg->ctr[GBPROX_PEER_CTR_ATTACH_COMPLS]); - break; - case GSM48_MT_GMM_RA_UPD_REQ: - rate_ctr_inc(&peer->ctrg->ctr[GBPROX_PEER_CTR_RA_UPD_REQS]); - break; - case GSM48_MT_GMM_RA_UPD_COMPL: - rate_ctr_inc(&peer->ctrg->ctr[GBPROX_PEER_CTR_RA_UPD_COMPLS]); - break; - case GSM48_MT_GMM_STATUS: - rate_ctr_inc(&peer->ctrg->ctr[GBPROX_PEER_CTR_GMM_STATUS_BSS]); - break; - case GSM48_MT_GSM_ACT_PDP_REQ: - rate_ctr_inc(&peer->ctrg->ctr[GBPROX_PEER_CTR_PDP_ACT_REQS]); - break; - case GSM48_MT_GSM_DEACT_PDP_REQ: - rate_ctr_inc(&peer->ctrg->ctr[GBPROX_PEER_CTR_PDP_DEACT_REQS]); - break; - - default: - break; - } + if (!(bssgp_pdu_type_flags(bgph->pdu_type) & BSSGP_PDUF_DL)) { + LOGP(DGPRS, LOGL_NOTICE, "%s %s not allowed in downlink direction\n", log_pfx, pdut_name); + return bssgp_tx_status(BSSGP_CAUSE_PROTO_ERR_UNSPEC, NULL, msg); } - if (link_info && cfg->route_to_sgsn2) { - if (cfg->acquire_imsi && link_info->imsi_len == 0) - sgsn_nsei = 0xffff; - else if (gbproxy_imsi_matches(cfg, GBPROX_MATCH_ROUTING, - link_info)) - sgsn_nsei = cfg->nsip_sgsn2_nsei; + sgsn_bvc = gbproxy_bvc_by_bvci(nse, ns_bvci); + if (!sgsn_bvc) { + LOGP(DGPRS, LOGL_NOTICE, "%s %s - Didn't find BVC for for PTP message, discarding\n", + log_pfx, pdut_name); + rate_ctr_inc(&nse->cfg->ctrg-> ctr[GBPROX_GLOB_CTR_INV_BVCI]); + return bssgp_tx_status(BSSGP_CAUSE_UNKNOWN_BVCI, &ns_bvci, msg); } - if (link_info) - link_info->sgsn_nsei = sgsn_nsei; - - /* Handle IMSI acquisition */ - if (cfg->acquire_imsi) { - rc = gbproxy_imsi_acquisition(peer, msg, now, link_info, - &parse_ctx); - if (rc <= 0) - return rc; + if (!bssgp_bvc_fsm_is_unblocked(sgsn_bvc->fi)) { + LOGPBVC(sgsn_bvc, LOGL_NOTICE, "Rx %s: Dropping on blocked BVC\n", pdut_name); + rate_ctr_inc(&sgsn_bvc->ctrg->ctr[GBPROX_PEER_CTR_DROPPED]); + return bssgp_tx_status(BSSGP_CAUSE_BVCI_BLOCKED, &ns_bvci, msg); } - gbproxy_patch_bssgp(msg, msgb_bssgph(msg), msgb_bssgp_len(msg), - peer, link_info, &len_change, &parse_ctx); + /* DL_UNITDATA has a different header than all other uplink PDUs */ + if (bgph->pdu_type == BSSGP_PDUT_DL_UNITDATA) { + const struct bssgp_ud_hdr *budh = (struct bssgp_ud_hdr *) msgb_bssgph(msg); + if (msgb_bssgp_len(msg) < sizeof(*budh)) + return bssgp_tx_status(BSSGP_CAUSE_INV_MAND_INF, NULL, msg); + rc = osmo_tlv_prot_parse(&osmo_pdef_bssgp, &tp, 1, bgph->pdu_type, budh->data, + msgb_bssgp_len(msg) - sizeof(*budh), 0, 0, DGPRS, log_pfx); + /* populate TLLI from the fixed headser into the TLV-parsed array so later code + * doesn't have to worry where the TLLI came from */ + tp.lv[BSSGP_IE_TLLI].len = 4; + tp.lv[BSSGP_IE_TLLI].val = (const uint8_t *) &budh->tlli; + } else { + rc = osmo_tlv_prot_parse(&osmo_pdef_bssgp, &tp, 1, bgph->pdu_type, bgph->data, + msgb_bssgp_len(msg) - sizeof(*bgph), 0, 0, DGPRS, log_pfx); + } + if (rc < 0) { + rate_ctr_inc(&nse->cfg->ctrg->ctr[GBPROX_GLOB_CTR_PROTO_ERR_BSS]); + return tx_status_from_tlvp(rc, msg); + } + /* hack to get both msg + tlv_parsed passed via osmo_fsm_inst_dispatch */ + msgb_bcid(msg) = (void *)&tp; - gbproxy_update_link_state_after(peer, link_info, now, &parse_ctx); + OSMO_ASSERT(sgsn_bvc->cell); + bss_bvc = sgsn_bvc->cell->bss_bvc; - if (sgsn_nsei != cfg->nsip_sgsn_nsei) { - /* Send message directly to the selected SGSN */ - rc = gbprox_relay2sgsn(cfg, msg, msgb_bvci(msg), sgsn_nsei); - /* Don't let the calling code handle the transmission */ - return 0; + switch (bgph->pdu_type) { + case BSSGP_PDUT_FLOW_CONTROL_BVC_ACK: + return osmo_fsm_inst_dispatch(sgsn_bvc->fi, BSSGP_BVCFSM_E_RX_FC_BVC_ACK, msg); + case BSSGP_PDUT_DUMMY_PAGING_PS: + case BSSGP_PDUT_PAGING_PS: + { + /* Cache the IMSI<->NSE to route PAGING REJECT */ + struct osmo_mobile_identity mi; + const uint8_t *mi_data = TLVP_VAL(&tp, BSSGP_IE_IMSI); + uint8_t mi_len = TLVP_LEN(&tp, BSSGP_IE_IMSI); + osmo_mobile_identity_decode(&mi, mi_data, mi_len, false); + gbproxy_imsi_cache_update(nse, mi.imsi); + break; } + default: + break; + } + return gbprox_relay2peer(msg, bss_bvc, bss_bvc->bvci); - return 1; } -/* patch BSSGP message to use core_plmn.mcc/mnc on the SGSN side */ -static void gbprox_process_bssgp_dl(struct gbproxy_config *cfg, - struct msgb *msg, - struct gbproxy_peer *peer) -{ - struct gprs_gb_parse_context parse_ctx = {0}; - int rc; - int len_change = 0; - time_t now; - struct timespec ts = {0,}; - struct gbproxy_link_info *link_info = NULL; +/*********************************************************************** + * BVC FSM call-backs + ***********************************************************************/ - if (!cfg->core_plmn.mcc && !cfg->core_plmn.mnc && !cfg->core_apn && - !cfg->acquire_imsi && !cfg->patch_ptmsi && !cfg->route_to_sgsn2) - return; +/* helper function to dispatch a FSM event to all SGSN-side BVC FSMs of a cell */ +static void dispatch_to_all_sgsn_bvc(struct gbproxy_cell *cell, uint32_t event, void *priv) +{ + unsigned int i; - parse_ctx.to_bss = 1; - parse_ctx.peer_nsei = msgb_nsei(msg); + for (i = 0; i < ARRAY_SIZE(cell->sgsn_bvc); i++) { + struct gbproxy_bvc *sgsn_bvc = cell->sgsn_bvc[i]; + if (!sgsn_bvc) + continue; + osmo_fsm_inst_dispatch(sgsn_bvc->fi, event, priv); + } +} - rc = gprs_gb_parse_bssgp(msgb_bssgph(msg), msgb_bssgp_len(msg), - &parse_ctx); +/* BVC FSM informs us about a BSS-side reset of the signaling BVC */ +static void bss_sig_bvc_reset_notif(uint16_t nsei, uint16_t bvci, const struct gprs_ra_id *ra_id, + uint16_t cell_id, uint8_t cause, void *priv) +{ + struct gbproxy_bvc *sig_bvc = priv; + struct gbproxy_nse *nse = sig_bvc->nse; + struct gbproxy_bvc *ptp_bvc; + unsigned int i; + + /* BLOCK all SGSN-side PTP BVC within this NSE */ + hash_for_each(nse->bvcs, i, ptp_bvc, list) { + if (ptp_bvc == sig_bvc) + continue; + OSMO_ASSERT(ptp_bvc->cell); - if (!rc && !parse_ctx.need_decryption) { - LOGP(DGPRS, LOGL_ERROR, - "NSEI=%u(SGSN) patching: failed to parse invalid %s message\n", - msgb_nsei(msg), gprs_gb_message_name(&parse_ctx, "NS_UNITDATA")); - gprs_gb_log_parse_context(LOGL_NOTICE, &parse_ctx, "NS_UNITDATA"); - LOGP(DGPRS, LOGL_NOTICE, - "NSEI=%u(SGSN) invalid message was: %s\n", - msgb_nsei(msg), msgb_hexdump(msg)); - return; + dispatch_to_all_sgsn_bvc(ptp_bvc->cell, BSSGP_BVCFSM_E_REQ_BLOCK, &cause); } - /* Get peer */ - if (!peer) - peer = gbproxy_find_peer(cfg, msg, &parse_ctx); + /* Delete all BSS-side PTP BVC within this NSE */ + gbproxy_cleanup_bvcs(nse, 0); - if (!peer) - return; + /* TODO: we keep the "CELL" around for now, re-connecting it to + * any (later) new PTP-BVC for that BVCI. Not sure if that's the + * best idea ? */ +} - osmo_clock_gettime(CLOCK_MONOTONIC, &ts); - now = ts.tv_sec; +/* forward declaration */ +static const struct bssgp_bvc_fsm_ops sgsn_ptp_bvc_fsm_ops; - if (parse_ctx.g48_hdr) { - switch (parse_ctx.g48_hdr->msg_type) { - case GSM48_MT_GMM_ATTACH_ACK: - rate_ctr_inc(&peer->ctrg->ctr[GBPROX_PEER_CTR_ATTACH_ACKS]); - break; - case GSM48_MT_GMM_ATTACH_REJ: - rate_ctr_inc(&peer->ctrg->ctr[GBPROX_PEER_CTR_ATTACH_REJS]); - break; - case GSM48_MT_GMM_DETACH_ACK: - rate_ctr_inc(&peer->ctrg->ctr[GBPROX_PEER_CTR_DETACH_ACKS]); - break; - case GSM48_MT_GMM_RA_UPD_ACK: - rate_ctr_inc(&peer->ctrg->ctr[GBPROX_PEER_CTR_RA_UPD_ACKS]); - break; - case GSM48_MT_GMM_RA_UPD_REJ: - rate_ctr_inc(&peer->ctrg->ctr[GBPROX_PEER_CTR_RA_UPD_REJS]); - break; - case GSM48_MT_GMM_STATUS: - rate_ctr_inc(&peer->ctrg->ctr[GBPROX_PEER_CTR_GMM_STATUS_SGSN]); - break; - case GSM48_MT_GSM_ACT_PDP_ACK: - rate_ctr_inc(&peer->ctrg->ctr[GBPROX_PEER_CTR_PDP_ACT_ACKS]); - break; - case GSM48_MT_GSM_ACT_PDP_REJ: - rate_ctr_inc(&peer->ctrg->ctr[GBPROX_PEER_CTR_PDP_ACT_REJS]); - break; - case GSM48_MT_GSM_DEACT_PDP_ACK: - rate_ctr_inc(&peer->ctrg->ctr[GBPROX_PEER_CTR_PDP_DEACT_ACKS]); - break; +static const struct bssgp_bvc_fsm_ops bss_sig_bvc_fsm_ops = { + .reset_notification = bss_sig_bvc_reset_notif, +}; - default: - break; +/* BVC FSM informs us about a BSS-side reset of a PTP BVC */ +static void bss_ptp_bvc_reset_notif(uint16_t nsei, uint16_t bvci, const struct gprs_ra_id *ra_id, + uint16_t cell_id, uint8_t cause, void *priv) +{ + struct gbproxy_bvc *bvc = priv; + struct gbproxy_config *cfg = bvc->nse->cfg; + struct gbproxy_nse *sgsn_nse; + unsigned int i; + + OSMO_ASSERT(bvci != 0); + + if (!bvc->cell) { + /* see if we have a CELL dangling around */ + bvc->cell = gbproxy_cell_by_bvci(cfg, bvci); + if (bvc->cell) { + /* the CELL already exists. This means either it * was created before at an + * earlier PTP BVC-RESET, or that there are non-unique BVCIs and hence a + * malconfiguration */ + if (bvc->cell->bss_bvc) { + LOGPBVC(bvc, LOGL_NOTICE, "Rx BVC-RESET via this NSE, but CELL already " + "has BVC on NSEI=%05u\n", bvc->cell->bss_bvc->nse->nsei); + LOGPBVC(bvc->cell->bss_bvc, LOGL_NOTICE, "Destroying due to conflicting " + "BVCI configuration (new NSEI=%05u)!\n", bvc->nse->nsei); + gbproxy_bvc_free(bvc->cell->bss_bvc); + } + bvc->cell->bss_bvc = bvc; } } - gprs_gb_log_parse_context(LOGL_DEBUG, &parse_ctx, "NS_UNITDATA"); - - link_info = gbproxy_update_link_state_dl(peer, now, &parse_ctx); - - gbproxy_patch_bssgp(msg, msgb_bssgph(msg), msgb_bssgp_len(msg), - peer, link_info, &len_change, &parse_ctx); + if (!bvc->cell) { + /* if we end up here, it means this is the first time we received a BVC-RESET + * for this BVC. We need to create the 'cell' data structure and the SGSN-side + * BVC counterparts */ - gbproxy_update_link_state_after(peer, link_info, now, &parse_ctx); + bvc->cell = gbproxy_cell_alloc(cfg, bvci); + OSMO_ASSERT(bvc->cell); + memcpy(bvc->cell->ra, bvc->ra, sizeof(bvc->cell->ra)); - return; -} - -/* feed a message down the NS-VC associated with the specified peer */ -static int gbprox_relay2sgsn(struct gbproxy_config *cfg, struct msgb *old_msg, - uint16_t ns_bvci, uint16_t sgsn_nsei) -{ - /* create a copy of the message so the old one can - * be free()d safely when we return from gbprox_rcvmsg() */ - struct msgb *msg = bssgp_msgb_copy(old_msg, "msgb_relay2sgsn"); - int rc; + /* link us to the cell and vice-versa */ + bvc->cell->bss_bvc = bvc; + } - DEBUGP(DGPRS, "NSEI=%u proxying BTS->SGSN (NS_BVCI=%u, NSEI=%u)\n", - msgb_nsei(msg), ns_bvci, sgsn_nsei); + /* allocate (any missing) SGSN-side BVCs within the cell, and reset them */ + hash_for_each(cfg->sgsn_nses, i, sgsn_nse, list) { + struct gbproxy_bvc *sgsn_bvc = gbproxy_bvc_by_bvci(sgsn_nse, bvci); + if (sgsn_bvc) + OSMO_ASSERT(sgsn_bvc->cell == bvc->cell || !sgsn_bvc->cell); - msgb_bvci(msg) = ns_bvci; - msgb_nsei(msg) = sgsn_nsei; + if (!sgsn_bvc) { + sgsn_bvc = gbproxy_bvc_alloc(sgsn_nse, bvci); + OSMO_ASSERT(sgsn_bvc); - strip_ns_hdr(msg); + sgsn_bvc->cell = bvc->cell; + memcpy(sgsn_bvc->ra, bvc->cell->ra, sizeof(sgsn_bvc->ra)); + sgsn_bvc->fi = bssgp_bvc_fsm_alloc_ptp_bss(sgsn_bvc, cfg->nsi, sgsn_nse->nsei, + bvci, ra_id, cell_id); + OSMO_ASSERT(sgsn_bvc->fi); + bssgp_bvc_fsm_set_ops(sgsn_bvc->fi, &sgsn_ptp_bvc_fsm_ops, sgsn_bvc); - rc = gprs_ns_sendmsg(bssgp_nsi, msg); - if (rc < 0) - rate_ctr_inc(&cfg->ctrg->ctr[GBPROX_GLOB_CTR_TX_ERR_SGSN]); + gbproxy_cell_add_sgsn_bvc(bvc->cell, sgsn_bvc); + } + } - return rc; + /* Trigger outbound BVC-RESET procedure toward each SGSN */ + dispatch_to_all_sgsn_bvc(bvc->cell, BSSGP_BVCFSM_E_REQ_RESET, &cause); } -/* feed a message down the NS-VC associated with the specified peer */ -static int gbprox_relay2peer(struct msgb *old_msg, struct gbproxy_peer *peer, - uint16_t ns_bvci) +/* BVC FSM informs us about a BSS-side FSM state change */ +static void bss_ptp_bvc_state_chg_notif(uint16_t nsei, uint16_t bvci, int old_state, int state, void *priv) { - /* create a copy of the message so the old one can - * be free()d safely when we return from gbprox_rcvmsg() */ - struct msgb *msg = bssgp_msgb_copy(old_msg, "msgb_relay2peer"); - int rc; - - DEBUGP(DGPRS, "NSEI=%u proxying SGSN->BSS (NS_BVCI=%u, NSEI=%u)\n", - msgb_nsei(msg), ns_bvci, peer->nsei); - - msgb_bvci(msg) = ns_bvci; - msgb_nsei(msg) = peer->nsei; - - /* Strip the old NS header, it will be replaced with a new one */ - strip_ns_hdr(msg); - - rc = gprs_ns_sendmsg(bssgp_nsi, msg); - if (rc < 0) - rate_ctr_inc(&peer->ctrg->ctr[GBPROX_PEER_CTR_TX_ERR]); + struct gbproxy_bvc *bvc = priv; + struct gbproxy_cell *cell = bvc->cell; + uint8_t cause = bssgp_bvc_fsm_get_block_cause(bvc->fi); - return rc; -} - -static int block_unblock_peer(struct gbproxy_config *cfg, uint16_t ptp_bvci, uint8_t pdu_type) -{ - struct gbproxy_peer *peer; - - peer = gbproxy_peer_by_bvci(cfg, ptp_bvci); - if (!peer) { - LOGP(DGPRS, LOGL_ERROR, "BVCI=%u: Cannot find BSS\n", - ptp_bvci); - rate_ctr_inc(&cfg->ctrg->ctr[GBPROX_GLOB_CTR_INV_BVCI]); - return -ENOENT; - } + /* we have just been created but due to callback ordering the cell is not associated */ + if (!cell) + return; - switch (pdu_type) { - case BSSGP_PDUT_BVC_BLOCK_ACK: - peer->blocked = true; - rate_ctr_inc(&peer->ctrg->ctr[GBPROX_PEER_CTR_BLOCKED]); + switch (state) { + case BSSGP_BVCFSM_S_BLOCKED: + /* block the corresponding SGSN-side PTP BVCs */ + dispatch_to_all_sgsn_bvc(cell, BSSGP_BVCFSM_E_REQ_BLOCK, &cause); break; - case BSSGP_PDUT_BVC_UNBLOCK_ACK: - peer->blocked = false; - rate_ctr_inc(&peer->ctrg->ctr[GBPROX_PEER_CTR_UNBLOCKED]); - break; - default: + case BSSGP_BVCFSM_S_UNBLOCKED: + /* unblock the corresponding SGSN-side PTP BVCs */ + dispatch_to_all_sgsn_bvc(cell, BSSGP_BVCFSM_E_REQ_UNBLOCK, NULL); break; } - return 0; } -/* Send a message to a peer identified by ptp_bvci but using ns_bvci - * in the NS hdr */ -static int gbprox_relay2bvci(struct gbproxy_config *cfg, struct msgb *msg, uint16_t ptp_bvci, - uint16_t ns_bvci) +/* BVC FSM informs us about BVC-FC PDU receive */ +static void bss_ptp_bvc_fc_bvc(uint16_t nsei, uint16_t bvci, const struct bssgp2_flow_ctrl *fc, void *priv) { - struct gbproxy_peer *peer; - - peer = gbproxy_peer_by_bvci(cfg, ptp_bvci); - if (!peer) { - LOGP(DGPRS, LOGL_ERROR, "BVCI=%u: Cannot find BSS\n", - ptp_bvci); - rate_ctr_inc(&cfg->ctrg->ctr[GBPROX_GLOB_CTR_INV_BVCI]); - return -ENOENT; - } + struct bssgp2_flow_ctrl fc_reduced; + struct gbproxy_bvc *bss_bvc = priv; + struct gbproxy_cell *cell; + struct gbproxy_config *cfg; - return gbprox_relay2peer(msg, peer, ns_bvci); -} + OSMO_ASSERT(bss_bvc); + OSMO_ASSERT(fc); -int bssgp_prim_cb(struct osmo_prim_hdr *oph, void *ctx) -{ - return 0; -} + cell = bss_bvc->cell; + if (!cell) + return; -/* Receive an incoming PTP message from a BSS-side NS-VC */ -static int gbprox_rx_ptp_from_bss(struct gbproxy_config *cfg, - struct msgb *msg, uint16_t nsei, - uint16_t nsvci, uint16_t ns_bvci) -{ - struct gbproxy_peer *peer; - struct bssgp_normal_hdr *bgph = (struct bssgp_normal_hdr *) msgb_bssgph(msg); - uint8_t pdu_type = bgph->pdu_type; - int rc; + cfg = cell->cfg; - peer = gbproxy_peer_by_bvci(cfg, ns_bvci); - if (!peer) { - LOGP(DGPRS, LOGL_NOTICE, "Didn't find peer for " - "BVCI=%u for PTP message from NSVC=%u/NSEI=%u (BSS), " - "discarding message\n", - ns_bvci, nsvci, nsei); - return bssgp_tx_status(BSSGP_CAUSE_UNKNOWN_BVCI, - &ns_bvci, msg); - } + /* reduce / scale according to configuration to make sure we only advertise a fraction + * of the capacity to each of the SGSNs in the pool */ + fc_reduced = *fc; + fc_reduced.bucket_size_max = (fc->bucket_size_max * cfg->pool.bvc_fc_ratio) / 100; + fc_reduced.bucket_leak_rate = (fc->bucket_leak_rate * cfg->pool.bvc_fc_ratio) / 100; + /* we don't modify the per-MS related values as any single MS is only served by one SGSN */ - check_peer_nsei(peer, nsei); + dispatch_to_all_sgsn_bvc(cell, BSSGP_BVCFSM_E_REQ_FC_BVC, (void *) &fc_reduced); +} - rc = gbprox_process_bssgp_ul(cfg, msg, peer); - if (!rc) - return 0; +static const struct bssgp_bvc_fsm_ops bss_ptp_bvc_fsm_ops = { + .reset_notification = bss_ptp_bvc_reset_notif, + .state_chg_notification = bss_ptp_bvc_state_chg_notif, + .rx_fc_bvc = bss_ptp_bvc_fc_bvc, +}; - switch (pdu_type) { - case BSSGP_PDUT_FLOW_CONTROL_BVC: - if (!cfg->route_to_sgsn2) - break; +/* BVC FSM informs us about a SGSN-side reset of a PTP BVC */ +static void sgsn_ptp_bvc_reset_notif(uint16_t nsei, uint16_t bvci, const struct gprs_ra_id *ra_id, + uint16_t cell_id, uint8_t cause, void *priv) +{ + struct gbproxy_bvc *bvc = priv; - /* Send a copy to the secondary SGSN */ - gbprox_relay2sgsn(cfg, msg, ns_bvci, cfg->nsip_sgsn2_nsei); - break; - default: - break; + if (!bvc->cell) { + LOGPBVC(bvc, LOGL_ERROR, "RESET of PTP BVC on SGSN side for which we have no BSS?\n"); + return; } + OSMO_ASSERT(bvc->cell->bss_bvc); - return gbprox_relay2sgsn(cfg, msg, ns_bvci, cfg->nsip_sgsn_nsei); + /* request reset of BSS-facing PTP-BVC */ + osmo_fsm_inst_dispatch(bvc->cell->bss_bvc->fi, BSSGP_BVCFSM_E_REQ_RESET, &cause); } -/* Receive an incoming PTP message from a SGSN-side NS-VC */ -static int gbprox_rx_ptp_from_sgsn(struct gbproxy_config *cfg, - struct msgb *msg, uint16_t nsei, - uint16_t nsvci, uint16_t ns_bvci) +static const struct bssgp_bvc_fsm_ops sgsn_ptp_bvc_fsm_ops = { + .reset_notification = sgsn_ptp_bvc_reset_notif, +}; + +/* BVC FSM informs us about a SGSN-side reset of the signaling BVC */ +static void sgsn_sig_bvc_reset_notif(uint16_t nsei, uint16_t bvci, const struct gprs_ra_id *ra_id, + uint16_t cell_id, uint8_t cause, void *priv) { - struct gbproxy_peer *peer; - struct bssgp_normal_hdr *bgph = (struct bssgp_normal_hdr *) msgb_bssgph(msg); - uint8_t pdu_type = bgph->pdu_type; + struct gbproxy_bvc *bvc = priv; + struct gbproxy_config *cfg = bvc->nse->cfg; + struct gbproxy_nse *bss_nse; + unsigned int i; + + /* delete all SGSN-side PTP BVC for this SGSN */ + gbproxy_cleanup_bvcs(bvc->nse, 0); + /* FIXME: what to do about the cells? */ + /* FIXME: do we really want to RESET all signaling BVC on the BSS and affect all other SGSN? */ + + /* we need to trigger generating a reset procedure towards each BSS side signaling BVC */ + hash_for_each(cfg->bss_nses, i, bss_nse, list) { + struct gbproxy_bvc *bss_bvc = gbproxy_bvc_by_bvci(bss_nse, 0); + if (!bss_bvc) { + LOGPNSE(bss_nse, LOGL_ERROR, "Doesn't have BVC with BVCI=0 ?!?\n"); + continue; + } + osmo_fsm_inst_dispatch(bss_bvc->fi, BSSGP_BVCFSM_E_REQ_RESET, &cause); + } +} - peer = gbproxy_peer_by_bvci(cfg, ns_bvci); +const struct bssgp_bvc_fsm_ops sgsn_sig_bvc_fsm_ops = { + .reset_notification = sgsn_sig_bvc_reset_notif, +}; - /* Send status messages before patching */ +/*********************************************************************** + * Signaling BVC handling + ***********************************************************************/ - if (!peer) { - LOGP(DGPRS, LOGL_INFO, "Didn't find peer for " - "BVCI=%u for message from NSVC=%u/NSEI=%u (SGSN)\n", - ns_bvci, nsvci, nsei); - rate_ctr_inc(&cfg->ctrg-> - ctr[GBPROX_GLOB_CTR_INV_BVCI]); - return bssgp_tx_status(BSSGP_CAUSE_UNKNOWN_BVCI, - &ns_bvci, msg); - } +/* process a BVC-RESET message from the BSS side */ +static int rx_bvc_reset_from_bss(struct gbproxy_nse *nse, struct msgb *msg, struct tlv_parsed *tp) +{ + struct gbproxy_bvc *from_bvc = NULL; + uint16_t bvci = ntohs(tlvp_val16_unal(tp, BSSGP_IE_BVCI)); + uint32_t features = 0; // FIXME: make configurable - if (peer->blocked) { - LOGP(DGPRS, LOGL_NOTICE, "Dropping PDU for " - "blocked BVCI=%u via NSVC=%u/NSEI=%u\n", - ns_bvci, nsvci, nsei); - rate_ctr_inc(&peer->ctrg->ctr[GBPROX_PEER_CTR_DROPPED]); - return bssgp_tx_status(BSSGP_CAUSE_BVCI_BLOCKED, &ns_bvci, msg); - } + LOGPNSE(nse, LOGL_INFO, "Rx BVC-RESET (BVCI=%05u)\n", bvci); - switch (pdu_type) { - case BSSGP_PDUT_FLOW_CONTROL_BVC_ACK: - case BSSGP_PDUT_BVC_BLOCK_ACK: - case BSSGP_PDUT_BVC_UNBLOCK_ACK: - if (cfg->route_to_sgsn2 && nsei == cfg->nsip_sgsn2_nsei) - /* Hide ACKs from the secondary SGSN, the primary SGSN - * is responsible to send them. */ - return 0; - break; - default: - break; - } + if (bvci == 0) { + /* If we receive a BVC reset on the signalling endpoint, we + * don't want the SGSN to reset, as the signalling endpoint + * is common for all point-to-point BVCs (and thus all BTS) */ - /* Optionally patch the message */ - gbprox_process_bssgp_dl(cfg, msg, peer); + from_bvc = gbproxy_bvc_by_bvci(nse, 0); + if (!from_bvc) { + from_bvc = gbproxy_bvc_alloc(nse, 0); + OSMO_ASSERT(from_bvc); + from_bvc->fi = bssgp_bvc_fsm_alloc_sig_sgsn(from_bvc, nse->cfg->nsi, nse->nsei, features); + if (!from_bvc->fi) { + LOGPNSE(nse, LOGL_ERROR, "Cannot allocate SIG-BVC FSM\n"); + gbproxy_bvc_free(from_bvc); + return -ENOMEM; + } + bssgp_bvc_fsm_set_ops(from_bvc->fi, &bss_sig_bvc_fsm_ops, from_bvc); + } + } else { + from_bvc = gbproxy_bvc_by_bvci(nse, bvci); + if (!from_bvc) { + /* if a PTP-BVC is reset, and we don't know that + * PTP-BVCI yet, we should allocate a new bvc */ + from_bvc = gbproxy_bvc_alloc(nse, bvci); + OSMO_ASSERT(from_bvc); + from_bvc->fi = bssgp_bvc_fsm_alloc_ptp_sgsn(from_bvc, nse->cfg->nsi, + nse->nsei, bvci); + if (!from_bvc->fi) { + LOGPNSE(nse, LOGL_ERROR, "Cannot allocate SIG-BVC FSM\n"); + gbproxy_bvc_free(from_bvc); + return -ENOMEM; + } + bssgp_bvc_fsm_set_ops(from_bvc->fi, &bss_ptp_bvc_fsm_ops, from_bvc); + } +#if 0 + /* Could have moved to a different NSE */ + if (!check_bvc_nsei(from_bvc, nsei)) { + LOGPBVC(from_bvc, LOGL_NOTICE, "moving bvc to NSE(%05u)\n", nsei); + + struct gbproxy_nse *nse_new = gbproxy_nse_by_nsei(cfg, nsei, false); + if (!nse_new) { + LOGP(DGPRS, LOGL_NOTICE, "NSE(%05u) Got PtP BVC reset before signalling reset for " + "BVCI=%05u\n", bvci, nsei); + bssgp_tx_status(BSSGP_CAUSE_PDU_INCOMP_STATE, NULL, msg); + return 0; + } - return gbprox_relay2peer(msg, peer, ns_bvci); + /* Move bvc to different NSE */ + gbproxy_bvc_move(from_bvc, nse_new); + } +#endif + /* FIXME: do we need this, if it happens within FSM? */ + if (TLVP_PRES_LEN(tp, BSSGP_IE_CELL_ID, 8)) { + struct gprs_ra_id raid; + /* We have a Cell Identifier present in this + * PDU, this means we can extend our local + * state information about this particular cell + * */ + memcpy(from_bvc->ra, TLVP_VAL(tp, BSSGP_IE_CELL_ID), sizeof(from_bvc->ra)); + gsm48_parse_ra(&raid, from_bvc->ra); + LOGPBVC(from_bvc, LOGL_INFO, "Cell ID %s\n", osmo_rai_name(&raid)); + } + } + /* hand into FSM for further processing */ + osmo_fsm_inst_dispatch(from_bvc->fi, BSSGP_BVCFSM_E_RX_RESET, msg); + return 0; } /* Receive an incoming signalling message from a BSS-side NS-VC */ -static int gbprox_rx_sig_from_bss(struct gbproxy_config *cfg, - struct msgb *msg, uint16_t nsei, - uint16_t ns_bvci) +static int gbprox_rx_sig_from_bss(struct gbproxy_nse *nse, struct msgb *msg, uint16_t ns_bvci) { struct bssgp_normal_hdr *bgph = (struct bssgp_normal_hdr *) msgb_bssgph(msg); - struct tlv_parsed tp; uint8_t pdu_type = bgph->pdu_type; + const char *pdut_name = osmo_tlv_prot_msg_name(&osmo_pdef_bssgp, bgph->pdu_type); + struct tlv_parsed tp; int data_len = msgb_bssgp_len(msg) - sizeof(*bgph); - struct gbproxy_peer *from_peer = NULL; - struct gprs_ra_id raid; - int copy_to_sgsn2 = 0; + struct gbproxy_bvc *from_bvc = NULL; + char log_pfx[32]; + uint16_t ptp_bvci; + uint32_t tlli; int rc; + snprintf(log_pfx, sizeof(log_pfx), "NSE(%05u/BSS)-BVC(%05u/??)", nse->nsei, ns_bvci); + + LOGP(DGPRS, LOGL_DEBUG, "%s Rx %s\n", log_pfx, pdut_name); + if (ns_bvci != 0 && ns_bvci != 1) { - LOGP(DGPRS, LOGL_NOTICE, "NSEI=%u BVCI=%u is not signalling\n", - nsei, ns_bvci); - return -EINVAL; + LOGP(DGPRS, LOGL_NOTICE, "%s %s BVCI=%05u is not signalling\n", log_pfx, pdut_name, ns_bvci); + return bssgp_tx_status(BSSGP_CAUSE_PROTO_ERR_UNSPEC, NULL, msg); } - /* we actually should never see those two for BVCI == 0, but double-check - * just to make sure */ - if (pdu_type == BSSGP_PDUT_UL_UNITDATA || - pdu_type == BSSGP_PDUT_DL_UNITDATA) { - LOGP(DGPRS, LOGL_NOTICE, "NSEI=%u UNITDATA not allowed in " - "signalling\n", nsei); - return -EINVAL; + if (!(bssgp_pdu_type_flags(pdu_type) & BSSGP_PDUF_SIG)) { + LOGP(DGPRS, LOGL_NOTICE, "%s %s not allowed in signalling BVC\n", log_pfx, pdut_name); + return bssgp_tx_status(BSSGP_CAUSE_PROTO_ERR_UNSPEC, NULL, msg); } - bssgp_tlv_parse(&tp, bgph->data, data_len); + if (!(bssgp_pdu_type_flags(pdu_type) & BSSGP_PDUF_UL)) { + LOGP(DGPRS, LOGL_NOTICE, "%s %s not allowed in uplink direction\n", log_pfx, pdut_name); + return bssgp_tx_status(BSSGP_CAUSE_PROTO_ERR_UNSPEC, NULL, msg); + } + rc = osmo_tlv_prot_parse(&osmo_pdef_bssgp, &tp, 1, pdu_type, bgph->data, data_len, 0, 0, + DGPRS, log_pfx); + if (rc < 0) { + rate_ctr_inc(&nse->cfg->ctrg->ctr[GBPROX_GLOB_CTR_PROTO_ERR_BSS]); + return tx_status_from_tlvp(rc, msg); + } + /* hack to get both msg + tlv_parsed passed via osmo_fsm_inst_dispatch */ + msgb_bcid(msg) = (void *)&tp; + + /* special case handling for some PDU types */ switch (pdu_type) { + case BSSGP_PDUT_BVC_RESET: + /* resolve or create gbproxy_bvc + handlei n BVC-FSM */ + return rx_bvc_reset_from_bss(nse, msg, &tp); + case BSSGP_PDUT_BVC_RESET_ACK: + ptp_bvci = ntohs(tlvp_val16_unal(&tp, BSSGP_IE_BVCI)); + from_bvc = gbproxy_bvc_by_bvci(nse, ptp_bvci); + if (!from_bvc) + goto err_no_bvc; + return osmo_fsm_inst_dispatch(from_bvc->fi, BSSGP_BVCFSM_E_RX_RESET_ACK, msg); + case BSSGP_PDUT_BVC_BLOCK: + ptp_bvci = ntohs(tlvp_val16_unal(&tp, BSSGP_IE_BVCI)); + from_bvc = gbproxy_bvc_by_bvci(nse, ptp_bvci); + if (!from_bvc) + goto err_no_bvc; + return osmo_fsm_inst_dispatch(from_bvc->fi, BSSGP_BVCFSM_E_RX_BLOCK, msg); + case BSSGP_PDUT_BVC_UNBLOCK: + ptp_bvci = ntohs(tlvp_val16_unal(&tp, BSSGP_IE_BVCI)); + from_bvc = gbproxy_bvc_by_bvci(nse, ptp_bvci); + if (!from_bvc) + goto err_no_bvc; + return osmo_fsm_inst_dispatch(from_bvc->fi, BSSGP_BVCFSM_E_RX_UNBLOCK, msg); case BSSGP_PDUT_SUSPEND: case BSSGP_PDUT_RESUME: - /* We implement RAI snooping during SUSPEND/RESUME, since it - * establishes a relationsip between BVCI/peer and the routeing - * area identification. The snooped information is then used - * for routing the {SUSPEND,RESUME}_[N]ACK back to the correct - * BSSGP */ - if (!TLVP_PRESENT(&tp, BSSGP_IE_ROUTEING_AREA)) - goto err_mand_ie; - from_peer = gbproxy_peer_by_nsei(cfg, nsei); - if (!from_peer) - goto err_no_peer; - memcpy(from_peer->ra, TLVP_VAL(&tp, BSSGP_IE_ROUTEING_AREA), - sizeof(from_peer->ra)); - gsm48_parse_ra(&raid, from_peer->ra); - LOGP(DGPRS, LOGL_INFO, "NSEI=%u BSSGP SUSPEND/RESUME " - "RAI snooping: RAI %s behind BVCI=%u\n", - nsei, osmo_rai_name(&raid), from_peer->bvci); - /* FIXME: This only supports one BSS per RA */ - break; - case BSSGP_PDUT_BVC_RESET: - /* If we receive a BVC reset on the signalling endpoint, we - * don't want the SGSN to reset, as the signalling endpoint - * is common for all point-to-point BVCs (and thus all BTS) */ - if (TLVP_PRESENT(&tp, BSSGP_IE_BVCI)) { - uint16_t bvci = ntohs(tlvp_val16_unal(&tp, BSSGP_IE_BVCI)); - LOGP(DGPRS, LOGL_INFO, "NSEI=%u Rx BVC RESET (BVCI=%u)\n", - nsei, bvci); - if (bvci == 0) { - /* FIXME: only do this if SGSN is alive! */ - LOGP(DGPRS, LOGL_INFO, "NSEI=%u Tx fake " - "BVC RESET ACK of BVCI=0\n", nsei); - return bssgp_tx_simple_bvci(BSSGP_PDUT_BVC_RESET_ACK, - nsei, 0, ns_bvci); - } - from_peer = gbproxy_peer_by_bvci(cfg, bvci); - if (!from_peer) { - /* if a PTP-BVC is reset, and we don't know that - * PTP-BVCI yet, we should allocate a new peer */ - LOGP(DGPRS, LOGL_INFO, "Allocationg new peer for BVCI=%u via NSEI=%u\n", bvci, nsei); - from_peer = gbproxy_peer_alloc(cfg, bvci); - OSMO_ASSERT(from_peer); - from_peer->nsei = nsei; - } + { + struct gbproxy_sgsn *sgsn; + + tlli = osmo_load32be(TLVP_VAL(&tp, BSSGP_IE_TLLI)); + sgsn = gbproxy_select_sgsn(nse->cfg, &tlli); + if (!sgsn) { + LOGP(DGPRS, LOGL_ERROR, "Could not find any SGSN for TLLI, dropping message!\n"); + rc = -EINVAL; + break; + } - if (!check_peer_nsei(from_peer, nsei)) - from_peer->nsei = nsei; - - if (TLVP_PRESENT(&tp, BSSGP_IE_CELL_ID)) { - struct gprs_ra_id raid; - /* We have a Cell Identifier present in this - * PDU, this means we can extend our local - * state information about this particular cell - * */ - memcpy(from_peer->ra, - TLVP_VAL(&tp, BSSGP_IE_CELL_ID), - sizeof(from_peer->ra)); - gsm48_parse_ra(&raid, from_peer->ra); - LOGP(DGPRS, LOGL_INFO, "NSEI=%u/BVCI=%u Cell ID %s\n", - nsei, bvci, osmo_rai_name(&raid)); - } - if (cfg->route_to_sgsn2) - copy_to_sgsn2 = 1; + gbproxy_tlli_cache_update(nse, tlli); + + rc = gbprox_relay2nse(msg, sgsn->nse, 0); +#if 0 + /* TODO: Validate the RAI for consistency with the RAI + * we expect for any of the BVC within this BSS side NSE */ + memcpy(ra, TLVP_VAL(&tp, BSSGP_IE_ROUTEING_AREA), sizeof(from_bvc->ra)); + gsm48_parse_ra(&raid, from_bvc->ra); +#endif + break; + } + case BSSGP_PDUT_STATUS: + /* FIXME: inspect the erroneous PDU IE (if any) and check + * if we can extract a TLLI/RNI to route it to the correct SGSN */ + break; + case BSSGP_PDUT_RAN_INFO: + case BSSGP_PDUT_RAN_INFO_REQ: + case BSSGP_PDUT_RAN_INFO_ACK: + case BSSGP_PDUT_RAN_INFO_ERROR: + case BSSGP_PDUT_RAN_INFO_APP_ERROR: + /* FIXME: route based in RIM Routing IE */ + rc = bssgp_tx_status(BSSGP_CAUSE_PDU_INCOMP_FEAT, NULL, msg); + break; + case BSSGP_PDUT_LLC_DISCARD: + case BSSGP_PDUT_FLUSH_LL_ACK: + /* route based on BVCI + TLLI */ + ptp_bvci = ntohs(tlvp_val16_unal(&tp, BSSGP_IE_BVCI)); + tlli = osmo_load32be(TLVP_VAL(&tp, BSSGP_IE_TLLI)); + from_bvc = gbproxy_bvc_by_bvci(nse, ptp_bvci); + if (!from_bvc) + goto err_no_bvc; + gbprox_bss2sgsn_tlli(from_bvc->cell, msg, &tlli, true); + break; + case BSSGP_PDUT_PAGING_PS_REJECT: + case BSSGP_PDUT_DUMMY_PAGING_PS_RESP: + { + /* Route according to IMSI<->NSE cache entry */ + struct osmo_mobile_identity mi; + const uint8_t *mi_data = TLVP_VAL(&tp, BSSGP_IE_IMSI); + uint8_t mi_len = TLVP_LEN(&tp, BSSGP_IE_IMSI); + osmo_mobile_identity_decode(&mi, mi_data, mi_len, false); + nse = gbproxy_nse_by_imsi(nse->cfg, mi.imsi); + if (!nse) { + return bssgp_tx_status(BSSGP_CAUSE_INV_MAND_INF, NULL, msg); } + OSMO_ASSERT(nse->sgsn_facing); + rc = gbprox_relay2nse(msg, nse, 0); + break; + } + default: + LOGPNSE(nse, LOGL_ERROR, "Rx %s: Implementation missing\n", pdut_name); break; } - /* Normally, we can simply pass on all signalling messages from BSS to - * SGSN */ - rc = gbprox_process_bssgp_ul(cfg, msg, from_peer); - if (!rc) - return 0; - - if (copy_to_sgsn2) - gbprox_relay2sgsn(cfg, msg, ns_bvci, cfg->nsip_sgsn2_nsei); - - return gbprox_relay2sgsn(cfg, msg, ns_bvci, cfg->nsip_sgsn_nsei); -err_no_peer: - LOGP(DGPRS, LOGL_ERROR, "NSEI=%u(BSS) cannot find peer based on NSEI\n", - nsei); - rate_ctr_inc(&cfg->ctrg->ctr[GBPROX_GLOB_CTR_INV_NSEI]); + return rc; +err_no_bvc: + LOGPNSE(nse, LOGL_ERROR, "Rx %s: cannot find BVC for BVCI=%05u\n", pdut_name, ptp_bvci); + rate_ctr_inc(&nse->cfg->ctrg->ctr[GBPROX_GLOB_CTR_INV_NSEI]); return bssgp_tx_status(BSSGP_CAUSE_INV_MAND_INF, NULL, msg); -err_mand_ie: - LOGP(DGPRS, LOGL_ERROR, "NSEI=%u(BSS) missing mandatory RA IE\n", - nsei); - rate_ctr_inc(&cfg->ctrg->ctr[GBPROX_GLOB_CTR_PROTO_ERR_BSS]); - return bssgp_tx_status(BSSGP_CAUSE_MISSING_MAND_IE, NULL, msg); } /* Receive paging request from SGSN, we need to relay to proper BSS */ -static int gbprox_rx_paging(struct gbproxy_config *cfg, struct msgb *msg, struct tlv_parsed *tp, - uint32_t nsei, uint16_t ns_bvci) +static int gbprox_rx_paging(struct gbproxy_nse *sgsn_nse, struct msgb *msg, const char *pdut_name, + struct tlv_parsed *tp, uint16_t ns_bvci, bool broadcast) { - struct gbproxy_peer *peer = NULL; + struct gbproxy_config *cfg = sgsn_nse->cfg; + struct gbproxy_bvc *sgsn_bvc, *bss_bvc; + struct gbproxy_nse *nse; + unsigned int n_nses = 0; int errctr = GBPROX_GLOB_CTR_PROTO_ERR_SGSN; + int i, j; - LOGP(DGPRS, LOGL_INFO, "NSEI=%u(SGSN) BSSGP PAGING ", - nsei); - if (TLVP_PRESENT(tp, BSSGP_IE_BVCI)) { + /* FIXME: Handle paging logic to only page each matching NSE */ + + if (TLVP_PRES_LEN(tp, BSSGP_IE_BVCI, 2)) { uint16_t bvci = ntohs(tlvp_val16_unal(tp, BSSGP_IE_BVCI)); - LOGPC(DGPRS, LOGL_INFO, "routing by BVCI to peer BVCI=%u\n", - bvci); errctr = GBPROX_GLOB_CTR_OTHER_ERR; - } else if (TLVP_PRESENT(tp, BSSGP_IE_ROUTEING_AREA)) { - peer = gbproxy_peer_by_rai(cfg, TLVP_VAL(tp, BSSGP_IE_ROUTEING_AREA)); - LOGPC(DGPRS, LOGL_INFO, "routing by RAI to peer BVCI=%u\n", - peer ? peer->bvci : -1); + sgsn_bvc = gbproxy_bvc_by_bvci(sgsn_nse, bvci); + if (!sgsn_bvc) { + LOGPNSE(sgsn_nse, LOGL_NOTICE, "Rx %s: unable to route: BVCI=%05u unknown\n", + pdut_name, bvci); + rate_ctr_inc(&cfg->ctrg->ctr[errctr]); + return -EINVAL; + } + LOGPBVC(sgsn_bvc, LOGL_INFO, "Rx %s: routing by BVCI\n", pdut_name); + return gbprox_relay2peer(msg, sgsn_bvc->cell->bss_bvc, ns_bvci); + } else if (TLVP_PRES_LEN(tp, BSSGP_IE_ROUTEING_AREA, 6)) { errctr = GBPROX_GLOB_CTR_INV_RAI; - } else if (TLVP_PRESENT(tp, BSSGP_IE_LOCATION_AREA)) { - peer = gbproxy_peer_by_lai(cfg, TLVP_VAL(tp, BSSGP_IE_LOCATION_AREA)); - LOGPC(DGPRS, LOGL_INFO, "routing by LAI to peer BVCI=%u\n", - peer ? peer->bvci : -1); + /* iterate over all bvcs and dispatch the paging to each matching one */ + hash_for_each(cfg->bss_nses, i, nse, list) { + hash_for_each(nse->bvcs, j, bss_bvc, list) { + if (!memcmp(bss_bvc->ra, TLVP_VAL(tp, BSSGP_IE_ROUTEING_AREA), 6)) { + LOGPNSE(nse, LOGL_INFO, "Rx %s: routing to NSE (RAI match)\n", + pdut_name); + gbprox_relay2peer(msg, bss_bvc, ns_bvci); + n_nses++; + /* Only send it once to each NSE */ + break; + } + } + } + } else if (TLVP_PRES_LEN(tp, BSSGP_IE_LOCATION_AREA, 5)) { errctr = GBPROX_GLOB_CTR_INV_LAI; - } else - LOGPC(DGPRS, LOGL_INFO, "\n"); + /* iterate over all bvcs and dispatch the paging to each matching one */ + hash_for_each(cfg->bss_nses, i, nse, list) { + hash_for_each(nse->bvcs, j, bss_bvc, list) { + if (!memcmp(bss_bvc->ra, TLVP_VAL(tp, BSSGP_IE_LOCATION_AREA), 5)) { + LOGPNSE(nse, LOGL_INFO, "Rx %s: routing to NSE (LAI match)\n", + pdut_name); + gbprox_relay2peer(msg, bss_bvc, ns_bvci); + n_nses++; + /* Only send it once to each NSE */ + break; + } + } + } + } else if (TLVP_PRES_LEN(tp, BSSGP_IE_BSS_AREA_ID, 1) || broadcast) { + /* iterate over all bvcs and dispatch the paging to each matching one */ + hash_for_each(cfg->bss_nses, i, nse, list) { + hash_for_each(nse->bvcs, j, bss_bvc, list) { + LOGPNSE(nse, LOGL_INFO, "Rx %s:routing to NSE (broadcast)\n", pdut_name); + gbprox_relay2peer(msg, bss_bvc, ns_bvci); + n_nses++; + /* Only send it once to each NSE */ + break; + } + } + } else { + LOGPNSE(sgsn_nse, LOGL_ERROR, "BSSGP PAGING: unable to route, missing IE\n"); + rate_ctr_inc(&cfg->ctrg->ctr[errctr]); + } - if (!peer) { - LOGP(DGPRS, LOGL_ERROR, "NSEI=%u(SGSN) BSSGP PAGING: " - "unable to route, missing IE\n", nsei); + if (n_nses == 0) { + LOGPNSE(sgsn_nse, LOGL_ERROR, "BSSGP PAGING: unable to route, no destination found\n"); rate_ctr_inc(&cfg->ctrg->ctr[errctr]); return -EINVAL; } - return gbprox_relay2peer(msg, peer, ns_bvci); + return 0; } /* Receive an incoming BVC-RESET message from the SGSN */ -static int rx_reset_from_sgsn(struct gbproxy_config *cfg, - struct msgb *orig_msg, - struct msgb *msg, struct tlv_parsed *tp, - uint32_t nsei, uint16_t ns_bvci) +static int rx_bvc_reset_from_sgsn(struct gbproxy_nse *nse, struct msgb *msg, struct tlv_parsed *tp, + uint16_t ns_bvci) { - struct gbproxy_peer *peer; - uint16_t ptp_bvci; + uint16_t ptp_bvci = ntohs(tlvp_val16_unal(tp, BSSGP_IE_BVCI)); + struct gbproxy_bvc *from_bvc; - if (!TLVP_PRESENT(tp, BSSGP_IE_BVCI)) { - rate_ctr_inc(&cfg->ctrg-> - ctr[GBPROX_GLOB_CTR_PROTO_ERR_SGSN]); - return bssgp_tx_status(BSSGP_CAUSE_MISSING_MAND_IE, - NULL, orig_msg); - } - ptp_bvci = ntohs(tlvp_val16_unal(tp, BSSGP_IE_BVCI)); - - if (ptp_bvci >= 2) { - /* A reset for a PTP BVC was received, forward it to its - * respective peer */ - peer = gbproxy_peer_by_bvci(cfg, ptp_bvci); - if (!peer) { - LOGP(DGPRS, LOGL_ERROR, "NSEI=%u BVCI=%u: Cannot find BSS\n", - nsei, ptp_bvci); - rate_ctr_inc(&cfg->ctrg-> - ctr[GBPROX_GLOB_CTR_INV_BVCI]); - return bssgp_tx_status(BSSGP_CAUSE_UNKNOWN_BVCI, - &ptp_bvci, orig_msg); + LOGPNSE(nse, LOGL_INFO, "Rx BVC-RESET (BVCI=%05u)\n", ptp_bvci); + + if (ptp_bvci == 0) { + from_bvc = gbproxy_bvc_by_bvci(nse, 0); + OSMO_ASSERT(from_bvc); + osmo_fsm_inst_dispatch(from_bvc->fi, BSSGP_BVCFSM_E_RX_RESET, msg); + } else { + from_bvc = gbproxy_bvc_by_bvci(nse, ptp_bvci); + if (!from_bvc) { + LOGPNSE(nse, LOGL_ERROR, "Rx BVC-RESET BVCI=%05u: Cannot find BVC\n", ptp_bvci); + rate_ctr_inc(&nse->cfg->ctrg->ctr[GBPROX_GLOB_CTR_INV_BVCI]); + return bssgp_tx_status(BSSGP_CAUSE_UNKNOWN_BVCI, &ptp_bvci, msg); } - return gbprox_relay2peer(msg, peer, ns_bvci); + osmo_fsm_inst_dispatch(from_bvc->fi, BSSGP_BVCFSM_E_RX_RESET, msg); } - /* A reset for the Signalling entity has been received - * from the SGSN. As the signalling BVCI is shared - * among all the BSS's that we multiplex, it needs to - * be relayed */ - llist_for_each_entry(peer, &cfg->bts_peers, list) - gbprox_relay2peer(msg, peer, ns_bvci); - return 0; } /* Receive an incoming signalling message from the SGSN-side NS-VC */ -static int gbprox_rx_sig_from_sgsn(struct gbproxy_config *cfg, - struct msgb *orig_msg, uint32_t nsei, - uint16_t ns_bvci) +static int gbprox_rx_sig_from_sgsn(struct gbproxy_nse *nse, struct msgb *msg, uint16_t ns_bvci) { - struct bssgp_normal_hdr *bgph = - (struct bssgp_normal_hdr *) msgb_bssgph(orig_msg); - struct tlv_parsed tp; + struct bssgp_normal_hdr *bgph = (struct bssgp_normal_hdr *) msgb_bssgph(msg); uint8_t pdu_type = bgph->pdu_type; + const char *pdut_name = osmo_tlv_prot_msg_name(&osmo_pdef_bssgp, bgph->pdu_type); + struct gbproxy_config *cfg = nse->cfg; + struct gbproxy_bvc *sgsn_bvc; + struct tlv_parsed tp; int data_len; - struct gbproxy_peer *peer; uint16_t bvci; - struct msgb *msg; + char log_pfx[32]; int rc = 0; int cause; + int i; + bool paging_bc = false; + + snprintf(log_pfx, sizeof(log_pfx), "NSE(%05u/SGSN)-BVC(%05u/??)", nse->nsei, ns_bvci); + + LOGP(DGPRS, LOGL_DEBUG, "%s Rx %s\n", log_pfx, pdut_name); if (ns_bvci != 0 && ns_bvci != 1) { - LOGP(DGPRS, LOGL_NOTICE, "NSEI=%u(SGSN) BVCI=%u is not " - "signalling\n", nsei, ns_bvci); - /* FIXME: Send proper error message */ - return -EINVAL; + LOGP(DGPRS, LOGL_NOTICE, "%s BVCI=%05u is not signalling\n", log_pfx, ns_bvci); + return bssgp_tx_status(BSSGP_CAUSE_PROTO_ERR_UNSPEC, NULL, msg); + } + + if (!(bssgp_pdu_type_flags(pdu_type) & BSSGP_PDUF_SIG)) { + LOGP(DGPRS, LOGL_NOTICE, "%s %s not allowed in signalling BVC\n", log_pfx, pdut_name); + return bssgp_tx_status(BSSGP_CAUSE_PROTO_ERR_UNSPEC, NULL, msg); } - /* we actually should never see those two for BVCI == 0, but double-check - * just to make sure */ - if (pdu_type == BSSGP_PDUT_UL_UNITDATA || - pdu_type == BSSGP_PDUT_DL_UNITDATA) { - LOGP(DGPRS, LOGL_NOTICE, "NSEI=%u(SGSN) UNITDATA not allowed in " - "signalling\n", nsei); - return bssgp_tx_status(BSSGP_CAUSE_PROTO_ERR_UNSPEC, NULL, orig_msg); + if (!(bssgp_pdu_type_flags(pdu_type) & BSSGP_PDUF_DL)) { + LOGP(DGPRS, LOGL_NOTICE, "%s %s not allowed in downlink direction\n", log_pfx, pdut_name); + return bssgp_tx_status(BSSGP_CAUSE_PROTO_ERR_UNSPEC, NULL, msg); } - msg = bssgp_msgb_copy(orig_msg, "rx_sig_from_sgsn"); - gbprox_process_bssgp_dl(cfg, msg, NULL); - /* Update message info */ - bgph = (struct bssgp_normal_hdr *) msgb_bssgph(msg); - data_len = msgb_bssgp_len(orig_msg) - sizeof(*bgph); - rc = bssgp_tlv_parse(&tp, bgph->data, data_len); + data_len = msgb_bssgp_len(msg) - sizeof(*bgph); + + rc = osmo_tlv_prot_parse(&osmo_pdef_bssgp, &tp, 1, pdu_type, bgph->data, data_len, 0, 0, + DGPRS, log_pfx); + if (rc < 0) { + rc = tx_status_from_tlvp(rc, msg); + rate_ctr_inc(&cfg->ctrg->ctr[GBPROX_GLOB_CTR_PROTO_ERR_SGSN]); + return rc; + } + /* hack to get both msg + tlv_parsed passed via osmo_fsm_inst_dispatch */ + msgb_bcid(msg) = (void *)&tp; switch (pdu_type) { case BSSGP_PDUT_BVC_RESET: - rc = rx_reset_from_sgsn(cfg, msg, orig_msg, &tp, nsei, ns_bvci); + /* resolve or create ggbproxy_bvc + handle in BVC-FSM */ + bvci = ntohs(tlvp_val16_unal(&tp, BSSGP_IE_BVCI)); + rc = rx_bvc_reset_from_sgsn(nse, msg, &tp, ns_bvci); break; case BSSGP_PDUT_BVC_RESET_ACK: - if (cfg->route_to_sgsn2 && nsei == cfg->nsip_sgsn2_nsei) - break; - /* fall through */ + bvci = ntohs(tlvp_val16_unal(&tp, BSSGP_IE_BVCI)); + sgsn_bvc = gbproxy_bvc_by_bvci(nse, bvci); + if (!sgsn_bvc) + goto err_no_bvc; + rc = osmo_fsm_inst_dispatch(sgsn_bvc->fi, BSSGP_BVCFSM_E_RX_RESET_ACK, msg); + break; + case BSSGP_PDUT_BVC_BLOCK_ACK: + bvci = ntohs(tlvp_val16_unal(&tp, BSSGP_IE_BVCI)); + sgsn_bvc = gbproxy_bvc_by_bvci(nse, bvci); + if (!sgsn_bvc) + goto err_no_bvc; + rc = osmo_fsm_inst_dispatch(sgsn_bvc->fi, BSSGP_BVCFSM_E_RX_BLOCK_ACK, msg); + break; + case BSSGP_PDUT_BVC_UNBLOCK_ACK: + bvci = ntohs(tlvp_val16_unal(&tp, BSSGP_IE_BVCI)); + sgsn_bvc = gbproxy_bvc_by_bvci(nse, bvci); + if (!sgsn_bvc) + goto err_no_bvc; + rc = osmo_fsm_inst_dispatch(sgsn_bvc->fi, BSSGP_BVCFSM_E_RX_UNBLOCK_ACK, msg); + break; case BSSGP_PDUT_FLUSH_LL: /* simple case: BVCI IE is mandatory */ - if (!TLVP_PRESENT(&tp, BSSGP_IE_BVCI)) - goto err_mand_ie; bvci = ntohs(tlvp_val16_unal(&tp, BSSGP_IE_BVCI)); - rc = gbprox_relay2bvci(cfg, msg, bvci, ns_bvci); + sgsn_bvc = gbproxy_bvc_by_bvci(nse, bvci); + if (!sgsn_bvc) + goto err_no_bvc; + if (sgsn_bvc->cell && sgsn_bvc->cell->bss_bvc) + rc = gbprox_relay2peer(msg, sgsn_bvc->cell->bss_bvc, ns_bvci); break; + case BSSGP_PDUT_DUMMY_PAGING_PS: + /* Routing area is optional in dummy paging and we have nothing else to go by + * so in case it is missing we need to broadcast the paging */ + paging_bc = true; + /* fall through */ case BSSGP_PDUT_PAGING_PS: + { + /* Cache the IMSI<->NSE to route PAGING REJECT */ + struct osmo_mobile_identity mi; + const uint8_t *mi_data = TLVP_VAL(&tp, BSSGP_IE_IMSI); + uint8_t mi_len = TLVP_LEN(&tp, BSSGP_IE_IMSI); + osmo_mobile_identity_decode(&mi, mi_data, mi_len, false); + gbproxy_imsi_cache_update(nse, mi.imsi); + /* fall through */ + } case BSSGP_PDUT_PAGING_CS: /* process the paging request (LAI/RAI lookup) */ - rc = gbprox_rx_paging(cfg, msg, &tp, nsei, ns_bvci); + rc = gbprox_rx_paging(nse, msg, pdut_name, &tp, ns_bvci, paging_bc); break; case BSSGP_PDUT_STATUS: /* Some exception has occurred */ - LOGP(DGPRS, LOGL_NOTICE, - "NSEI=%u(SGSN) BSSGP STATUS ", nsei); - if (!TLVP_PRESENT(&tp, BSSGP_IE_CAUSE)) { - LOGPC(DGPRS, LOGL_NOTICE, "\n"); - goto err_mand_ie; - } cause = *TLVP_VAL(&tp, BSSGP_IE_CAUSE); - LOGPC(DGPRS, LOGL_NOTICE, - "cause=0x%02x(%s) ", *TLVP_VAL(&tp, BSSGP_IE_CAUSE), + LOGPNSE(nse, LOGL_NOTICE, "Rx STATUS cause=0x%02x(%s) ", cause, bssgp_cause_str(cause)); - if (TLVP_PRESENT(&tp, BSSGP_IE_BVCI)) { + if (TLVP_PRES_LEN(&tp, BSSGP_IE_BVCI, 2)) { bvci = ntohs(tlvp_val16_unal(&tp, BSSGP_IE_BVCI)); - LOGPC(DGPRS, LOGL_NOTICE, "BVCI=%u\n", bvci); - - if (cause == BSSGP_CAUSE_UNKNOWN_BVCI) - rc = gbprox_relay2bvci(cfg, msg, bvci, ns_bvci); + LOGPC(DGPRS, LOGL_NOTICE, "BVCI=%05u\n", bvci); + sgsn_bvc = gbproxy_bvc_by_bvci(nse, bvci); + /* don't send STATUS in response to STATUS if !bvc */ + if (sgsn_bvc && sgsn_bvc->cell && sgsn_bvc->cell->bss_bvc) + rc = gbprox_relay2peer(msg, sgsn_bvc->cell->bss_bvc, ns_bvci); } else LOGPC(DGPRS, LOGL_NOTICE, "\n"); break; @@ -1248,207 +1217,292 @@ static int gbprox_rx_sig_from_sgsn(struct gbproxy_config *cfg, case BSSGP_PDUT_SUSPEND_NACK: case BSSGP_PDUT_RESUME_ACK: case BSSGP_PDUT_RESUME_NACK: - /* RAI IE is mandatory */ - if (!TLVP_PRESENT(&tp, BSSGP_IE_ROUTEING_AREA)) - goto err_mand_ie; - peer = gbproxy_peer_by_rai(cfg, TLVP_VAL(&tp, BSSGP_IE_ROUTEING_AREA)); - if (!peer) - goto err_no_peer; - rc = gbprox_relay2peer(msg, peer, ns_bvci); - break; - case BSSGP_PDUT_BVC_BLOCK_ACK: - case BSSGP_PDUT_BVC_UNBLOCK_ACK: - if (!TLVP_PRESENT(&tp, BSSGP_IE_BVCI)) - goto err_mand_ie; - bvci = ntohs(tlvp_val16_unal(&tp, BSSGP_IE_BVCI)); - if (bvci == 0) { - LOGP(DGPRS, LOGL_NOTICE, "NSEI=%u(SGSN) BSSGP " - "%sBLOCK_ACK for signalling BVCI ?!?\n", nsei, - pdu_type == BSSGP_PDUT_BVC_UNBLOCK_ACK ? "UN":""); - /* should we send STATUS ? */ - rate_ctr_inc(&cfg->ctrg-> - ctr[GBPROX_GLOB_CTR_INV_BVCI]); - } else { - /* Mark BVC as (un)blocked */ - block_unblock_peer(cfg, bvci, pdu_type); + { + struct gbproxy_nse *nse_peer; + uint32_t tlli = osmo_load32be(TLVP_VAL(&tp, BSSGP_IE_TLLI)); + + nse_peer = gbproxy_nse_by_tlli(cfg, tlli); + if (!nse_peer) { + LOGPNSE(nse, LOGL_ERROR, "Rx %s: Cannot find NSE\n", pdut_name); + /* TODO: Counter */ + return bssgp_tx_status(BSSGP_CAUSE_INV_MAND_INF, NULL, msg); } - rc = gbprox_relay2bvci(cfg, msg, bvci, ns_bvci); + /* Delete the entry after we're done */ + gbproxy_tlli_cache_remove(cfg, tlli); + LOGPNSE(nse_peer, LOGL_DEBUG, "Rx %s: forwarding\n", pdut_name); + gbprox_relay2nse(msg, nse_peer, ns_bvci); break; + } case BSSGP_PDUT_SGSN_INVOKE_TRACE: - LOGP(DGPRS, LOGL_ERROR, - "NSEI=%u(SGSN) BSSGP INVOKE TRACE not supported\n",nsei); - rate_ctr_inc(&cfg->ctrg-> - ctr[GBPROX_GLOB_CTR_NOT_SUPPORTED_SGSN]); - rc = bssgp_tx_status(BSSGP_CAUSE_PDU_INCOMP_FEAT, NULL, orig_msg); + case BSSGP_PDUT_OVERLOAD: + LOGPNSE(nse, LOGL_DEBUG, "Rx %s: broadcasting\n", pdut_name); + /* broadcast to all BSS-side bvcs */ + hash_for_each(cfg->bss_nses, i, nse, list) { + gbprox_relay2nse(msg, nse, 0); + } + break; + case BSSGP_PDUT_RAN_INFO: + case BSSGP_PDUT_RAN_INFO_REQ: + case BSSGP_PDUT_RAN_INFO_ACK: + case BSSGP_PDUT_RAN_INFO_ERROR: + case BSSGP_PDUT_RAN_INFO_APP_ERROR: + /* FIXME: route based in RIM Routing IE */ + rc = bssgp_tx_status(BSSGP_CAUSE_PDU_INCOMP_FEAT, NULL, msg); break; default: - LOGP(DGPRS, LOGL_NOTICE, "BSSGP PDU type %s not supported\n", bssgp_pdu_str(pdu_type)); - rate_ctr_inc(&cfg->ctrg-> - ctr[GBPROX_GLOB_CTR_PROTO_ERR_SGSN]); - rc = bssgp_tx_status(BSSGP_CAUSE_PROTO_ERR_UNSPEC, NULL, orig_msg); + LOGPNSE(nse, LOGL_NOTICE, "Rx %s: Not supported\n", pdut_name); + rate_ctr_inc(&cfg->ctrg->ctr[GBPROX_GLOB_CTR_PROTO_ERR_SGSN]); + rc = bssgp_tx_status(BSSGP_CAUSE_PROTO_ERR_UNSPEC, NULL, msg); break; } - msgb_free(msg); - return rc; -err_mand_ie: - LOGP(DGPRS, LOGL_ERROR, "NSEI=%u(SGSN) missing mandatory IE\n", - nsei); - rate_ctr_inc(&cfg->ctrg-> - ctr[GBPROX_GLOB_CTR_PROTO_ERR_SGSN]); - msgb_free(msg); - return bssgp_tx_status(BSSGP_CAUSE_MISSING_MAND_IE, NULL, orig_msg); -err_no_peer: - LOGP(DGPRS, LOGL_ERROR, "NSEI=%u(SGSN) cannot find peer based on RAI\n", - nsei); + +err_no_bvc: + LOGPNSE(nse, LOGL_ERROR, "Rx %s: Cannot find BVC\n", pdut_name); rate_ctr_inc(&cfg->ctrg-> ctr[GBPROX_GLOB_CTR_INV_RAI]); - msgb_free(msg); - return bssgp_tx_status(BSSGP_CAUSE_INV_MAND_INF, NULL, orig_msg); + return bssgp_tx_status(BSSGP_CAUSE_INV_MAND_INF, NULL, msg); } -static int gbproxy_is_sgsn_nsei(struct gbproxy_config *cfg, uint16_t nsei) -{ - return nsei == cfg->nsip_sgsn_nsei || - (cfg->route_to_sgsn2 && nsei == cfg->nsip_sgsn2_nsei); -} -/* Main input function for Gb proxy */ -int gbprox_rcvmsg(struct gbproxy_config *cfg, struct msgb *msg, uint16_t nsei, - uint16_t ns_bvci, uint16_t nsvci) +/*********************************************************************** + * libosmogb NS/BSSGP integration + ***********************************************************************/ + +int gbprox_bssgp_send_cb(void *ctx, struct msgb *msg) { int rc; - int remote_end_is_sgsn = gbproxy_is_sgsn_nsei(cfg, nsei); + struct gbproxy_config *cfg = (struct gbproxy_config *) ctx; + struct gprs_ns2_inst *nsi = cfg->nsi; + struct osmo_gprs_ns2_prim nsp = {}; - /* Only BVCI=0 messages need special treatment */ - if (ns_bvci == 0 || ns_bvci == 1) { - if (remote_end_is_sgsn) - rc = gbprox_rx_sig_from_sgsn(cfg, msg, nsei, ns_bvci); - else - rc = gbprox_rx_sig_from_bss(cfg, msg, nsei, ns_bvci); - } else { - /* All other BVCI are PTP */ - if (remote_end_is_sgsn) - rc = gbprox_rx_ptp_from_sgsn(cfg, msg, nsei, nsvci, - ns_bvci); - else - rc = gbprox_rx_ptp_from_bss(cfg, msg, nsei, nsvci, - ns_bvci); - } + nsp.bvci = msgb_bvci(msg); + nsp.nsei = msgb_nsei(msg); + + osmo_prim_init(&nsp.oph, SAP_NS, PRIM_NS_UNIT_DATA, PRIM_OP_REQUEST, msg); + rc = gprs_ns2_recv_prim(nsi, &nsp.oph); return rc; } -int gbprox_reset_persistent_nsvcs(struct gprs_ns_inst *nsi) +/* Main input function for Gb proxy */ +int gbprox_rcvmsg(void *ctx, struct msgb *msg) { - struct gprs_nsvc *nsvc; + struct gbproxy_config *cfg = (struct gbproxy_config *) ctx; + uint16_t ns_bvci = msgb_bvci(msg); + uint16_t nsei = msgb_nsei(msg); + struct gbproxy_nse *nse; + + /* ensure minimum length to decode PCU type */ + if (msgb_bssgp_len(msg) < sizeof(struct bssgp_normal_hdr)) + return bssgp_tx_status(BSSGP_CAUSE_SEM_INCORR_PDU, NULL, msg); + + nse = gbproxy_nse_by_nsei(cfg, nsei, NSE_F_SGSN); + if (nse) { + if (ns_bvci == 0 || ns_bvci == 1) + return gbprox_rx_sig_from_sgsn(nse, msg, ns_bvci); + else + return gbprox_rx_ptp_from_sgsn(nse, msg, ns_bvci); + } - llist_for_each_entry(nsvc, &nsi->gprs_nsvcs, list) { - if (!nsvc->persistent) - continue; - gprs_nsvc_reset(nsvc, NS_CAUSE_OM_INTERVENTION); + nse = gbproxy_nse_by_nsei(cfg, nsei, NSE_F_BSS); + if (!nse) { + LOGP(DGPRS, LOGL_NOTICE, "NSE(%05u/BSS) not known -> allocating\n", nsei); + nse = gbproxy_nse_alloc(cfg, nsei, false); + } + if (nse) { + if (ns_bvci == 0 || ns_bvci == 1) + return gbprox_rx_sig_from_bss(nse, msg, ns_bvci); + else + return gbprox_rx_ptp_from_bss(nse, msg, ns_bvci); } + return 0; } -/* Signal handler for signals from NS layer */ -int gbprox_signal(unsigned int subsys, unsigned int signal, - void *handler_data, void *signal_data) +/* TODO: What about handling: + * NS_AFF_CAUSE_VC_FAILURE, + NS_AFF_CAUSE_VC_RECOVERY, + NS_AFF_CAUSE_FAILURE, + NS_AFF_CAUSE_RECOVERY, + osmocom own causes + NS_AFF_CAUSE_SNS_CONFIGURED, + NS_AFF_CAUSE_SNS_FAILURE, + */ + +void gprs_ns_prim_status_cb(struct gbproxy_config *cfg, struct osmo_gprs_ns2_prim *nsp) { - struct gbproxy_config *cfg = handler_data; - struct ns_signal_data *nssd = signal_data; - struct gprs_nsvc *nsvc = nssd->nsvc; - struct gbproxy_peer *peer; - int remote_end_is_sgsn = gbproxy_is_sgsn_nsei(cfg, nsvc->nsei); + /* TODO: bss nsei available/unavailable bssgp_tx_simple_bvci(BSSGP_PDUT_BVC_BLOCK, nsvc->nsei, bvc->bvci, 0); + * TODO: sgsn nsei available/unavailable + */ - if (subsys != SS_L_NS) - return 0; + struct gbproxy_bvc *bvc; + struct gbproxy_nse *sgsn_nse; - if (signal == S_NS_RESET && remote_end_is_sgsn) { - /* We have received a NS-RESET from the NSEI and NSVC - * of the SGSN. This might happen with SGSN that start - * their own NS-RESET procedure without waiting for our - * NS-RESET */ - nsvc->remote_end_is_sgsn = 1; - } - - if (signal == S_NS_ALIVE_EXP && nsvc->remote_end_is_sgsn) { - LOGP(DGPRS, LOGL_NOTICE, "Tns alive expired too often, " - "re-starting RESET procedure\n"); - rate_ctr_inc(&cfg->ctrg-> - ctr[GBPROX_GLOB_CTR_RESTART_RESET_SGSN]); - gprs_ns_nsip_connect(nsvc->nsi, &nsvc->ip.bts_addr, - nsvc->nsei, nsvc->nsvci); - } + switch (nsp->u.status.cause) { + case NS_AFF_CAUSE_SNS_FAILURE: + case NS_AFF_CAUSE_SNS_CONFIGURED: + break; - if (!nsvc->remote_end_is_sgsn) { - /* from BSS to SGSN */ - peer = gbproxy_peer_by_nsei(cfg, nsvc->nsei); - if (!peer) { - LOGP(DGPRS, LOGL_NOTICE, "signal '%s' for unknown peer NSEI=%u/NSVCI=%u\n", - get_value_string(gprs_ns_signal_ns_names, signal), nsvc->nsei, nsvc->nsvci); - return 0; + case NS_AFF_CAUSE_RECOVERY: + LOGP(DGPRS, LOGL_NOTICE, "NS-NSE %d became available\n", nsp->nsei); + sgsn_nse = gbproxy_nse_by_nsei(cfg, nsp->nsei, NSE_F_SGSN); + if (sgsn_nse) { + uint8_t cause = BSSGP_CAUSE_OML_INTERV; + bvc = gbproxy_bvc_by_bvci(sgsn_nse, 0); + if (bvc) + osmo_fsm_inst_dispatch(bvc->fi, BSSGP_BVCFSM_E_REQ_RESET, &cause); } - switch (signal) { - case S_NS_RESET: - case S_NS_BLOCK: - if (!peer->blocked) - break; - LOGP(DGPRS, LOGL_NOTICE, "Converting '%s' from NSEI=%u/NSVCI=%u into BSSGP_BVC_BLOCK to SGSN\n", - get_value_string(gprs_ns_signal_ns_names, signal), nsvc->nsei, nsvc->nsvci); - bssgp_tx_simple_bvci(BSSGP_PDUT_BVC_BLOCK, nsvc->nsei, - peer->bvci, 0); - break; - } - } else { - /* Forward this message to all NS-VC to BSS */ - struct gprs_ns_inst *nsi = cfg->nsi; - struct gprs_nsvc *next_nsvc; - - llist_for_each_entry(next_nsvc, &nsi->gprs_nsvcs, list) { - if (next_nsvc->remote_end_is_sgsn) - continue; - - /* Note that the following does not start the full - * procedures including timer based retransmissions. */ - switch (signal) { - case S_NS_RESET: - gprs_ns_tx_reset(next_nsvc, nssd->cause); - break; - case S_NS_BLOCK: - gprs_ns_tx_block(next_nsvc, nssd->cause); + break; + case NS_AFF_CAUSE_FAILURE: +#if 0 + if (gbproxy_is_sgsn_nsei(cfg, nsp->nsei)) { + /* sgsn */ + /* TODO: BSVC: block all PtP towards bss */ + rate_ctr_inc(&cfg->ctrg-> + ctr[GBPROX_GLOB_CTR_RESTART_RESET_SGSN]); + } else { + /* bss became unavailable + * TODO: Block all BVC belonging to that NSE */ + bvc = gbproxy_bvc_by_nsei(cfg, nsp->nsei); + if (!bvc) { + /* TODO: use primitive name + status cause name */ + LOGP(DGPRS, LOGL_NOTICE, "Received ns2 primitive %d for unknown bvc NSEI=%u\n", + nsp->u.status.cause, nsp->nsei); break; - case S_NS_UNBLOCK: - gprs_ns_tx_unblock(next_nsvc); + } + + if (!bvc->blocked) break; + hash_for_each(cfg->sgsn_nses, _sgsn, sgsn_nse, list) { + bssgp_tx_simple_bvci(BSSGP_PDUT_BVC_BLOCK, sgsn_nse->nsei, bvc->bvci, 0); } } +#endif + LOGP(DGPRS, LOGL_NOTICE, "NS-NSE %d became unavailable\n", nsp->nsei); + break; + default: + LOGP(DGPRS, LOGL_NOTICE, "NS: Unknown NS-STATUS.ind cause=%s from NS\n", + gprs_ns2_aff_cause_prim_str(nsp->u.status.cause)); + break; } - return 0; +} + +/* called by the ns layer */ +int gprs_ns2_prim_cb(struct osmo_prim_hdr *oph, void *ctx) +{ + struct osmo_gprs_ns2_prim *nsp; + struct gbproxy_config *cfg = (struct gbproxy_config *) ctx; + uintptr_t bvci; + int rc = 0; + + if (oph->sap != SAP_NS) + return 0; + + nsp = container_of(oph, struct osmo_gprs_ns2_prim, oph); + + if (oph->operation != PRIM_OP_INDICATION) { + LOGP(DGPRS, LOGL_NOTICE, "NS: Unexpected primitive operation %s from NS\n", + get_value_string(osmo_prim_op_names, oph->operation)); + return 0; + } + + switch (oph->primitive) { + case PRIM_NS_UNIT_DATA: + + /* hand the message into the BSSGP implementation */ + msgb_bssgph(oph->msg) = oph->msg->l3h; + msgb_bvci(oph->msg) = nsp->bvci; + msgb_nsei(oph->msg) = nsp->nsei; + bvci = nsp->bvci | BVC_LOG_CTX_FLAG; + + log_set_context(LOG_CTX_GB_BVC, (void *)bvci); + rc = gbprox_rcvmsg(cfg, oph->msg); + msgb_free(oph->msg); + break; + case PRIM_NS_STATUS: + gprs_ns_prim_status_cb(cfg, nsp); + break; + default: + LOGP(DGPRS, LOGL_NOTICE, "NS: Unknown prim %s %s from NS\n", + gprs_ns2_prim_str(oph->primitive), + get_value_string(osmo_prim_op_names, oph->operation)); + break; + } + + return rc; } void gbprox_reset(struct gbproxy_config *cfg) { - struct gbproxy_peer *peer, *tmp; + struct gbproxy_nse *nse; + struct hlist_node *ntmp; + int i, j; + + hash_for_each_safe(cfg->bss_nses, i, ntmp, nse, list) { + struct gbproxy_bvc *bvc; + struct hlist_node *tmp; + hash_for_each_safe(nse->bvcs, j, tmp, bvc, list) + gbproxy_bvc_free(bvc); - llist_for_each_entry_safe(peer, tmp, &cfg->bts_peers, list) - gbproxy_peer_free(peer); + gbproxy_nse_free(nse); + } + /* FIXME: cells */ + /* FIXME: SGSN side BVCs (except signaling) */ rate_ctr_group_free(cfg->ctrg); gbproxy_init_config(cfg); } +static void tlli_cache_cleanup(void *data) +{ + struct gbproxy_config *cfg = data; + gbproxy_tlli_cache_cleanup(cfg); + + /* TODO: Disable timer when cache is empty */ + osmo_timer_schedule(&cfg->tlli_cache.timer, 2, 0); +} + +static void imsi_cache_cleanup(void *data) +{ + struct gbproxy_config *cfg = data; + gbproxy_imsi_cache_cleanup(cfg); + + /* TODO: Disable timer when cache is empty */ + osmo_timer_schedule(&cfg->imsi_cache.timer, 2, 0); +} + int gbproxy_init_config(struct gbproxy_config *cfg) { struct timespec tp; - INIT_LLIST_HEAD(&cfg->bts_peers); + /* by default we advertise 100% of the BSS-side capacity to _each_ SGSN */ + cfg->pool.bvc_fc_ratio = 100; + cfg->pool.null_nri_ranges = osmo_nri_ranges_alloc(cfg); + /* TODO: Make configurable */ + cfg->tlli_cache.timeout = 10; + cfg->imsi_cache.timeout = 10; + + hash_init(cfg->bss_nses); + hash_init(cfg->sgsn_nses); + hash_init(cfg->cells); + hash_init(cfg->tlli_cache.entries); + INIT_LLIST_HEAD(&cfg->sgsns); + + osmo_timer_setup(&cfg->tlli_cache.timer, tlli_cache_cleanup, cfg); + osmo_timer_schedule(&cfg->tlli_cache.timer, 2, 0); + + /* We could also combine both timers */ + osmo_timer_setup(&cfg->imsi_cache.timer, imsi_cache_cleanup, cfg); + osmo_timer_schedule(&cfg->imsi_cache.timer, 2, 0); + cfg->ctrg = rate_ctr_group_alloc(tall_sgsn_ctx, &global_ctrg_desc, 0); if (!cfg->ctrg) { LOGP(DGPRS, LOGL_ERROR, "Cannot allocate global counter group!\n"); return -1; } osmo_clock_gettime(CLOCK_REALTIME, &tp); + osmo_fsm_log_timeouts(true); return 0; -} +}
\ No newline at end of file diff --git a/src/gbproxy/gb_proxy_ctrl.c b/src/gbproxy/gb_proxy_ctrl.c index 4b7c2f43..45616346 100644 --- a/src/gbproxy/gb_proxy_ctrl.c +++ b/src/gbproxy/gb_proxy_ctrl.c @@ -33,19 +33,45 @@ extern vector ctrl_node_vec; +struct nsvc_cb_data { + struct ctrl_cmd *cmd; + uint16_t nsei; + bool is_sgsn; +}; + +static int ctrl_nsvc_state_cb(struct gprs_ns2_vc *nsvc, void *ctx) { + struct nsvc_cb_data *data = (struct nsvc_cb_data *)ctx; + struct ctrl_cmd *cmd = (struct ctrl_cmd *)data->cmd; + + cmd->reply = talloc_asprintf_append(cmd->reply, "%u,%s,%s,%s\n", + data->nsei, gprs_ns2_ll_str(nsvc), gprs_ns2_nsvc_state_name(nsvc), + data->is_sgsn ? "SGSN" : "BSS" ); + + return 0; +} + static int get_nsvc_state(struct ctrl_cmd *cmd, void *data) { struct gbproxy_config *cfg = data; - struct gprs_ns_inst *nsi = cfg->nsi; - struct gprs_nsvc *nsvc; + struct gprs_ns2_inst *nsi = cfg->nsi; + struct gprs_ns2_nse *nse; + struct gbproxy_nse *nse_peer; + int i; cmd->reply = talloc_strdup(cmd, ""); - llist_for_each_entry(nsvc, &nsi->gprs_nsvcs, list) { - if (nsvc == nsi->unknown_nsvc) - continue; + /* NS-VCs for SGSN */ + hash_for_each(cfg->sgsn_nses, i, nse_peer, list) { + nse = gprs_ns2_nse_by_nsei(nsi, nse_peer->nsei); + if (nse) + gprs_ns2_nse_foreach_nsvc(nse, &ctrl_nsvc_state_cb, cmd); + } - cmd->reply = gprs_nsvc_state_append(cmd->reply, nsvc); + /* NS-VCs for BSS peers */ + hash_for_each(cfg->bss_nses, i, nse_peer, list) { + nse = gprs_ns2_nse_by_nsei(nsi, nse_peer->nsei); + if (nse) + gprs_ns2_nse_foreach_nsvc(nse, &ctrl_nsvc_state_cb, cmd); } return CTRL_CMD_REPLY; @@ -56,19 +82,23 @@ CTRL_CMD_DEFINE_RO(nsvc_state, "nsvc-state"); static int get_gbproxy_state(struct ctrl_cmd *cmd, void *data) { struct gbproxy_config *cfg = data; - struct gbproxy_peer *peer; + struct gbproxy_nse *nse_peer; + int i, j; cmd->reply = talloc_strdup(cmd, ""); - llist_for_each_entry(peer, &cfg->bts_peers, list) { - struct gprs_ra_id raid; - gsm48_parse_ra(&raid, peer->ra); - - cmd->reply = talloc_asprintf_append(cmd->reply, "%u,%u,%u,%u,%u,%u,%s\n", - peer->nsei, peer->bvci, - raid.mcc, raid.mnc, - raid.lac, raid.rac, - peer->blocked ? "BLOCKED" : "UNBLOCKED"); + hash_for_each(cfg->bss_nses, i, nse_peer, list) { + struct gbproxy_bvc *bvc; + hash_for_each(nse_peer->bvcs, j, bvc, list) { + struct gprs_ra_id raid; + gsm48_parse_ra(&raid, bvc->ra); + + cmd->reply = talloc_asprintf_append(cmd->reply, "%u,%u,%u,%u,%u,%u,%s\n", + nse_peer->nsei, bvc->bvci, + raid.mcc, raid.mnc, + raid.lac, raid.rac, + osmo_fsm_inst_state_name(bvc->fi)); + } } return CTRL_CMD_REPLY; @@ -79,9 +109,18 @@ CTRL_CMD_DEFINE_RO(gbproxy_state, "gbproxy-state"); static int get_num_peers(struct ctrl_cmd *cmd, void *data) { struct gbproxy_config *cfg = data; + struct gbproxy_nse *nse_peer; + struct gbproxy_bvc *bvc; + uint32_t count = 0; + int i, j; + + hash_for_each(cfg->bss_nses, i, nse_peer, list) { + hash_for_each(nse_peer->bvcs, j, bvc, list) + count++; + } cmd->reply = talloc_strdup(cmd, ""); - cmd->reply = talloc_asprintf_append(cmd->reply, "%u", llist_count(&cfg->bts_peers)); + cmd->reply = talloc_asprintf_append(cmd->reply, "%u", count); return CTRL_CMD_REPLY; } diff --git a/src/gbproxy/gb_proxy_main.c b/src/gbproxy/gb_proxy_main.c index 8c839804..37afb5e7 100644 --- a/src/gbproxy/gb_proxy_main.c +++ b/src/gbproxy/gb_proxy_main.c @@ -38,7 +38,7 @@ #include <osmocom/core/rate_ctr.h> #include <osmocom/core/stats.h> -#include <osmocom/gprs/gprs_ns.h> +#include <osmocom/gprs/gprs_ns2.h> #include <osmocom/gprs/gprs_bssgp.h> #include <osmocom/sgsn/signal.h> @@ -80,31 +80,11 @@ static int daemonize = 0; /* Pointer to the SGSN peer */ extern struct gbprox_peer *gbprox_peer_sgsn; -/* call-back function for the NS protocol */ -static int proxy_ns_cb(enum gprs_ns_evt event, struct gprs_nsvc *nsvc, - struct msgb *msg, uint16_t bvci) +static void signal_handler(int signum) { - int rc = 0; + fprintf(stdout, "signal %u received\n", signum); - switch (event) { - case GPRS_NS_EVT_UNIT_DATA: - rc = gbprox_rcvmsg(gbcfg, msg, nsvc->nsei, bvci, nsvc->nsvci); - break; - default: - LOGP(DGPRS, LOGL_ERROR, "SGSN: Unknown event %u from NS\n", event); - if (msg) - msgb_free(msg); - rc = -EIO; - break; - } - return rc; -} - -static void signal_handler(int signal) -{ - fprintf(stdout, "signal %u received\n", signal); - - switch (signal) { + switch (signum) { case SIGINT: case SIGTERM: osmo_signal_dispatch(SS_L_GLOBAL, S_L_GLOBAL_SHUTDOWN, NULL); @@ -112,8 +92,17 @@ static void signal_handler(int signal) exit(0); break; case SIGABRT: - /* in case of abort, we want to obtain a talloc report - * and then return to the caller, who will abort the process */ + /* in case of abort, we want to obtain a talloc report and + * then run default SIGABRT handler, who will generate coredump + * and abort the process. abort() should do this for us after we + * return, but program wouldn't exit if an external SIGABRT is + * received. + */ + talloc_report(tall_vty_ctx, stderr); + talloc_report_full(tall_sgsn_ctx, stderr); + signal(SIGABRT, SIG_DFL); + raise(SIGABRT); + break; case SIGUSR1: talloc_report(tall_vty_ctx, stderr); talloc_report_full(tall_sgsn_ctx, stderr); @@ -203,39 +192,9 @@ static void handle_options(int argc, char **argv) } } -int gbproxy_vty_is_config_node(struct vty *vty, int node) -{ - switch (node) { - /* add items that are not config */ - case CONFIG_NODE: - return 0; - - default: - return 1; - } -} - -int gbproxy_vty_go_parent(struct vty *vty) -{ - switch (vty->node) { - case GBPROXY_NODE: - default: - if (gbproxy_vty_is_config_node(vty, vty->node)) - vty->node = CONFIG_NODE; - else - vty->node = ENABLE_NODE; - - vty->index = NULL; - } - - return vty->node; -} - static struct vty_app_info vty_info = { .name = "OsmoGbProxy", .version = PACKAGE_VERSION, - .go_parent_cb = gbproxy_vty_go_parent, - .is_config_node = gbproxy_vty_is_config_node, }; /* default categories */ @@ -250,10 +209,11 @@ static struct log_info_cat gprs_categories[] = { .description = "GPRS Network Service (NS)", .enabled = 1, .loglevel = LOGL_INFO, }, - [DBSSGP] = { - .name = "DBSSGP", - .description = "GPRS BSS Gateway Protocol (BSSGP)", - .enabled = 1, .loglevel = LOGL_DEBUG, + [DOBJ] = { + .name = "DOBJ", + .description = "GbProxy object allocation/release", + .enabled = 1, + .color = "\033[38;5;121m" }, }; @@ -269,6 +229,8 @@ static bool file_exists(const char *path) return stat(path, &sb) ? false : true; } +int gbprox_bssgp_send_cb(void *ctx, struct msgb *msg); + int main(int argc, char **argv) { int rc; @@ -292,6 +254,7 @@ int main(int argc, char **argv) logging_vty_add_cmds(); osmo_talloc_vty_add_cmds(); osmo_stats_vty_add_cmds(); + osmo_fsm_vty_add_cmds(); gbproxy_vty_init(); handle_options(argc, argv); @@ -314,23 +277,23 @@ int main(int argc, char **argv) rate_ctr_init(tall_sgsn_ctx); osmo_stats_init(tall_sgsn_ctx); - bssgp_nsi = gprs_ns_instantiate(&proxy_ns_cb, tall_sgsn_ctx); - if (!bssgp_nsi) { - LOGP(DGPRS, LOGL_ERROR, "Unable to instantiate NS\n"); - exit(1); - } - gbcfg = talloc_zero(tall_sgsn_ctx, struct gbproxy_config); if (!gbcfg) { LOGP(DGPRS, LOGL_FATAL, "Unable to allocate config\n"); exit(1); } gbproxy_init_config(gbcfg); - gbcfg->nsi = bssgp_nsi; - gprs_ns_vty_init(bssgp_nsi); - gprs_ns_set_log_ss(DNS); - bssgp_set_log_ss(DBSSGP); - osmo_signal_register_handler(SS_L_NS, &gbprox_signal, gbcfg); + gbcfg->nsi = gprs_ns2_instantiate(tall_sgsn_ctx, gprs_ns2_prim_cb, gbcfg); + if (!gbcfg->nsi) { + LOGP(DGPRS, LOGL_ERROR, "Unable to instantiate NS\n"); + exit(1); + } + + gprs_ns2_vty2_init(gbcfg->nsi); + logging_vty_add_deprecated_subsys(tall_sgsn_ctx, "bssgp"); + gprs_ns2_dynamic_create_nse(gbcfg->nsi, true); + + bssgp_set_bssgp_callback(gbprox_bssgp_send_cb, gbcfg); rc = gbproxy_parse_config(config_file, gbcfg); if (rc < 0) { @@ -357,26 +320,6 @@ int main(int argc, char **argv) exit(1); } - if (!gprs_nsvc_by_nsei(gbcfg->nsi, gbcfg->nsip_sgsn_nsei)) { - LOGP(DGPRS, LOGL_FATAL, "You cannot proxy to NSEI %u " - "without creating that NSEI before\n", - gbcfg->nsip_sgsn_nsei); - exit(2); - } - - rc = gprs_ns_nsip_listen(bssgp_nsi); - if (rc < 0) { - LOGP(DGPRS, LOGL_FATAL, "Cannot bind/listen on NSIP socket\n"); - exit(2); - } - - rc = gprs_ns_frgre_listen(bssgp_nsi); - if (rc < 0) { - LOGP(DGPRS, LOGL_FATAL, "Cannot bind/listen GRE " - "socket. Do you have CAP_NET_RAW?\n"); - exit(2); - } - if (daemonize) { rc = osmo_daemonize(); if (rc < 0) { @@ -385,9 +328,6 @@ int main(int argc, char **argv) } } - /* Reset all the persistent NS-VCs that we've read from the config */ - gbprox_reset_persistent_nsvcs(bssgp_nsi); - while (1) { rc = osmo_select_main(0); if (rc < 0) diff --git a/src/gbproxy/gb_proxy_patch.c b/src/gbproxy/gb_proxy_patch.c deleted file mode 100644 index 2bc3b4b7..00000000 --- a/src/gbproxy/gb_proxy_patch.c +++ /dev/null @@ -1,463 +0,0 @@ -/* 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 <osmocom/sgsn/gb_proxy.h> - -#include <osmocom/sgsn/gprs_utils.h> -#include <osmocom/sgsn/gprs_gb_parse.h> - -#include <osmocom/sgsn/debug.h> - -#include <osmocom/gprs/protocol/gsm_08_18.h> -#include <osmocom/core/rate_ctr.h> -#include <osmocom/gsm/apn.h> - -extern void *tall_sgsn_ctx; - -/* patch RA identifier in place */ -static void gbproxy_patch_raid(struct gsm48_ra_id *raid_enc, struct gbproxy_peer *peer, - int to_bss, const char *log_text) -{ - struct gbproxy_patch_state *state = &peer->patch_state; - struct osmo_plmn_id old_plmn; - struct gprs_ra_id raid; - enum gbproxy_peer_ctr counter = - to_bss ? - GBPROX_PEER_CTR_RAID_PATCHED_SGSN : - GBPROX_PEER_CTR_RAID_PATCHED_BSS; - - if (!state->local_plmn.mcc || !state->local_plmn.mnc) - return; - - gsm48_parse_ra(&raid, (uint8_t *)raid_enc); - - old_plmn = (struct osmo_plmn_id){ - .mcc = raid.mcc, - .mnc = raid.mnc, - .mnc_3_digits = raid.mnc_3_digits, - }; - - if (!to_bss) { - /* BSS -> SGSN */ - if (state->local_plmn.mcc) - raid.mcc = peer->cfg->core_plmn.mcc; - - if (state->local_plmn.mnc) { - raid.mnc = peer->cfg->core_plmn.mnc; - raid.mnc_3_digits = peer->cfg->core_plmn.mnc_3_digits; - } - } else { - /* SGSN -> BSS */ - if (state->local_plmn.mcc) - raid.mcc = state->local_plmn.mcc; - - if (state->local_plmn.mnc) { - raid.mnc = state->local_plmn.mnc; - raid.mnc_3_digits = state->local_plmn.mnc_3_digits; - } - } - - LOGP(DGPRS, LOGL_DEBUG, - "Patching %s to %s: " - "%s-%d-%d -> %s\n", - log_text, - to_bss ? "BSS" : "SGSN", - osmo_plmn_name(&old_plmn), raid.lac, raid.rac, - osmo_rai_name(&raid)); - - gsm48_encode_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, - osmo_apn_to_str(str1, apn, apn_len)); - - *new_apn_ie_len = 0; - 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, - osmo_apn_to_str(str1, apn, apn_len), - osmo_apn_to_str(str2, peer->cfg->core_apn, - peer->cfg->core_apn_size)); - - *new_apn_ie_len = peer->cfg->core_apn_size + 2; - 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, 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, &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_link_info *link_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; - struct gbproxy_config *cfg = peer->cfg; - - if (parse_ctx->ptmsi_enc && link_info && - !parse_ctx->old_raid_is_foreign && peer->cfg->patch_ptmsi) { - uint32_t ptmsi; - if (parse_ctx->to_bss) - ptmsi = link_info->tlli.ptmsi; - else - ptmsi = link_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 && link_info && cfg->patch_ptmsi) { - uint32_t ptmsi; - if (parse_ctx->to_bss) - ptmsi = link_info->tlli.ptmsi; - else - ptmsi = link_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((struct gsm48_ra_id *)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_is_foreign) { - /* TODO: Patch to invalid if P-TMSI unknown. */ - gbproxy_patch_raid((struct gsm48_ra_id *)parse_ctx->old_raid_enc, peer, parse_ctx->to_bss, - parse_ctx->llc_msg_name); - have_patched = 1; - } - - if (parse_ctx->apn_ie && - cfg->core_apn && - !parse_ctx->to_bss && - gbproxy_imsi_matches(cfg, GBPROX_MATCH_PATCHING, link_info) && - cfg->core_apn) { - 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_plmn.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_link_info *link_info, int *len_change, - struct gprs_gb_parse_context *parse_ctx) -{ - const char *err_info = NULL; - int err_ctr = -1; - - if (parse_ctx->bssgp_raid_enc) - gbproxy_patch_raid((struct gsm48_ra_id *)parse_ctx->bssgp_raid_enc, peer, - parse_ctx->to_bss, "BSSGP"); - - if (parse_ctx->need_decryption && - (peer->cfg->patch_ptmsi || peer->cfg->core_apn)) { - /* 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 (!link_info && parse_ctx->tlli_enc && 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; - } - - if (!link_info) - return; - - if (parse_ctx->tlli_enc && peer->cfg->patch_ptmsi) { - uint32_t tlli = gbproxy_map_tlli(parse_ctx->tlli, - link_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 { - /* Internal error */ - err_ctr = GBPROX_PEER_CTR_PATCH_ERR; - err_info = "Replacement TLLI is 0"; - goto patch_error; - } - } - - if (parse_ctx->bssgp_ptmsi_enc && peer->cfg->patch_ptmsi) { - uint32_t ptmsi; - if (parse_ctx->to_bss) - ptmsi = link_info->tlli.ptmsi; - else - ptmsi = link_info->sgsn_tlli.ptmsi; - - if (ptmsi != GSM_RESERVED_TMSI) - gbproxy_patch_ptmsi( - parse_ctx->bssgp_ptmsi_enc, peer, - ptmsi, parse_ctx->to_bss, "BSSGP P-TMSI"); - } - - 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, link_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_match *match) -{ - if (match->enable) { - regfree(&match->re_comp); - match->enable = false; - } - talloc_free(match->re_str); - match->re_str = NULL; -} - -int gbproxy_set_patch_filter(struct gbproxy_match *match, const char *filter, - const char **err_msg) -{ - static char err_buf[300]; - int rc; - - gbproxy_clear_patch_filter(match); - - if (!filter) - return 0; - - rc = regcomp(&match->re_comp, filter, - REG_EXTENDED | REG_NOSUB | REG_ICASE); - - if (rc == 0) { - match->enable = true; - match->re_str = talloc_strdup(tall_sgsn_ctx, filter); - return 0; - } - - if (err_msg) { - regerror(rc, &match->re_comp, - err_buf, sizeof(err_buf)); - *err_msg = err_buf; - } - - return -1; -} - -int gbproxy_check_imsi(struct gbproxy_match *match, - const uint8_t *imsi, size_t imsi_len) -{ - int rc; - struct osmo_mobile_identity mi; - - if (!match->enable) - return 1; - - rc = osmo_mobile_identity_decode(&mi, imsi, imsi_len, false); - if (rc || mi.type != GSM_MI_TYPE_IMSI) { - 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.imsi, rc); - - rc = regexec(&match->re_comp, mi.imsi, 0, NULL, 0); - if (rc == REG_NOMATCH) { - LOGP(DGPRS, LOGL_INFO, - "IMSI '%s' doesn't match pattern '%s'\n", - mi.imsi, match->re_str); - return 0; - } - - return 1; -} diff --git a/src/gbproxy/gb_proxy_peer.c b/src/gbproxy/gb_proxy_peer.c index 48482b6a..7d6ba864 100644 --- a/src/gbproxy/gb_proxy_peer.c +++ b/src/gbproxy/gb_proxy_peer.c @@ -25,216 +25,735 @@ #include <osmocom/sgsn/debug.h> #include <osmocom/gprs/protocol/gsm_08_18.h> +#include <osmocom/core/crc16.h> +#include <osmocom/core/logging.h> +#include <osmocom/core/linuxlist.h> #include <osmocom/core/rate_ctr.h> #include <osmocom/core/stats.h> #include <osmocom/core/talloc.h> +#include <osmocom/core/utils.h> #include <osmocom/gsm/tlv.h> #include <string.h> extern void *tall_sgsn_ctx; -static const struct rate_ctr_desc peer_ctr_description[] = { +static const struct rate_ctr_desc bvc_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 " }, - { "attach-acks", "Attach Accept count " }, - { "attach-cpls", "Attach Completed count " }, - { "ra-upd-reqs", "RoutingArea Update Request count" }, - { "ra-upd-rejs", "RoutingArea Update Reject count " }, - { "ra-upd-acks", "RoutingArea Update Accept count " }, - { "ra-upd-cpls", "RoutingArea Update Compltd count" }, - { "gmm-status", "GMM Status count (BSS)" }, - { "gmm-status", "GMM Status count (SGSN)" }, - { "detach-reqs", "Detach Request count " }, - { "detach-acks", "Detach Accept count " }, - { "pdp-act-reqs", "PDP Activation Request count " }, - { "pdp-act-rejs", "PDP Activation Reject count " }, - { "pdp-act-acks", "PDP Activation Accept count " }, - { "pdp-deact-reqs","PDP Deactivation Request count " }, - { "pdp-deact-acks","PDP Deactivation Accept count " }, - { "tlli-unknown", "TLLI from SGSN unknown " }, - { "tlli-cache", "TLLI cache size " }, }; -osmo_static_assert(ARRAY_SIZE(peer_ctr_description) == GBPROX_PEER_CTR_LAST, everything_described); +osmo_static_assert(ARRAY_SIZE(bvc_ctr_description) == GBPROX_PEER_CTR_LAST, everything_described); -static const struct rate_ctr_group_desc peer_ctrg_desc = { +static const struct rate_ctr_group_desc bvc_ctrg_desc = { .group_name_prefix = "gbproxy:peer", .group_description = "GBProxy Peer Statistics", - .num_ctr = ARRAY_SIZE(peer_ctr_description), - .ctr_desc = peer_ctr_description, + .num_ctr = ARRAY_SIZE(bvc_ctr_description), + .ctr_desc = bvc_ctr_description, .class_id = OSMO_STATS_CLASS_PEER, }; -/* Find the gbprox_peer by its BVCI */ -struct gbproxy_peer *gbproxy_peer_by_bvci(struct gbproxy_config *cfg, uint16_t bvci) +/* Find the gbproxy_bvc by its BVCI. There can only be one match */ +struct gbproxy_bvc *gbproxy_bvc_by_bvci(struct gbproxy_nse *nse, uint16_t bvci) { - struct gbproxy_peer *peer; - llist_for_each_entry(peer, &cfg->bts_peers, list) { - if (peer->bvci == bvci) - return peer; + struct gbproxy_bvc *bvc; + hash_for_each_possible(nse->bvcs, bvc, list, bvci) { + if (bvc->bvci == bvci) + return bvc; } 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_bvc *gbproxy_bvc_alloc(struct gbproxy_nse *nse, uint16_t bvci) { - struct gbproxy_peer *peer; - llist_for_each_entry(peer, &cfg->bts_peers, list) { - if (peer->nsei == nsei) - return peer; + struct gbproxy_bvc *bvc; + OSMO_ASSERT(nse); + struct gbproxy_config *cfg = nse->cfg; + OSMO_ASSERT(cfg); + + bvc = talloc_zero(tall_sgsn_ctx, struct gbproxy_bvc); + if (!bvc) + return NULL; + + bvc->bvci = bvci; + bvc->ctrg = rate_ctr_group_alloc(bvc, &bvc_ctrg_desc, (nse->nsei << 16) | bvci); + if (!bvc->ctrg) { + talloc_free(bvc); + return NULL; } - return NULL; + bvc->nse = nse; + + hash_add(nse->bvcs, &bvc->list, bvc->bvci); + + LOGPBVC_CAT(bvc, DOBJ, LOGL_INFO, "BVC Created\n"); + + /* We leave allocating the bvc->fi to the caller, as the FSM details depend + * on the type of BVC (SIG/PTP) and role (SGSN/BSS) */ + + return bvc; } -/* 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) +void gbproxy_bvc_free(struct gbproxy_bvc *bvc) { - struct gbproxy_peer *peer; - llist_for_each_entry(peer, &cfg->bts_peers, list) { - if (!memcmp(peer->ra, ra, 6)) - return peer; + struct gbproxy_cell *cell; + + if (!bvc) + return; + + LOGPBVC_CAT(bvc, DOBJ, LOGL_INFO, "BVC Destroying\n"); + + hash_del(&bvc->list); + + rate_ctr_group_free(bvc->ctrg); + bvc->ctrg = NULL; + + osmo_fsm_inst_free(bvc->fi); + + cell = bvc->cell; + if (cell) { + int i; + + if (cell->bss_bvc == bvc) + cell->bss_bvc = NULL; + + /* we could also be a SGSN-side BVC */ + for (i = 0; i < ARRAY_SIZE(cell->sgsn_bvc); i++) { + if (cell->sgsn_bvc[i] == bvc) + cell->sgsn_bvc[i] = NULL; + } + bvc->cell = NULL; } - return NULL; + + talloc_free(bvc); +} + +/*! remove BVCs on NSE specified by NSEI. + * \param[in] cfg proxy in which we operate + * \param[in] nsei NS entity in which we should clean up + * \param[in] bvci if 0: remove all PTP BVCs; if != 0: BVCI of the single BVC to clean up */ +int gbproxy_cleanup_bvcs(struct gbproxy_nse *nse, uint16_t bvci) +{ + struct hlist_node *btmp; + struct gbproxy_bvc *bvc; + int j, counter = 0; + + if (!nse) + return 0; + + hash_for_each_safe(nse->bvcs, j, btmp, bvc, list) { + if (bvci && bvc->bvci != bvci) + continue; + if (bvci == 0 && bvc->bvci == 0) + continue; + + gbproxy_bvc_free(bvc); + counter += 1; + } + + return counter; +} + + +/*********************************************************************** + * CELL + ***********************************************************************/ + +/* Allocate a new 'cell' object */ +struct gbproxy_cell *gbproxy_cell_alloc(struct gbproxy_config *cfg, uint16_t bvci) +{ + struct gbproxy_cell *cell; + OSMO_ASSERT(cfg); + + cell = talloc_zero(cfg, struct gbproxy_cell); + if (!cell) + return NULL; + + cell->cfg = cfg; + cell->bvci = bvci; + + hash_add(cfg->cells, &cell->list, cell->bvci); + + LOGPCELL_CAT(cell, DOBJ, LOGL_INFO, "CELL Created\n"); + + return cell; } -/* 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) +/* Find cell by BVCI */ +struct gbproxy_cell *gbproxy_cell_by_bvci(struct gbproxy_config *cfg, uint16_t bvci) { - struct gbproxy_peer *peer; - llist_for_each_entry(peer, &cfg->bts_peers, list) { - if (!memcmp(peer->ra, la, 5)) - return peer; + struct gbproxy_cell *cell; + + hash_for_each_possible(cfg->cells, cell, list, bvci) { + if (cell->bvci == bvci) + return cell; } 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_cell *gbproxy_cell_by_bvci_or_new(struct gbproxy_config *cfg, uint16_t bvci) +{ + struct gbproxy_cell *cell; + OSMO_ASSERT(cfg); + + cell = gbproxy_cell_by_bvci(cfg, bvci); + if (!cell) + cell = gbproxy_cell_alloc(cfg, bvci); + + return cell; +} + +void gbproxy_cell_free(struct gbproxy_cell *cell) { - struct gbproxy_peer *peer; - llist_for_each_entry(peer, &cfg->bts_peers, list) { - if (!memcmp(peer->ra + 3, la + 3, 2)) - return peer; + unsigned int i; + + if (!cell) + return; + + LOGPCELL_CAT(cell, DOBJ, LOGL_INFO, "CELL Destroying\n"); + + /* remove from cfg.cells */ + hash_del(&cell->list); + + /* remove back-pointers from the BSS side */ + if (cell->bss_bvc && cell->bss_bvc->cell) + cell->bss_bvc->cell = NULL; + + /* remove back-pointers from the SGSN side */ + for (i = 0; i < ARRAY_SIZE(cell->sgsn_bvc); i++) { + if (!cell->sgsn_bvc[i]) + continue; + if (cell->sgsn_bvc[i]->cell) + cell->sgsn_bvc[i]->cell = NULL; + } + + talloc_free(cell); +} + +bool gbproxy_cell_add_sgsn_bvc(struct gbproxy_cell *cell, struct gbproxy_bvc *bvc) +{ + unsigned int i; + for (i = 0; i < ARRAY_SIZE(cell->sgsn_bvc); i++) { + if (!cell->sgsn_bvc[i]) { + cell->sgsn_bvc[i] = bvc; + LOGPCELL_CAT(cell, DOBJ, LOGL_DEBUG, "CELL linked to SGSN\n"); + LOGPBVC_CAT(bvc, DOBJ, LOGL_DEBUG, "BVC linked to CELL\n"); + return true; + } + } + return false; +} + + +/*********************************************************************** + * TLLI cache + ***********************************************************************/ + +static inline struct gbproxy_tlli_cache_entry *_get_tlli_entry(struct gbproxy_config *cfg, uint32_t tlli) +{ + struct gbproxy_tlli_cache_entry *cache_entry; + + hash_for_each_possible(cfg->tlli_cache.entries, cache_entry, list, tlli) { + if (cache_entry->tlli == tlli) + return cache_entry; } return NULL; } -struct gbproxy_peer *gbproxy_peer_by_bssgp_tlv(struct gbproxy_config *cfg, - struct tlv_parsed *tp) +void gbproxy_tlli_cache_update(struct gbproxy_nse *nse, uint32_t tlli) { - if (TLVP_PRESENT(tp, BSSGP_IE_BVCI)) { - uint16_t bvci; + struct gbproxy_config *cfg = nse->cfg; + struct timespec now; + struct gbproxy_tlli_cache_entry *cache_entry = _get_tlli_entry(cfg, tlli); - bvci = ntohs(tlvp_val16_unal(tp, BSSGP_IE_BVCI)); - if (bvci >= 2) - return gbproxy_peer_by_bvci(cfg, bvci); + osmo_clock_gettime(CLOCK_MONOTONIC, &now); + + if (cache_entry) { + /* Update the entry if it already exists */ + cache_entry->nse = nse; + cache_entry->tstamp = now.tv_sec; + return; + } + + cache_entry = talloc_zero(cfg, struct gbproxy_tlli_cache_entry); + cache_entry->tlli = tlli; + cache_entry->nse = nse; + cache_entry->tstamp = now.tv_sec; + hash_add(cfg->tlli_cache.entries, &cache_entry->list, cache_entry->tlli); +} + +static void _tlli_cache_remove_nse(struct gbproxy_nse *nse) { + uint i; + struct gbproxy_config *cfg = nse->cfg; + struct gbproxy_tlli_cache_entry *tlli_cache; + struct hlist_node *tmp; + + hash_for_each_safe(cfg->tlli_cache.entries, i, tmp, tlli_cache, list) { + if (tlli_cache->nse == nse) { + hash_del(&tlli_cache->list); + talloc_free(tlli_cache); + } } +} - 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); +void gbproxy_tlli_cache_remove(struct gbproxy_config *cfg, uint32_t tlli) +{ + struct gbproxy_tlli_cache_entry *tlli_cache; + struct hlist_node *tmp; + + hash_for_each_possible_safe(cfg->tlli_cache.entries, tlli_cache, tmp, list, tlli) { + if (tlli_cache->tlli == tlli) { + hash_del(&tlli_cache->list); + talloc_free(tlli_cache); + return; + } } +} - 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); +int gbproxy_tlli_cache_cleanup(struct gbproxy_config *cfg) +{ + int i, count = 0; + struct gbproxy_tlli_cache_entry *tlli_cache; + struct hlist_node *tmp; + struct timespec now; + time_t expiry; + + osmo_clock_gettime(CLOCK_MONOTONIC, &now); + expiry = now.tv_sec - cfg->tlli_cache.timeout; + + hash_for_each_safe(cfg->tlli_cache.entries, i, tmp, tlli_cache, list) { + if (tlli_cache->tstamp < expiry) { + count++; + LOGP(DGPRS, LOGL_NOTICE, "Cache entry for TLLI %08x expired, removing\n", tlli_cache->tlli); + hash_del(&tlli_cache->list); + talloc_free(tlli_cache); + } } + return count; + +} +/*********************************************************************** + * IMSI cache + ***********************************************************************/ +static inline uint16_t _checksum_imsi(const char *imsi) +{ + size_t len = strlen(imsi); + return osmo_crc16(0, (const uint8_t *)imsi, len); +} + +static inline struct gbproxy_imsi_cache_entry *_get_imsi_entry(struct gbproxy_config *cfg, const char *imsi) +{ + struct gbproxy_imsi_cache_entry *cache_entry; + uint16_t imsi_hash = _checksum_imsi(imsi); + hash_for_each_possible(cfg->imsi_cache.entries, cache_entry, list, imsi_hash) { + if (!strncmp(cache_entry->imsi, imsi, sizeof(cache_entry->imsi))) + return cache_entry; + } return NULL; } -static void clean_stale_timer_cb(void *data) +void gbproxy_imsi_cache_update(struct gbproxy_nse *nse, const char *imsi) +{ + struct gbproxy_config *cfg = nse->cfg; + struct timespec now; + struct gbproxy_imsi_cache_entry *cache_entry = _get_imsi_entry(cfg, imsi); + uint16_t imsi_hash = _checksum_imsi(imsi); + + osmo_clock_gettime(CLOCK_MONOTONIC, &now); + + if (cache_entry) { + /* Update the entry if it already exists */ + cache_entry->nse = nse; + cache_entry->tstamp = now.tv_sec; + return; + } + + cache_entry = talloc_zero(cfg, struct gbproxy_imsi_cache_entry); + OSMO_STRLCPY_ARRAY(cache_entry->imsi, imsi); + cache_entry->nse = nse; + cache_entry->tstamp = now.tv_sec; + hash_add(cfg->imsi_cache.entries, &cache_entry->list, imsi_hash); +} + +static void _imsi_cache_remove_nse(struct gbproxy_nse *nse) { + uint i; + struct gbproxy_config *cfg = nse->cfg; + struct gbproxy_imsi_cache_entry *imsi_cache; + struct hlist_node *tmp; + + hash_for_each_safe(cfg->imsi_cache.entries, i, tmp, imsi_cache, list) { + if (imsi_cache->nse == nse) { + hash_del(&imsi_cache->list); + talloc_free(imsi_cache); + } + } +} + +void gbproxy_imsi_cache_remove(struct gbproxy_config *cfg, const char *imsi) { - time_t now; - struct timespec ts = {0,}; - struct gbproxy_peer *peer = (struct gbproxy_peer *) data; + struct gbproxy_imsi_cache_entry *imsi_cache; + struct hlist_node *tmp; + uint16_t imsi_hash = _checksum_imsi(imsi); + + hash_for_each_possible_safe(cfg->imsi_cache.entries, imsi_cache, tmp, list, imsi_hash) { + if (!(strncmp(imsi_cache->imsi, imsi, sizeof(imsi_cache->imsi)))) { + hash_del(&imsi_cache->list); + talloc_free(imsi_cache); + return; + } + } +} - osmo_clock_gettime(CLOCK_MONOTONIC, &ts); - now = ts.tv_sec; - gbproxy_remove_stale_link_infos(peer, now); - if (peer->cfg->clean_stale_timer_freq != 0) - osmo_timer_schedule(&peer->clean_stale_timer, - peer->cfg->clean_stale_timer_freq, 0); +int gbproxy_imsi_cache_cleanup(struct gbproxy_config *cfg) +{ + int i, count = 0; + struct gbproxy_imsi_cache_entry *imsi_cache; + struct hlist_node *tmp; + struct timespec now; + time_t expiry; + + osmo_clock_gettime(CLOCK_MONOTONIC, &now); + expiry = now.tv_sec - cfg->imsi_cache.timeout; + + hash_for_each_safe(cfg->imsi_cache.entries, i, tmp, imsi_cache, list) { + if (imsi_cache->tstamp < expiry) { + count++; + LOGP(DGPRS, LOGL_NOTICE, "Cache entry for IMSI %s expired, removing\n", imsi_cache->imsi); + hash_del(&imsi_cache->list); + talloc_free(imsi_cache); + } + } + return count; } -struct gbproxy_peer *gbproxy_peer_alloc(struct gbproxy_config *cfg, uint16_t bvci) +/*********************************************************************** + * NSE - NS Entity + ***********************************************************************/ + +struct gbproxy_nse *gbproxy_nse_alloc(struct gbproxy_config *cfg, uint16_t nsei, bool sgsn_facing) { - struct gbproxy_peer *peer; + struct gbproxy_nse *nse; + OSMO_ASSERT(cfg); - peer = talloc_zero(tall_sgsn_ctx, struct gbproxy_peer); - if (!peer) + nse = talloc_zero(tall_sgsn_ctx, struct gbproxy_nse); + if (!nse) return NULL; - peer->bvci = bvci; - peer->ctrg = rate_ctr_group_alloc(peer, &peer_ctrg_desc, bvci); - if (!peer->ctrg) { - talloc_free(peer); + nse->nsei = nsei; + nse->cfg = cfg; + nse->sgsn_facing = sgsn_facing; + + if (sgsn_facing) + hash_add(cfg->sgsn_nses, &nse->list, nsei); + else + hash_add(cfg->bss_nses, &nse->list, nsei); + + hash_init(nse->bvcs); + + LOGPNSE_CAT(nse, DOBJ, LOGL_INFO, "NSE Created\n"); + + return nse; +} + +static void _nse_free(struct gbproxy_nse *nse) +{ + struct gbproxy_bvc *bvc; + struct hlist_node *tmp; + int i; + + if (!nse) + return; + + LOGPNSE_CAT(nse, DOBJ, LOGL_INFO, "NSE Destroying\n"); + + hash_del(&nse->list); + /* Clear the cache entries of this NSE */ + _tlli_cache_remove_nse(nse); + _imsi_cache_remove_nse(nse); + + hash_for_each_safe(nse->bvcs, i, tmp, bvc, list) + gbproxy_bvc_free(bvc); + + talloc_free(nse); +} +static void _sgsn_free(struct gbproxy_sgsn *sgsn); + +void gbproxy_nse_free(struct gbproxy_nse *nse) +{ + if (!nse) + return; + OSMO_ASSERT(nse->cfg); + + if (nse->sgsn_facing) { + struct gbproxy_sgsn *sgsn = gbproxy_sgsn_by_nsei(nse->cfg, nse->nsei); + OSMO_ASSERT(sgsn); + _sgsn_free(sgsn); + } + + _nse_free(nse); +} + +struct gbproxy_nse *gbproxy_nse_by_nsei(struct gbproxy_config *cfg, uint16_t nsei, uint32_t flags) +{ + struct gbproxy_nse *nse; + OSMO_ASSERT(cfg); + + if (flags & NSE_F_SGSN) { + hash_for_each_possible(cfg->sgsn_nses, nse, list, nsei) { + if (nse->nsei == nsei) + return nse; + } + } + + if (flags & NSE_F_BSS) { + hash_for_each_possible(cfg->bss_nses, nse, list, nsei) { + if (nse->nsei == nsei) + return nse; + } + } + + return NULL; +} + +struct gbproxy_nse *gbproxy_nse_by_nsei_or_new(struct gbproxy_config *cfg, uint16_t nsei, bool sgsn_facing) +{ + struct gbproxy_nse *nse; + OSMO_ASSERT(cfg); + + nse = gbproxy_nse_by_nsei(cfg, nsei, sgsn_facing ? NSE_F_SGSN : NSE_F_BSS); + if (!nse) + nse = gbproxy_nse_alloc(cfg, nsei, sgsn_facing); + + return nse; +} + +struct gbproxy_nse *gbproxy_nse_by_tlli(struct gbproxy_config *cfg, uint32_t tlli) +{ + struct gbproxy_tlli_cache_entry *tlli_cache; + + hash_for_each_possible(cfg->tlli_cache.entries, tlli_cache, list, tlli) { + if (tlli_cache->tlli == tlli) + return tlli_cache->nse; + } + return NULL; +} + +struct gbproxy_nse *gbproxy_nse_by_imsi(struct gbproxy_config *cfg, const char *imsi) +{ + struct gbproxy_imsi_cache_entry *imsi_cache; + uint16_t imsi_hash = _checksum_imsi(imsi); + + hash_for_each_possible(cfg->imsi_cache.entries, imsi_cache, list, imsi_hash) { + if (!strncmp(imsi_cache->imsi, imsi, sizeof(imsi_cache->imsi))) + return imsi_cache->nse; + } + return NULL; +} + +/*********************************************************************** + * SGSN - Serving GPRS Support Node + ***********************************************************************/ + +/*! Allocate a new SGSN. This ensures the corresponding gbproxy_nse is allocated as well + * \param[in] cfg The gbproxy configuration + * \param[in] nsei The nsei where the SGSN can be reached + * \param[in] name A name to give the SGSN + * \return The SGSN, NULL if it couldn't be allocated + */ +struct gbproxy_sgsn *gbproxy_sgsn_alloc(struct gbproxy_config *cfg, uint16_t nsei, const char *name) +{ + struct gbproxy_sgsn *sgsn; + OSMO_ASSERT(cfg); + + sgsn = talloc_zero(tall_sgsn_ctx, struct gbproxy_sgsn); + if (!sgsn) return NULL; + + sgsn->nse = gbproxy_nse_alloc(cfg, nsei, true); + if (!sgsn->nse) { + LOGP(DOBJ, LOGL_ERROR, "Could not allocate NSE(%05u) for SGSN(%s)\n", + nsei, sgsn->name); + goto free_sgsn; } - peer->cfg = cfg; - llist_add(&peer->list, &cfg->bts_peers); + if (name) + sgsn->name = talloc_strdup(sgsn, name); + else + sgsn->name = talloc_asprintf(sgsn, "NSE(%05u)", sgsn->nse->nsei); + if (!sgsn->name) + goto free_sgsn; - INIT_LLIST_HEAD(&peer->patch_state.logical_links); + sgsn->pool.allow_attach = true; + sgsn->pool.nri_ranges = osmo_nri_ranges_alloc(sgsn); - osmo_timer_setup(&peer->clean_stale_timer, clean_stale_timer_cb, peer); - if (peer->cfg->clean_stale_timer_freq != 0) - osmo_timer_schedule(&peer->clean_stale_timer, - peer->cfg->clean_stale_timer_freq, 0); + llist_add_tail(&sgsn->list, &cfg->sgsns); + LOGPSGSN_CAT(sgsn, DOBJ, LOGL_INFO, "SGSN Created\n"); + return sgsn; - return peer; +free_sgsn: + talloc_free(sgsn); + return NULL; +} + +/* Only free gbproxy_sgsn, sgsn can't be NULL */ +static void _sgsn_free(struct gbproxy_sgsn *sgsn) { + struct gbproxy_config *cfg; + + OSMO_ASSERT(sgsn->nse); + cfg = sgsn->nse->cfg; + OSMO_ASSERT(cfg); + + LOGPSGSN_CAT(sgsn, DOBJ, LOGL_INFO, "SGSN Destroying\n"); + llist_del(&sgsn->list); + /* talloc will free ->name and ->pool.nri_ranges */ + talloc_free(sgsn); } -void gbproxy_peer_free(struct gbproxy_peer *peer) +/*! Free the SGSN. This ensures the corresponding gbproxy_nse is freed as well + * \param[in] sgsn The SGSN + */ +void gbproxy_sgsn_free(struct gbproxy_sgsn *sgsn) { - llist_del(&peer->list); - osmo_timer_del(&peer->clean_stale_timer); - gbproxy_delete_link_infos(peer); + if (!sgsn) + return; - rate_ctr_group_free(peer->ctrg); - peer->ctrg = NULL; + OSMO_ASSERT(sgsn->nse) - talloc_free(peer); + _nse_free(sgsn->nse); + _sgsn_free(sgsn); } -int gbproxy_cleanup_peers(struct gbproxy_config *cfg, uint16_t nsei, uint16_t bvci) +/*! Return the SGSN for a given NSEI + * \param[in] cfg The gbproxy configuration + * \param[in] nsei The nsei where the SGSN can be reached + * \return Returns the matching SGSN or NULL if it couldn't be found + */ +struct gbproxy_sgsn *gbproxy_sgsn_by_name(struct gbproxy_config *cfg, const char *name) { - int counter = 0; - struct gbproxy_peer *peer, *tmp; + struct gbproxy_sgsn *sgsn; + OSMO_ASSERT(cfg); - llist_for_each_entry_safe(peer, tmp, &cfg->bts_peers, list) { - if (peer->nsei != nsei) - continue; - if (bvci && peer->bvci != bvci) - continue; + llist_for_each_entry(sgsn, &cfg->sgsns, list) { + if (!strcmp(sgsn->name, name)) + return sgsn; + } - gbproxy_peer_free(peer); - counter += 1; + return NULL; +} + +/*! Return the SGSN for a given NSEI + * \param[in] cfg The gbproxy configuration + * \param[in] nsei The nsei where the SGSN can be reached + * \return Returns the matching SGSN or NULL if it couldn't be found + */ +struct gbproxy_sgsn *gbproxy_sgsn_by_nsei(struct gbproxy_config *cfg, uint16_t nsei) +{ + struct gbproxy_sgsn *sgsn; + OSMO_ASSERT(cfg); + + llist_for_each_entry(sgsn, &cfg->sgsns, list) { + if (sgsn->nse->nsei == nsei) + return sgsn; } - return counter; + return NULL; +} + +/*! Return the SGSN for a given NSEI, creating a new one if none exists + * \param[in] cfg The gbproxy configuration + * \param[in] nsei The nsei where the SGSN can be reached + * \return Returns the SGSN + */ +struct gbproxy_sgsn *gbproxy_sgsn_by_nsei_or_new(struct gbproxy_config *cfg, uint16_t nsei) +{ + struct gbproxy_sgsn *sgsn; + OSMO_ASSERT(cfg); + + sgsn = gbproxy_sgsn_by_nsei(cfg, nsei); + if (!sgsn) + sgsn = gbproxy_sgsn_alloc(cfg, nsei, NULL); + + return sgsn; +} + +/*! Return the gbproxy_sgsn matching that NRI + * \param[in] cfg proxy in which we operate + * \param[in] nri NRI to look for + * \param[out] null_nri If not NULL this indicates whether the NRI is a null NRI + * \return The SGSN this NRI has been added to, NULL if no matching SGSN could be found + */ +struct gbproxy_sgsn *gbproxy_sgsn_by_nri(struct gbproxy_config *cfg, uint16_t nri, bool *null_nri) +{ + struct gbproxy_sgsn *sgsn; + OSMO_ASSERT(cfg); + + llist_for_each_entry(sgsn, &cfg->sgsns, list) { + if (osmo_nri_v_matches_ranges(nri, sgsn->pool.nri_ranges)) { + /* Also check if the NRI we're looking for is a NULL NRI */ + if (null_nri) { + if (osmo_nri_v_matches_ranges(nri, cfg->pool.null_nri_ranges)) + *null_nri = true; + else + *null_nri = false; + } + return sgsn; + } + } + + return NULL; +} + +/*! Seleect a pseudo-random SGSN for a given TLLI, ignoring any SGSN that is not accepting connections + * \param[in] cfg The gbproxy configuration + * \param[in] sgsn_avoid If not NULL then avoid this SGSN when selecting a new one. Use for load redistribution + * \param[in] tlli The tlli to choose an SGSN for. The same tlli will map to the same SGSN as long as no SGSN is + * added/removed or allow_attach changes. + * \return Returns the sgsn on success, NULL if no SGSN that allows new connections could be found + */ +struct gbproxy_sgsn *gbproxy_sgsn_by_tlli(struct gbproxy_config *cfg, struct gbproxy_sgsn *sgsn_avoid, + uint32_t tlli) +{ + uint32_t i = 0; + uint32_t index, num_sgsns; + OSMO_ASSERT(cfg); + + struct gbproxy_sgsn *sgsn = cfg->pool.nsf_override; + + if (sgsn) { + LOGPSGSN(sgsn, LOGL_DEBUG, "Node selection function is overridden by config\n"); + return sgsn; + } + + /* TODO: We should keep track of count in cfg */ + num_sgsns = llist_count(&cfg->sgsns); + + if (num_sgsns == 0) + return NULL; + + /* FIXME: 256 SGSNs ought to be enough for everyone */ + index = hash_32(tlli, 8) % num_sgsns; + + /* Get the first enabled SGSN after index */ + llist_for_each_entry(sgsn, &cfg->sgsns, list) { + if (i >= index && sgsn->pool.allow_attach) { + return sgsn; + } + i++; + } + /* Start again from the beginning */ + i = 0; + llist_for_each_entry(sgsn, &cfg->sgsns, list) { + if (i >= index) { + break; + } else if (sgsn->pool.allow_attach) { + return sgsn; + } + i++; + } + + return NULL; } diff --git a/src/gbproxy/gb_proxy_tlli.c b/src/gbproxy/gb_proxy_tlli.c deleted file mode 100644 index e9271c22..00000000 --- a/src/gbproxy/gb_proxy_tlli.c +++ /dev/null @@ -1,725 +0,0 @@ -/* 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 <osmocom/gsm/gsm48.h> - -#include <osmocom/sgsn/gb_proxy.h> - -#include <osmocom/sgsn/gprs_utils.h> -#include <osmocom/sgsn/gprs_gb_parse.h> - -#include <osmocom/sgsn/debug.h> - -#include <osmocom/gsm/gsm_utils.h> - -#include <osmocom/core/rate_ctr.h> -#include <osmocom/core/talloc.h> - -struct gbproxy_link_info *gbproxy_link_info_by_tlli(struct gbproxy_peer *peer, - uint32_t tlli) -{ - struct gbproxy_link_info *link_info; - struct gbproxy_patch_state *state = &peer->patch_state; - - if (!tlli) - return NULL; - - llist_for_each_entry(link_info, &state->logical_links, list) - if (link_info->tlli.current == tlli || - link_info->tlli.assigned == tlli) - return link_info; - - return NULL; -} - -struct gbproxy_link_info *gbproxy_link_info_by_ptmsi( - struct gbproxy_peer *peer, - uint32_t ptmsi) -{ - struct gbproxy_link_info *link_info; - struct gbproxy_patch_state *state = &peer->patch_state; - - if (ptmsi == GSM_RESERVED_TMSI) - return NULL; - - llist_for_each_entry(link_info, &state->logical_links, list) - if (link_info->tlli.ptmsi == ptmsi) - return link_info; - - return NULL; -} - -struct gbproxy_link_info *gbproxy_link_info_by_any_sgsn_tlli( - struct gbproxy_peer *peer, - uint32_t tlli) -{ - struct gbproxy_link_info *link_info; - struct gbproxy_patch_state *state = &peer->patch_state; - - if (!tlli) - return NULL; - - /* Don't care about the NSEI */ - llist_for_each_entry(link_info, &state->logical_links, list) - if (link_info->sgsn_tlli.current == tlli || - link_info->sgsn_tlli.assigned == tlli) - return link_info; - - return NULL; -} - -struct gbproxy_link_info *gbproxy_link_info_by_sgsn_tlli( - struct gbproxy_peer *peer, - uint32_t tlli, uint32_t sgsn_nsei) -{ - struct gbproxy_link_info *link_info; - struct gbproxy_patch_state *state = &peer->patch_state; - - if (!tlli) - return NULL; - - llist_for_each_entry(link_info, &state->logical_links, list) - if ((link_info->sgsn_tlli.current == tlli || - link_info->sgsn_tlli.assigned == tlli) && - link_info->sgsn_nsei == sgsn_nsei) - return link_info; - - return NULL; -} - -struct gbproxy_link_info *gbproxy_link_info_by_imsi( - struct gbproxy_peer *peer, - const uint8_t *imsi, - size_t imsi_len) -{ - struct gbproxy_link_info *link_info; - struct gbproxy_patch_state *state = &peer->patch_state; - - if (!gprs_is_mi_imsi(imsi, imsi_len)) - return NULL; - - llist_for_each_entry(link_info, &state->logical_links, list) { - if (link_info->imsi_len != imsi_len) - continue; - if (memcmp(link_info->imsi, imsi, imsi_len) != 0) - continue; - - return link_info; - } - - return NULL; -} - -void gbproxy_link_info_discard_messages(struct gbproxy_link_info *link_info) -{ - struct msgb *msg, *nxt; - - llist_for_each_entry_safe(msg, nxt, &link_info->stored_msgs, list) { - llist_del(&msg->list); - msgb_free(msg); - } -} - -void gbproxy_delete_link_info(struct gbproxy_peer *peer, - struct gbproxy_link_info *link_info) -{ - struct gbproxy_patch_state *state = &peer->patch_state; - - gbproxy_link_info_discard_messages(link_info); - - llist_del(&link_info->list); - talloc_free(link_info); - state->logical_link_count -= 1; - - peer->ctrg->ctr[GBPROX_PEER_CTR_TLLI_CACHE_SIZE].current = - state->logical_link_count; -} - -void gbproxy_delete_link_infos(struct gbproxy_peer *peer) -{ - struct gbproxy_link_info *link_info, *nxt; - struct gbproxy_patch_state *state = &peer->patch_state; - - llist_for_each_entry_safe(link_info, nxt, &state->logical_links, list) - gbproxy_delete_link_info(peer, link_info); - - OSMO_ASSERT(state->logical_link_count == 0); - OSMO_ASSERT(llist_empty(&state->logical_links)); -} - -void gbproxy_attach_link_info(struct gbproxy_peer *peer, time_t now, - struct gbproxy_link_info *link_info) -{ - struct gbproxy_patch_state *state = &peer->patch_state; - - link_info->timestamp = now; - llist_add(&link_info->list, &state->logical_links); - state->logical_link_count += 1; - - peer->ctrg->ctr[GBPROX_PEER_CTR_TLLI_CACHE_SIZE].current = - state->logical_link_count; -} - -int gbproxy_remove_stale_link_infos(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->logical_link_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_link_info *link_info; - OSMO_ASSERT(!llist_empty(&state->logical_links)); - link_info = llist_entry(state->logical_links.prev, - struct gbproxy_link_info, - list); - LOGP(DGPRS, LOGL_INFO, - "Removing TLLI %08x from list " - "(stale, length %d, max_len exceeded)\n", - link_info->tlli.current, state->logical_link_count); - - gbproxy_delete_link_info(peer, link_info); - deleted_count += 1; - } - - while (check_for_age && !llist_empty(&state->logical_links)) { - time_t age; - struct gbproxy_link_info *link_info; - link_info = llist_entry(state->logical_links.prev, - struct gbproxy_link_info, - list); - age = now - link_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", - link_info->tlli.current, (int)age); - - gbproxy_delete_link_info(peer, link_info); - deleted_count += 1; - } - - return deleted_count; -} - -struct gbproxy_link_info *gbproxy_link_info_alloc( struct gbproxy_peer *peer) -{ - struct gbproxy_link_info *link_info; - - link_info = talloc_zero(peer, struct gbproxy_link_info); - link_info->tlli.ptmsi = GSM_RESERVED_TMSI; - link_info->sgsn_tlli.ptmsi = GSM_RESERVED_TMSI; - - link_info->vu_gen_tx_bss = GBPROXY_INIT_VU_GEN_TX; - - INIT_LLIST_HEAD(&link_info->stored_msgs); - - return link_info; -} - -void gbproxy_detach_link_info( - struct gbproxy_peer *peer, - struct gbproxy_link_info *link_info) -{ - struct gbproxy_patch_state *state = &peer->patch_state; - - llist_del(&link_info->list); - OSMO_ASSERT(state->logical_link_count > 0); - state->logical_link_count -= 1; - - peer->ctrg->ctr[GBPROX_PEER_CTR_TLLI_CACHE_SIZE].current = - state->logical_link_count; -} - -void gbproxy_update_link_info(struct gbproxy_link_info *link_info, - const uint8_t *imsi, size_t imsi_len) -{ - if (!gprs_is_mi_imsi(imsi, imsi_len)) - return; - - link_info->imsi_len = imsi_len; - link_info->imsi = - talloc_realloc_size(link_info, link_info->imsi, imsi_len); - OSMO_ASSERT(link_info->imsi != NULL); - memcpy(link_info->imsi, 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 = false; - tlli_state->net_validated = false; -} - -uint32_t gbproxy_map_tlli(uint32_t other_tlli, - struct gbproxy_link_info *link_info, int to_bss) -{ - uint32_t tlli = 0; - struct gbproxy_tlli_state *src, *dst; - if (to_bss) { - src = &link_info->sgsn_tlli; - dst = &link_info->tlli; - } else { - src = &link_info->tlli; - dst = &link_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 = true; - else - tlli_state->bss_validated = true; - - 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; -} - -static void gbproxy_touch_link_info(struct gbproxy_peer *peer, - struct gbproxy_link_info *link_info, - time_t now) -{ - gbproxy_detach_link_info(peer, link_info); - gbproxy_attach_link_info(peer, now, link_info); -} - -static int gbproxy_unregister_link_info(struct gbproxy_peer *peer, - struct gbproxy_link_info *link_info) -{ - if (!link_info) - return 1; - - if (link_info->tlli.ptmsi == GSM_RESERVED_TMSI && !link_info->imsi_len) { - LOGP(DGPRS, LOGL_INFO, - "Removing TLLI %08x from list (P-TMSI or IMSI are not set)\n", - link_info->tlli.current); - gbproxy_delete_link_info(peer, link_info); - return 1; - } - - link_info->tlli.current = 0; - link_info->tlli.assigned = 0; - link_info->sgsn_tlli.current = 0; - link_info->sgsn_tlli.assigned = 0; - - link_info->is_deregistered = true; - - gbproxy_reset_link(link_info); - - return 0; -} - -int gbproxy_imsi_matches(struct gbproxy_config *cfg, - enum gbproxy_match_id match_id, - struct gbproxy_link_info *link_info) -{ - struct gbproxy_match *match; - OSMO_ASSERT(match_id >= 0 && match_id < ARRAY_SIZE(cfg->matches)); - - match = &cfg->matches[match_id]; - if (!match->enable) - return 1; - - return link_info != NULL && link_info->is_matching[match_id]; -} - -static void gbproxy_assign_imsi(struct gbproxy_peer *peer, - struct gbproxy_link_info *link_info, - struct gprs_gb_parse_context *parse_ctx) -{ - int imsi_matches; - struct gbproxy_link_info *other_link_info; - enum gbproxy_match_id match_id; - - /* Make sure that there is a second entry with the same IMSI */ - other_link_info = gbproxy_link_info_by_imsi( - peer, parse_ctx->imsi, parse_ctx->imsi_len); - - if (other_link_info && other_link_info != link_info) { - struct osmo_mobile_identity mi; - if (osmo_mobile_identity_decode(&mi, parse_ctx->imsi, parse_ctx->imsi_len, false) - || mi.type != GSM_MI_TYPE_IMSI) { - LOGP(DGPRS, LOGL_ERROR, "Failed to decode Mobile Identity\n"); - } else { - LOGP(DGPRS, LOGL_INFO, - "Removing TLLI %08x from list (IMSI %s re-used)\n", - other_link_info->tlli.current, mi.imsi); - gbproxy_delete_link_info(peer, other_link_info); - } - } - - /* Update the IMSI field */ - gbproxy_update_link_info(link_info, - parse_ctx->imsi, parse_ctx->imsi_len); - - /* Check, whether the IMSI matches */ - OSMO_ASSERT(ARRAY_SIZE(link_info->is_matching) == - ARRAY_SIZE(peer->cfg->matches)); - for (match_id = 0; match_id < ARRAY_SIZE(link_info->is_matching); - ++match_id) { - imsi_matches = gbproxy_check_imsi( - &peer->cfg->matches[match_id], - parse_ctx->imsi, parse_ctx->imsi_len); - if (imsi_matches >= 0) - link_info->is_matching[match_id] = imsi_matches ? true : false; - } -} - -static int gbproxy_tlli_match(const struct gbproxy_tlli_state *a, - const struct gbproxy_tlli_state *b) -{ - if (a->current && a->current == b->current) - return 1; - - if (a->assigned && a->assigned == b->assigned) - return 1; - - if (a->ptmsi != GSM_RESERVED_TMSI && a->ptmsi == b->ptmsi) - return 1; - - return 0; -} - -static void gbproxy_remove_matching_link_infos( - struct gbproxy_peer *peer, struct gbproxy_link_info *link_info) -{ - struct gbproxy_link_info *info, *nxt; - struct gbproxy_patch_state *state = &peer->patch_state; - - /* Make sure that there is no second entry with the same P-TMSI or TLLI */ - llist_for_each_entry_safe(info, nxt, &state->logical_links, list) { - if (info == link_info) - continue; - - if (!gbproxy_tlli_match(&link_info->tlli, &info->tlli) && - (link_info->sgsn_nsei != info->sgsn_nsei || - !gbproxy_tlli_match(&link_info->sgsn_tlli, &info->sgsn_tlli))) - continue; - - LOGP(DGPRS, LOGL_INFO, - "Removing TLLI %08x from list (P-TMSI/TLLI re-used)\n", - info->tlli.current); - gbproxy_delete_link_info(peer, info); - } -} - -static struct gbproxy_link_info *gbproxy_get_link_info_ul( - struct gbproxy_peer *peer, - int *tlli_is_valid, - struct gprs_gb_parse_context *parse_ctx) -{ - struct gbproxy_link_info *link_info = NULL; - - if (parse_ctx->tlli_enc) { - link_info = gbproxy_link_info_by_tlli(peer, parse_ctx->tlli); - - if (link_info) { - *tlli_is_valid = 1; - return link_info; - } - } - - *tlli_is_valid = 0; - - if (!link_info && parse_ctx->imsi) { - link_info = gbproxy_link_info_by_imsi( - peer, parse_ctx->imsi, parse_ctx->imsi_len); - } - - if (!link_info && parse_ctx->ptmsi_enc && !parse_ctx->old_raid_is_foreign) { - uint32_t bss_ptmsi; - gprs_parse_tmsi(parse_ctx->ptmsi_enc, &bss_ptmsi); - link_info = gbproxy_link_info_by_ptmsi(peer, bss_ptmsi); - } - - if (!link_info) - return NULL; - - link_info->is_deregistered = false; - - return link_info; -} - -struct gbproxy_link_info *gbproxy_update_link_state_ul( - struct gbproxy_peer *peer, - time_t now, - struct gprs_gb_parse_context *parse_ctx) -{ - struct gbproxy_link_info *link_info; - int tlli_is_valid; - - link_info = gbproxy_get_link_info_ul(peer, &tlli_is_valid, parse_ctx); - - if (parse_ctx->tlli_enc && parse_ctx->llc) { - uint32_t sgsn_tlli; - - if (!link_info) { - LOGP(DGPRS, LOGL_INFO, "Adding TLLI %08x to list\n", - parse_ctx->tlli); - link_info = gbproxy_link_info_alloc(peer); - gbproxy_attach_link_info(peer, now, link_info); - - /* Setup TLLIs */ - sgsn_tlli = gbproxy_make_sgsn_tlli(peer, link_info, - parse_ctx->tlli); - link_info->sgsn_tlli.current = sgsn_tlli; - link_info->tlli.current = parse_ctx->tlli; - } else if (!tlli_is_valid) { - /* New TLLI (info found by IMSI or P-TMSI) */ - link_info->tlli.current = parse_ctx->tlli; - link_info->tlli.assigned = 0; - link_info->sgsn_tlli.current = - gbproxy_make_sgsn_tlli(peer, link_info, - parse_ctx->tlli); - link_info->sgsn_tlli.assigned = 0; - gbproxy_touch_link_info(peer, link_info, now); - } else { - sgsn_tlli = gbproxy_map_tlli(parse_ctx->tlli, link_info, 0); - if (!sgsn_tlli) - sgsn_tlli = gbproxy_make_sgsn_tlli(peer, link_info, - parse_ctx->tlli); - - gbproxy_validate_tlli(&link_info->tlli, - parse_ctx->tlli, 0); - gbproxy_validate_tlli(&link_info->sgsn_tlli, - sgsn_tlli, 0); - gbproxy_touch_link_info(peer, link_info, now); - } - } else if (link_info) { - gbproxy_touch_link_info(peer, link_info, now); - } - - if (parse_ctx->imsi && link_info && link_info->imsi_len == 0) - gbproxy_assign_imsi(peer, link_info, parse_ctx); - - return link_info; -} - -static struct gbproxy_link_info *gbproxy_get_link_info_dl( - struct gbproxy_peer *peer, - struct gprs_gb_parse_context *parse_ctx) -{ - struct gbproxy_link_info *link_info = NULL; - - /* Which key to use depends on its availability only, if that fails, do - * not retry it with another key (e.g. IMSI). */ - if (parse_ctx->tlli_enc) - link_info = gbproxy_link_info_by_sgsn_tlli(peer, parse_ctx->tlli, - parse_ctx->peer_nsei); - - /* TODO: Get link_info by (SGSN) P-TMSI if that is available (see - * GSM 08.18, 7.2) instead of using the IMSI as key. */ - else if (parse_ctx->imsi) - link_info = gbproxy_link_info_by_imsi( - peer, parse_ctx->imsi, parse_ctx->imsi_len); - - if (link_info) - link_info->is_deregistered = false; - - return link_info; -} - -struct gbproxy_link_info *gbproxy_update_link_state_dl( - struct gbproxy_peer *peer, - time_t now, - struct gprs_gb_parse_context *parse_ctx) -{ - struct gbproxy_link_info *link_info = NULL; - - link_info = gbproxy_get_link_info_dl(peer, parse_ctx); - - if (parse_ctx->tlli_enc && parse_ctx->new_ptmsi_enc && link_info) { - /* A new P-TMSI has been signalled in the message, - * register new TLLI */ - uint32_t new_sgsn_ptmsi; - uint32_t new_bss_ptmsi = GSM_RESERVED_TMSI; - gprs_parse_tmsi(parse_ctx->new_ptmsi_enc, &new_sgsn_ptmsi); - - if (link_info->sgsn_tlli.ptmsi == new_sgsn_ptmsi) - new_bss_ptmsi = link_info->tlli.ptmsi; - - if (new_bss_ptmsi == GSM_RESERVED_TMSI) - new_bss_ptmsi = gbproxy_make_bss_ptmsi(peer, new_sgsn_ptmsi); - - LOGP(DGPRS, LOGL_INFO, - "Got new PTMSI %08x from SGSN, using %08x for BSS\n", - new_sgsn_ptmsi, new_bss_ptmsi); - /* Setup PTMSIs */ - link_info->sgsn_tlli.ptmsi = new_sgsn_ptmsi; - link_info->tlli.ptmsi = new_bss_ptmsi; - } else if (parse_ctx->tlli_enc && parse_ctx->new_ptmsi_enc && !link_info && - !peer->cfg->patch_ptmsi) { - /* A new P-TMSI has been signalled in the message with an unknown - * TLLI, create a new link_info */ - /* TODO: Add a test case for this branch */ - uint32_t new_ptmsi; - gprs_parse_tmsi(parse_ctx->new_ptmsi_enc, &new_ptmsi); - - LOGP(DGPRS, LOGL_INFO, - "Adding TLLI %08x to list (SGSN, new P-TMSI is %08x)\n", - parse_ctx->tlli, new_ptmsi); - - link_info = gbproxy_link_info_alloc(peer); - link_info->sgsn_tlli.current = parse_ctx->tlli; - link_info->tlli.current = parse_ctx->tlli; - link_info->sgsn_tlli.ptmsi = new_ptmsi; - link_info->tlli.ptmsi = new_ptmsi; - gbproxy_attach_link_info(peer, now, link_info); - } else if (parse_ctx->tlli_enc && parse_ctx->llc && !link_info && - !peer->cfg->patch_ptmsi) { - /* Unknown SGSN TLLI, create a new link_info */ - uint32_t new_ptmsi; - link_info = gbproxy_link_info_alloc(peer); - LOGP(DGPRS, LOGL_INFO, "Adding TLLI %08x to list (SGSN)\n", - parse_ctx->tlli); - - gbproxy_attach_link_info(peer, now, link_info); - - /* Setup TLLIs */ - link_info->sgsn_tlli.current = parse_ctx->tlli; - link_info->tlli.current = parse_ctx->tlli; - - if (!parse_ctx->new_ptmsi_enc) - return link_info; - /* A new P-TMSI has been signalled in the message */ - - gprs_parse_tmsi(parse_ctx->new_ptmsi_enc, &new_ptmsi); - LOGP(DGPRS, LOGL_INFO, - "Assigning new P-TMSI %08x\n", new_ptmsi); - /* Setup P-TMSIs */ - link_info->sgsn_tlli.ptmsi = new_ptmsi; - link_info->tlli.ptmsi = new_ptmsi; - } else if (parse_ctx->tlli_enc && parse_ctx->llc && link_info) { - uint32_t bss_tlli = gbproxy_map_tlli(parse_ctx->tlli, - link_info, 1); - gbproxy_validate_tlli(&link_info->sgsn_tlli, parse_ctx->tlli, 1); - gbproxy_validate_tlli(&link_info->tlli, bss_tlli, 1); - gbproxy_touch_link_info(peer, link_info, now); - } else if (link_info) { - gbproxy_touch_link_info(peer, link_info, now); - } - - if (parse_ctx->imsi && link_info && link_info->imsi_len == 0) - gbproxy_assign_imsi(peer, link_info, parse_ctx); - - return link_info; -} - -int gbproxy_update_link_state_after( - struct gbproxy_peer *peer, - struct gbproxy_link_info *link_info, - time_t now, - struct gprs_gb_parse_context *parse_ctx) -{ - int rc = 0; - if (parse_ctx->invalidate_tlli && link_info) { - int keep_info = - peer->cfg->keep_link_infos == GBPROX_KEEP_ALWAYS || - (peer->cfg->keep_link_infos == GBPROX_KEEP_REATTACH && - parse_ctx->await_reattach) || - (peer->cfg->keep_link_infos == GBPROX_KEEP_IDENTIFIED && - link_info->imsi_len > 0); - if (keep_info) { - LOGP(DGPRS, LOGL_INFO, "Unregistering TLLI %08x\n", - link_info->tlli.current); - rc = gbproxy_unregister_link_info(peer, link_info); - } else { - LOGP(DGPRS, LOGL_INFO, "Removing TLLI %08x from list\n", - link_info->tlli.current); - gbproxy_delete_link_info(peer, link_info); - rc = 1; - } - } else if (parse_ctx->to_bss && parse_ctx->tlli_enc && - parse_ctx->new_ptmsi_enc && link_info) { - /* A new PTMSI has been signaled in the message, - * register new TLLI */ - uint32_t new_sgsn_ptmsi = link_info->sgsn_tlli.ptmsi; - uint32_t new_bss_ptmsi = link_info->tlli.ptmsi; - uint32_t new_sgsn_tlli; - uint32_t new_bss_tlli = 0; - - new_sgsn_tlli = gprs_tmsi2tlli(new_sgsn_ptmsi, TLLI_LOCAL); - if (new_bss_ptmsi != GSM_RESERVED_TMSI) - new_bss_tlli = gprs_tmsi2tlli(new_bss_ptmsi, TLLI_LOCAL); - LOGP(DGPRS, LOGL_INFO, - "Assigning new TLLI %08x to SGSN, %08x to BSS\n", - new_sgsn_tlli, new_bss_tlli); - - gbproxy_reassign_tlli(&link_info->sgsn_tlli, - peer, new_sgsn_tlli); - gbproxy_reassign_tlli(&link_info->tlli, - peer, new_bss_tlli); - gbproxy_remove_matching_link_infos(peer, link_info); - } - - gbproxy_remove_stale_link_infos(peer, now); - - return rc; -} - - diff --git a/src/gbproxy/gb_proxy_vty.c b/src/gbproxy/gb_proxy_vty.c index 355b23fb..7ae65d20 100644 --- a/src/gbproxy/gb_proxy_vty.c +++ b/src/gbproxy/gb_proxy_vty.c @@ -25,12 +25,18 @@ #include <time.h> #include <inttypes.h> +#include <osmocom/core/hashtable.h> #include <osmocom/core/talloc.h> +#include <osmocom/core/timer.h> #include <osmocom/core/rate_ctr.h> -#include <osmocom/gsm/gsm48.h> +#include <osmocom/core/utils.h> + +#include <osmocom/gprs/gprs_ns2.h> +#include <osmocom/gprs/bssgp_bvc_fsm.h> -#include <osmocom/gprs/gprs_ns.h> #include <osmocom/gsm/apn.h> +#include <osmocom/gsm/gsm23236.h> +#include <osmocom/gsm/gsm48.h> #include <osmocom/sgsn/debug.h> #include <osmocom/sgsn/gb_proxy.h> @@ -38,9 +44,23 @@ #include <osmocom/sgsn/vty.h> #include <osmocom/vty/command.h> +#include <osmocom/vty/logging.h> #include <osmocom/vty/vty.h> #include <osmocom/vty/misc.h> +#define GBPROXY_STR "Display information about the Gb proxy\n" +#define NRI_STR "Mapping of Network Resource Indicators to this SGSN, for SGSN pooling\n" +#define NULL_NRI_STR "Define NULL-NRI values that cause re-assignment of an MS to a different SGSN, for SGSN pooling.\n" +#define NRI_FIRST_LAST_STR "First value of the NRI value range, should not surpass the configured 'nri bitlen'.\n" \ + "Last value of the NRI value range, should not surpass the configured 'nri bitlen' and be larger than the" \ + " first value; if omitted, apply only the first value.\n" +#define NRI_ARGS_TO_STR_FMT "%s%s%s" +#define NRI_ARGS_TO_STR_ARGS(ARGC, ARGV) ARGV[0], (ARGC>1)? ".." : "", (ARGC>1)? ARGV[1] : "" +#define NRI_WARN(SGSN, FORMAT, args...) do { \ + vty_out(vty, "%% Warning: NSE(%05d/SGSN): " FORMAT "%s", (SGSN)->nse->nsei, ##args, VTY_NEWLINE); \ + LOGP(DLBSSGP, LOGL_ERROR, "NSE(%05d/SGSN): " FORMAT "\n", (SGSN)->nse->nsei, ##args); \ + } while (0) + static struct gbproxy_config *g_cfg = NULL; /* @@ -52,91 +72,77 @@ static struct cmd_node gbproxy_node = { 1, }; -static const struct value_string keep_modes[] = { - {GBPROX_KEEP_NEVER, "never"}, - {GBPROX_KEEP_REATTACH, "re-attach"}, - {GBPROX_KEEP_IDENTIFIED, "identified"}, - {GBPROX_KEEP_ALWAYS, "always"}, - {0, NULL} -}; +static void gbprox_vty_print_bvc(struct vty *vty, struct gbproxy_bvc *bvc) +{ -static const struct value_string match_ids[] = { - {GBPROX_MATCH_PATCHING, "patching"}, - {GBPROX_MATCH_ROUTING, "routing"}, - {0, NULL} -}; + if (bvc->bvci == 0) { + vty_out(vty, "NSEI %5u, SIG-BVCI %5u [%s]%s", bvc->nse->nsei, bvc->bvci, + osmo_fsm_inst_state_name(bvc->fi), VTY_NEWLINE); + } else { + struct gprs_ra_id raid; + gsm48_parse_ra(&raid, bvc->ra); + vty_out(vty, "NSEI %5u, PTP-BVCI %5u, RAI %s [%s]%s", bvc->nse->nsei, bvc->bvci, + osmo_rai_name(&raid), osmo_fsm_inst_state_name(bvc->fi), VTY_NEWLINE); + } +} -static void gbprox_vty_print_peer(struct vty *vty, struct gbproxy_peer *peer) +static void gbproxy_vty_print_nse(struct vty *vty, struct gbproxy_nse *nse, bool show_stats) { - struct gprs_ra_id raid; - gsm48_parse_ra(&raid, peer->ra); + struct gbproxy_bvc *bvc; + int j; - vty_out(vty, "NSEI %5u, PTP-BVCI %5u, " - "RAI %s", peer->nsei, peer->bvci, osmo_rai_name(&raid)); - if (peer->blocked) - vty_out(vty, " [BVC-BLOCKED]"); + hash_for_each(nse->bvcs, j, bvc, list) { + gbprox_vty_print_bvc(vty, bvc); - vty_out(vty, "%s", VTY_NEWLINE); + if (show_stats) + vty_out_rate_ctr_group(vty, " ", bvc->ctrg); + } } -static int config_write_gbproxy(struct vty *vty) +static void gbproxy_vty_print_cell(struct vty *vty, struct gbproxy_cell *cell, bool show_stats) { - enum gbproxy_match_id match_id; + struct gprs_ra_id raid; + gsm48_parse_ra(&raid, cell->ra); + unsigned int num_sgsn_bvc = 0; + unsigned int i; - vty_out(vty, "gbproxy%s", VTY_NEWLINE); + vty_out(vty, "BVCI %5u RAI %s: ", cell->bvci, osmo_rai_name(&raid)); + if (cell->bss_bvc) + vty_out(vty, "BSS NSEI %5u, SGSN NSEI ", cell->bss_bvc->nse->nsei); + else + vty_out(vty, "BSS NSEI <none>, SGSN NSEI "); - vty_out(vty, " sgsn nsei %u%s", g_cfg->nsip_sgsn_nsei, - VTY_NEWLINE); - - if (g_cfg->core_plmn.mcc > 0) - vty_out(vty, " core-mobile-country-code %s%s", - osmo_mcc_name(g_cfg->core_plmn.mcc), VTY_NEWLINE); - if (g_cfg->core_plmn.mnc > 0) - vty_out(vty, " core-mobile-network-code %s%s", - osmo_mnc_name(g_cfg->core_plmn.mnc, g_cfg->core_plmn.mnc_3_digits), VTY_NEWLINE); - - for (match_id = 0; match_id < ARRAY_SIZE(g_cfg->matches); ++match_id) { - struct gbproxy_match *match = &g_cfg->matches[match_id]; - if (match->re_str) - vty_out(vty, " match-imsi %s %s%s", - get_value_string(match_ids, match_id), - match->re_str, VTY_NEWLINE); + for (i = 0; i < ARRAY_SIZE(cell->sgsn_bvc); i++) { + struct gbproxy_bvc *sgsn_bvc = cell->sgsn_bvc[i]; + if (sgsn_bvc) { + vty_out(vty, "%5u ", sgsn_bvc->nse->nsei); + num_sgsn_bvc++; + } } + if (num_sgsn_bvc) + vty_out(vty, "%s", VTY_NEWLINE); + else + vty_out(vty, "<none>%s", VTY_NEWLINE); +} - if (g_cfg->core_apn != NULL) { - if (g_cfg->core_apn_size > 0) { - char str[500] = {0}; - vty_out(vty, " core-access-point-name %s%s", - osmo_apn_to_str(str, g_cfg->core_apn, - g_cfg->core_apn_size), - VTY_NEWLINE); - } else { - vty_out(vty, " core-access-point-name none%s", - VTY_NEWLINE); - } - } +static int config_write_gbproxy(struct vty *vty) +{ + struct osmo_nri_range *r; - if (g_cfg->route_to_sgsn2) - vty_out(vty, " secondary-sgsn nsei %u%s", g_cfg->nsip_sgsn2_nsei, - VTY_NEWLINE); + vty_out(vty, "gbproxy%s", VTY_NEWLINE); - if (g_cfg->clean_stale_timer_freq > 0) - vty_out(vty, " link-list clean-stale-timer %u%s", - g_cfg->clean_stale_timer_freq, VTY_NEWLINE); - if (g_cfg->tlli_max_age > 0) - vty_out(vty, " link-list max-age %d%s", - g_cfg->tlli_max_age, VTY_NEWLINE); - if (g_cfg->tlli_max_len > 0) - vty_out(vty, " link-list max-length %d%s", - g_cfg->tlli_max_len, VTY_NEWLINE); - vty_out(vty, " link-list keep-mode %s%s", - get_value_string(keep_modes, g_cfg->keep_link_infos), - VTY_NEWLINE); - if (g_cfg->stored_msgs_max_len > 0) - vty_out(vty, " link stored-msgs-max-length %"PRIu32"%s", - g_cfg->stored_msgs_max_len, VTY_NEWLINE); + if (g_cfg->pool.bvc_fc_ratio != 100) + vty_out(vty, " pool bvc-flow-control-ratio %u%s", g_cfg->pool.bvc_fc_ratio, VTY_NEWLINE); + if (g_cfg->pool.nri_bitlen != OSMO_NRI_BITLEN_DEFAULT) + vty_out(vty, " nri bitlen %u%s", g_cfg->pool.nri_bitlen, VTY_NEWLINE); + llist_for_each_entry(r, &g_cfg->pool.null_nri_ranges->entries, entry) { + vty_out(vty, " nri null add %d", r->first); + if (r->first != r->last) + vty_out(vty, " %d", r->last); + vty_out(vty, "%s", VTY_NEWLINE); + } return CMD_SUCCESS; } @@ -149,470 +155,471 @@ DEFUN(cfg_gbproxy, return CMD_SUCCESS; } -DEFUN(cfg_nsip_sgsn_nsei, - cfg_nsip_sgsn_nsei_cmd, - "sgsn nsei <0-65534>", - "SGSN information\n" - "NSEI to be used in the connection with the SGSN\n" - "The NSEI\n") -{ - unsigned int nsei = atoi(argv[0]); +/* VTY code for SGSN (pool) configuration */ +extern const struct bssgp_bvc_fsm_ops sgsn_sig_bvc_fsm_ops; +#include <osmocom/gprs/protocol/gsm_08_18.h> - if (g_cfg->route_to_sgsn2 && g_cfg->nsip_sgsn2_nsei == nsei) { - vty_out(vty, "SGSN NSEI %d conflicts with secondary SGSN NSEI%s", - nsei, VTY_NEWLINE); - return CMD_WARNING; - } +static struct cmd_node sgsn_node = { + SGSN_NODE, + "%s(config-sgsn)# ", + 1, +}; - g_cfg->nsip_sgsn_nsei = nsei; - return CMD_SUCCESS; -} +static void sgsn_write_nri(struct vty *vty, struct gbproxy_sgsn *sgsn, bool verbose) +{ + struct osmo_nri_range *r; -#define GBPROXY_CORE_MNC_STR "Use this network code for the core network\n" + if (verbose) { + vty_out(vty, "sgsn nsei %d%s", sgsn->nse->nsei, VTY_NEWLINE); + if (llist_empty(&sgsn->pool.nri_ranges->entries)) { + vty_out(vty, " %% no NRI mappings%s", VTY_NEWLINE); + return; + } + } -DEFUN(cfg_gbproxy_core_mnc, - cfg_gbproxy_core_mnc_cmd, - "core-mobile-network-code <1-999>", - GBPROXY_CORE_MNC_STR "NCC value\n") -{ - uint16_t mnc; - bool mnc_3_digits; - if (osmo_mnc_from_str(argv[0], &mnc, &mnc_3_digits)) { - vty_out(vty, "%% Invalid MNC: %s%s", argv[0], VTY_NEWLINE); - return CMD_WARNING; + llist_for_each_entry(r, &sgsn->pool.nri_ranges->entries, entry) { + if (osmo_nri_range_validate(r, 255)) + vty_out(vty, " %% INVALID RANGE:"); + vty_out(vty, " nri add %d", r->first); + if (r->first != r->last) + vty_out(vty, " %d", r->last); + vty_out(vty, "%s", VTY_NEWLINE); } - g_cfg->core_plmn.mnc = mnc; - g_cfg->core_plmn.mnc_3_digits = mnc_3_digits; - return CMD_SUCCESS; } -DEFUN(cfg_gbproxy_no_core_mnc, - cfg_gbproxy_no_core_mnc_cmd, - "no core-mobile-network-code", - NO_STR GBPROXY_CORE_MNC_STR) +static void write_sgsn(struct vty *vty, struct gbproxy_sgsn *sgsn) { - g_cfg->core_plmn.mnc = 0; - g_cfg->core_plmn.mnc_3_digits = false; - return CMD_SUCCESS; + vty_out(vty, "sgsn nsei %u%s", sgsn->nse->nsei, VTY_NEWLINE); + vty_out(vty, " name %s%s", sgsn->name, VTY_NEWLINE); + vty_out(vty, " %sallow-attach%s", sgsn->pool.allow_attach ? "" : "no ", VTY_NEWLINE); + sgsn_write_nri(vty, sgsn, false); } -#define GBPROXY_CORE_MCC_STR "Use this country code for the core network\n" - -DEFUN(cfg_gbproxy_core_mcc, - cfg_gbproxy_core_mcc_cmd, - "core-mobile-country-code <1-999>", - GBPROXY_CORE_MCC_STR "MCC value\n") +static int config_write_sgsn(struct vty *vty) { - g_cfg->core_plmn.mcc = atoi(argv[0]); - return CMD_SUCCESS; -} + struct gbproxy_sgsn *sgsn; + + llist_for_each_entry(sgsn, &g_cfg->sgsns, list) + write_sgsn(vty, sgsn); -DEFUN(cfg_gbproxy_no_core_mcc, - cfg_gbproxy_no_core_mcc_cmd, - "no core-mobile-country-code", - NO_STR GBPROXY_CORE_MCC_STR) -{ - g_cfg->core_plmn.mcc = 0; return CMD_SUCCESS; } -#define GBPROXY_MATCH_IMSI_STR "Restrict actions to certain IMSIs\n" - -DEFUN(cfg_gbproxy_match_imsi, - cfg_gbproxy_match_imsi_cmd, - "match-imsi (patching|routing) .REGEXP", - GBPROXY_MATCH_IMSI_STR - "Patch MS related information elements on match only\n" - "Route to the secondary SGSN on match only\n" - "Regular expression for the IMSI match\n") +DEFUN(cfg_sgsn_nsei, + cfg_sgsn_nsei_cmd, + "sgsn nsei <0-65534>", + "Configure the SGSN\n" + "NSEI to be used in the connection with the SGSN\n" + "The NSEI\n") { - const char *filter = argv[1]; - const char *err_msg = NULL; - struct gbproxy_match *match; - enum gbproxy_match_id match_id = get_string_value(match_ids, argv[0]); - - OSMO_ASSERT(match_id >= GBPROX_MATCH_PATCHING && - match_id < GBPROX_MATCH_LAST); - match = &g_cfg->matches[match_id]; - - if (gbproxy_set_patch_filter(match, filter, &err_msg) != 0) { - vty_out(vty, "Match expression invalid: %s%s", - err_msg, VTY_NEWLINE); + uint32_t features = 0; // FIXME: make configurable + unsigned int nsei = atoi(argv[0]); + unsigned int num_sgsn = llist_count(&g_cfg->sgsns); + struct gbproxy_sgsn *sgsn; + struct gbproxy_nse *nse; + struct gbproxy_bvc *bvc; + + if (num_sgsn >= GBPROXY_MAX_NR_SGSN) { + vty_out(vty, "%% Too many SGSN NSE defined (%d), increase GBPROXY_MAX_NR_SGSN%s", + num_sgsn, VTY_NEWLINE); return CMD_WARNING; } - g_cfg->acquire_imsi = true; + /* This will have created the gbproxy_nse as well */ + sgsn = gbproxy_sgsn_by_nsei_or_new(g_cfg, nsei); + if (!sgsn) + goto free_nothing; + nse = sgsn->nse; + if (num_sgsn > 1 && g_cfg->pool.nri_bitlen == 0) + vty_out(vty, "%% Multiple SGSNs defined, but no pooling enabled%s", VTY_NEWLINE); + + + if (!gbproxy_bvc_by_bvci(nse, 0)) { + uint8_t cause = BSSGP_CAUSE_OML_INTERV; + bvc = gbproxy_bvc_alloc(nse, 0); + if (!bvc) + goto free_sgsn; + bvc->fi = bssgp_bvc_fsm_alloc_sig_bss(bvc, nse->cfg->nsi, nsei, features); + if (!bvc->fi) + goto free_bvc; + bssgp_bvc_fsm_set_ops(bvc->fi, &sgsn_sig_bvc_fsm_ops, bvc); + osmo_fsm_inst_dispatch(bvc->fi, BSSGP_BVCFSM_E_REQ_RESET, &cause); + } + vty->node = SGSN_NODE; + vty->index = sgsn; return CMD_SUCCESS; -} -DEFUN(cfg_gbproxy_no_match_imsi, - cfg_gbproxy_no_match_imsi_cmd, - "no match-imsi", - NO_STR GBPROXY_MATCH_IMSI_STR) -{ - enum gbproxy_match_id match_id; - - for (match_id = 0; match_id < ARRAY_SIZE(g_cfg->matches); ++match_id) - gbproxy_clear_patch_filter(&g_cfg->matches[match_id]); - - g_cfg->acquire_imsi = false; - - return CMD_SUCCESS; +free_bvc: + gbproxy_bvc_free(bvc); +free_sgsn: + gbproxy_sgsn_free(sgsn); +free_nothing: + vty_out(vty, "%% Unable to create NSE for NSEI=%05u%s", nsei, VTY_NEWLINE); + return CMD_WARNING; } -#define GBPROXY_CORE_APN_STR "Use this access point name (APN) for the backbone\n" -#define GBPROXY_CORE_APN_ARG_STR "Replace APN by this string\n" "Remove APN\n" - -static int set_core_apn(struct vty *vty, const char *apn) +DEFUN(cfg_sgsn_name, + cfg_sgsn_name_cmd, + "name NAME", + "Configure the SGSN\n" + "Name the SGSN\n" + "The name\n") { - int apn_len; + struct gbproxy_sgsn *sgsn = vty->index; + const char *name = argv[0]; - if (!apn) { - talloc_free(g_cfg->core_apn); - g_cfg->core_apn = NULL; - g_cfg->core_apn_size = 0; - return CMD_SUCCESS; - } - - apn_len = strlen(apn); - if (apn_len >= 100) { - vty_out(vty, "APN string too long (max 99 chars)%s", - VTY_NEWLINE); + osmo_talloc_replace_string(sgsn, &sgsn->name, name); + if (!sgsn->name) { + vty_out(vty, "%% Unable to set name for SGSN with nsei %05u%s", sgsn->nse->nsei, VTY_NEWLINE); return CMD_WARNING; } - if (apn_len == 0) { - talloc_free(g_cfg->core_apn); - /* TODO: replace NULL */ - g_cfg->core_apn = talloc_zero_size(NULL, 2); - g_cfg->core_apn_size = 0; - } else { - /* TODO: replace NULL */ - g_cfg->core_apn = - talloc_realloc_size(NULL, g_cfg->core_apn, apn_len + 1); - g_cfg->core_apn_size = - gprs_str_to_apn(g_cfg->core_apn, apn_len + 1, apn); - } - return CMD_SUCCESS; } -DEFUN(cfg_gbproxy_core_apn, - cfg_gbproxy_core_apn_cmd, - "core-access-point-name (APN|none)", - GBPROXY_CORE_APN_STR GBPROXY_CORE_APN_ARG_STR) -{ - if (strcmp(argv[0], "none") == 0) - return set_core_apn(vty, ""); - else - return set_core_apn(vty, argv[0]); -} - -DEFUN(cfg_gbproxy_no_core_apn, - cfg_gbproxy_no_core_apn_cmd, - "no core-access-point-name", - NO_STR GBPROXY_CORE_APN_STR) +DEFUN_ATTR(cfg_sgsn_nri_add, cfg_sgsn_nri_add_cmd, + "nri add <0-32767> [<0-32767>]", + NRI_STR "Add NRI value or range to the NRI mapping for this MSC\n" + NRI_FIRST_LAST_STR, + CMD_ATTR_IMMEDIATE) { - return set_core_apn(vty, NULL); -} + struct gbproxy_sgsn *sgsn = vty->index; + struct gbproxy_sgsn *other_sgsn; + bool before; + int rc; + const char *message; + struct osmo_nri_range add_range; -/* TODO: Remove the patch-ptmsi command, since P-TMSI patching is enabled - * automatically when needed. This command is only left for manual testing - * (e.g. doing P-TMSI patching without using a secondary SGSN) - */ -#define GBPROXY_PATCH_PTMSI_STR "Patch P-TMSI/TLLI\n" + rc = osmo_nri_ranges_vty_add(&message, &add_range, sgsn->pool.nri_ranges, argc, argv, g_cfg->pool.nri_bitlen); + if (message) { + NRI_WARN(sgsn, "%s: " NRI_ARGS_TO_STR_FMT, message, NRI_ARGS_TO_STR_ARGS(argc, argv)); + } + if (rc < 0) + return CMD_WARNING; -DEFUN(cfg_gbproxy_patch_ptmsi, - cfg_gbproxy_patch_ptmsi_cmd, - "patch-ptmsi", - GBPROXY_PATCH_PTMSI_STR) -{ - g_cfg->patch_ptmsi = true; + /* Issue a warning about NRI range overlaps (but still allow them). + * Overlapping ranges will map to whichever SGSN comes fist in the gbproxy_config->sgsns llist, + * which should be the first one defined in the config */ + before = true; + llist_for_each_entry(other_sgsn, &g_cfg->sgsns, list) { + if (other_sgsn == sgsn) { + before = false; + continue; + } + if (osmo_nri_range_overlaps_ranges(&add_range, other_sgsn->pool.nri_ranges)) { + uint16_t nsei = sgsn->nse->nsei; + uint16_t other_nsei = other_sgsn->nse->nsei; + NRI_WARN(sgsn, "NRI range [%d..%d] overlaps between NSE %05d and NSE %05d." + " For overlaps, NSE %05d has higher priority than NSE %05d", + add_range.first, add_range.last, nsei, other_nsei, + before ? other_nsei : nsei, before ? nsei : other_nsei); + } + } return CMD_SUCCESS; } -DEFUN(cfg_gbproxy_no_patch_ptmsi, - cfg_gbproxy_no_patch_ptmsi_cmd, - "no patch-ptmsi", - NO_STR GBPROXY_PATCH_PTMSI_STR) +DEFUN_ATTR(cfg_sgsn_nri_del, cfg_sgsn_nri_del_cmd, + "nri del <0-32767> [<0-32767>]", + NRI_STR "Remove NRI value or range from the NRI mapping for this MSC\n" + NRI_FIRST_LAST_STR, + CMD_ATTR_IMMEDIATE) { - g_cfg->patch_ptmsi = false; + struct gbproxy_sgsn *sgsn = vty->index; + int rc; + const char *message; + rc = osmo_nri_ranges_vty_del(&message, NULL, sgsn->pool.nri_ranges, argc, argv); + if (message) { + NRI_WARN(sgsn, "%s: " NRI_ARGS_TO_STR_FMT, message, NRI_ARGS_TO_STR_ARGS(argc, argv)); + } + if (rc < 0) + return CMD_WARNING; return CMD_SUCCESS; } -/* TODO: Remove the acquire-imsi command, since that feature is enabled - * automatically when IMSI matching is enabled. This command is only left for - * manual testing (e.g. doing IMSI acquisition without IMSI based patching) - */ -#define GBPROXY_ACQUIRE_IMSI_STR "Acquire the IMSI before establishing a LLC connection (Experimental)\n" - -DEFUN(cfg_gbproxy_acquire_imsi, - cfg_gbproxy_acquire_imsi_cmd, - "acquire-imsi", - GBPROXY_ACQUIRE_IMSI_STR) +DEFUN_ATTR(cfg_sgsn_allow_attach, cfg_sgsn_allow_attach_cmd, + "allow-attach", + "Allow this SGSN to attach new subscribers (default).\n", + CMD_ATTR_IMMEDIATE) { - g_cfg->acquire_imsi = true; - + struct gbproxy_sgsn *sgsn = vty->index; + sgsn->pool.allow_attach = true; return CMD_SUCCESS; } -DEFUN(cfg_gbproxy_no_acquire_imsi, - cfg_gbproxy_no_acquire_imsi_cmd, - "no acquire-imsi", - NO_STR GBPROXY_ACQUIRE_IMSI_STR) +DEFUN_ATTR(cfg_sgsn_no_allow_attach, cfg_sgsn_no_allow_attach_cmd, + "no allow-attach", + NO_STR + "Do not assign new subscribers to this MSC." + " Useful if an MSC in an MSC pool is configured to off-load subscribers." + " The MSC will still be operational for already IMSI-Attached subscribers," + " but the NAS node selection function will skip this MSC for new subscribers\n", + CMD_ATTR_IMMEDIATE) { - g_cfg->acquire_imsi = false; - + struct gbproxy_sgsn *sgsn = vty->index; + sgsn->pool.allow_attach = false; return CMD_SUCCESS; } -#define GBPROXY_SECOND_SGSN_STR "Route matching LLC connections to a second SGSN (Experimental)\n" - -DEFUN(cfg_gbproxy_secondary_sgsn, - cfg_gbproxy_secondary_sgsn_cmd, - "secondary-sgsn nsei <0-65534>", - GBPROXY_SECOND_SGSN_STR - "NSEI to be used in the connection with the SGSN\n" - "The NSEI\n") +DEFUN(sgsn_show_nri_all, show_nri_all_cmd, + "show nri all", + SHOW_STR NRI_STR "Show all SGSNs\n") { - unsigned int nsei = atoi(argv[0]); - - if (g_cfg->nsip_sgsn_nsei == nsei) { - vty_out(vty, "Secondary SGSN NSEI %d conflicts with primary SGSN NSEI%s", - nsei, VTY_NEWLINE); - return CMD_WARNING; - } - - g_cfg->route_to_sgsn2 = true; - g_cfg->nsip_sgsn2_nsei = nsei; + struct gbproxy_sgsn *sgsn; - g_cfg->patch_ptmsi = true; + llist_for_each_entry(sgsn, &g_cfg->sgsns, list) + sgsn_write_nri(vty, sgsn, true); return CMD_SUCCESS; } -DEFUN(cfg_gbproxy_no_secondary_sgsn, - cfg_gbproxy_no_secondary_sgsn_cmd, - "no secondary-sgsn", - NO_STR GBPROXY_SECOND_SGSN_STR) +DEFUN(show_nri_nsei, show_nri_nsei_cmd, + "show nri nsei <0-65535>", + SHOW_STR NRI_STR "Identify SGSN by NSEI\n" + "NSEI of the SGSN\n") { - g_cfg->route_to_sgsn2 = false; - g_cfg->nsip_sgsn2_nsei = 0xFFFF; + struct gbproxy_sgsn *sgsn; + int nsei = atoi(argv[0]); - g_cfg->patch_ptmsi = false; + sgsn = gbproxy_sgsn_by_nsei(g_cfg, nsei); + if (!sgsn) { + vty_out(vty, "%% No SGSN with found for NSEI %05d%s", nsei, VTY_NEWLINE); + return CMD_SUCCESS; + } + sgsn_write_nri(vty, sgsn, true); return CMD_SUCCESS; } -#define GBPROXY_LINK_LIST_STR "Set TLLI list parameters\n" -#define GBPROXY_LINK_STR "Set TLLI parameters\n" - -#define GBPROXY_CLEAN_STALE_TIMER_STR "Periodic timer to clean stale links\n" - -DEFUN(cfg_gbproxy_link_list_clean_stale_timer, - cfg_gbproxy_link_list_clean_stale_timer_cmd, - "link-list clean-stale-timer <1-999999>", - GBPROXY_LINK_LIST_STR GBPROXY_CLEAN_STALE_TIMER_STR - "Frequency at which the periodic timer is fired (in seconds)\n") +DEFUN(cfg_pool_bvc_fc_ratio, + cfg_pool_bvc_fc_ratio_cmd, + "pool bvc-flow-control-ratio <1-100>", + "SGSN Pool related configuration\n" + "Ratio of BSS-advertised bucket size + leak rate advertised to each SGSN\n" + "Ratio of BSS-advertised bucket size + leak rate advertised to each SGSN (Percent)\n") { - struct gbproxy_peer *peer; - g_cfg->clean_stale_timer_freq = (unsigned int) atoi(argv[0]); - - /* Re-schedule running timers soon in case prev frequency was really big - and new frequency is desired to be lower. After initial run, periodic - time is used. Use random() to avoid firing timers for all peers at - the same time */ - llist_for_each_entry(peer, &g_cfg->bts_peers, list) - osmo_timer_schedule(&peer->clean_stale_timer, - random() % 5, random() % 1000000); - + g_cfg->pool.bvc_fc_ratio = atoi(argv[0]); return CMD_SUCCESS; } - -DEFUN(cfg_gbproxy_link_list_no_clean_stale_timer, - cfg_gbproxy_link_list_no_clean_stale_timer_cmd, - "no link-list clean-stale-timer", - NO_STR GBPROXY_LINK_LIST_STR GBPROXY_CLEAN_STALE_TIMER_STR) - +DEFUN_ATTR(cfg_gbproxy_nri_bitlen, + cfg_gbproxy_nri_bitlen_cmd, + "nri bitlen <0-15>", + NRI_STR + "Set number of bits that an NRI has, to extract from TMSI identities (always starting just after the TMSI's most significant octet).\n" + "bit count (0 disables) pooling)\n", + CMD_ATTR_IMMEDIATE) { - struct gbproxy_peer *peer; - g_cfg->clean_stale_timer_freq = 0; + g_cfg->pool.nri_bitlen = atoi(argv[0]); + + if (llist_count(&g_cfg->sgsns) > 1 && g_cfg->pool.nri_bitlen == 0) + vty_out(vty, "%% Pooling disabled, but multiple SGSNs defined%s", VTY_NEWLINE); - llist_for_each_entry(peer, &g_cfg->bts_peers, list) - osmo_timer_del(&peer->clean_stale_timer); + /* TODO: Verify all nri ranges and warn on mismatch */ return CMD_SUCCESS; } -#define GBPROXY_MAX_AGE_STR "Limit maximum age\n" - -DEFUN(cfg_gbproxy_link_list_max_age, - cfg_gbproxy_link_list_max_age_cmd, - "link-list max-age <1-999999>", - GBPROXY_LINK_LIST_STR GBPROXY_MAX_AGE_STR - "Maximum age in seconds\n") +DEFUN_ATTR(cfg_gbproxy_nri_null_add, + cfg_gbproxy_nri_null_add_cmd, + "nri null add <0-32767> [<0-32767>]", + NRI_STR NULL_NRI_STR "Add NULL-NRI value (or range)\n" + NRI_FIRST_LAST_STR, + CMD_ATTR_IMMEDIATE) { - g_cfg->tlli_max_age = atoi(argv[0]); + int rc; + const char *message; + rc = osmo_nri_ranges_vty_add(&message, NULL, g_cfg->pool.null_nri_ranges, argc, argv, + g_cfg->pool.nri_bitlen); + if (message) { + vty_out(vty, "%% nri null add: %s: " NRI_ARGS_TO_STR_FMT "%s", message, NRI_ARGS_TO_STR_ARGS(argc, argv), + VTY_NEWLINE); + vty_out(vty, "%s: \n" NRI_ARGS_TO_STR_FMT, message, NRI_ARGS_TO_STR_ARGS(argc, argv)); + } + if (rc < 0) + return CMD_WARNING; return CMD_SUCCESS; } -DEFUN(cfg_gbproxy_link_list_no_max_age, - cfg_gbproxy_link_list_no_max_age_cmd, - "no link-list max-age", - NO_STR GBPROXY_LINK_LIST_STR GBPROXY_MAX_AGE_STR) +DEFUN_ATTR(cfg_gbproxy_nri_null_del, + cfg_gbproxy_nri_null_del_cmd, + "nri null del <0-32767> [<0-32767>]", + NRI_STR NULL_NRI_STR "Remove NRI value or range from the NRI mapping for this MSC\n" + NRI_FIRST_LAST_STR, + CMD_ATTR_IMMEDIATE) { - g_cfg->tlli_max_age = 0; - + int rc; + const char *message; + rc = osmo_nri_ranges_vty_del(&message, NULL, g_cfg->pool.null_nri_ranges, argc, argv); + if (message) { + vty_out(vty, "%% %s: " NRI_ARGS_TO_STR_FMT "%s", message, NRI_ARGS_TO_STR_ARGS(argc, argv), + VTY_NEWLINE); + } + if (rc < 0) + return CMD_WARNING; return CMD_SUCCESS; } -#define GBPROXY_MAX_LEN_STR "Limit list length\n" - -DEFUN(cfg_gbproxy_link_list_max_len, - cfg_gbproxy_link_list_max_len_cmd, - "link-list max-length <1-99999>", - GBPROXY_LINK_LIST_STR GBPROXY_MAX_LEN_STR - "Maximum number of logical links in the list\n") +static void log_set_bvc_filter(struct log_target *target, + const uint16_t *bvci) { - g_cfg->tlli_max_len = atoi(argv[0]); - - return CMD_SUCCESS; + if (bvci) { + uintptr_t bvci_filter = *bvci | BVC_LOG_CTX_FLAG; + target->filter_map |= (1 << LOG_FLT_GB_BVC); + target->filter_data[LOG_FLT_GB_BVC] = (void *)bvci_filter; + } else if (target->filter_data[LOG_FLT_GB_BVC]) { + target->filter_map = ~(1 << LOG_FLT_GB_BVC); + target->filter_data[LOG_FLT_GB_BVC] = NULL; + } } -DEFUN(cfg_gbproxy_link_list_no_max_len, - cfg_gbproxy_link_list_no_max_len_cmd, - "no link-list max-length", - NO_STR GBPROXY_LINK_LIST_STR GBPROXY_MAX_LEN_STR) +DEFUN(logging_fltr_bvc, + logging_fltr_bvc_cmd, + "logging filter bvc bvci <0-65535>", + LOGGING_STR FILTER_STR + "Filter based on BSSGP VC\n" + "Identify BVC by BVCI\n" + "Numeric identifier\n") { - g_cfg->tlli_max_len = 0; + struct log_target *tgt; + uint16_t id = atoi(argv[0]); + + log_tgt_mutex_lock(); + tgt = osmo_log_vty2tgt(vty); + if (!tgt) { + log_tgt_mutex_unlock(); + return CMD_WARNING; + } + log_set_bvc_filter(tgt, &id); + log_tgt_mutex_unlock(); return CMD_SUCCESS; } -DEFUN(cfg_gbproxy_link_list_keep_mode, - cfg_gbproxy_link_list_keep_mode_cmd, - "link-list keep-mode (never|re-attach|identified|always)", - GBPROXY_LINK_LIST_STR "How to keep entries for detached logical links\n" - "Discard entry immediately after detachment\n" - "Keep entry if a re-attachment has be requested\n" - "Keep entry if it associated with an IMSI\n" - "Don't discard entries after detachment\n") +DEFUN(show_gbproxy_bvc, show_gbproxy_bvc_cmd, "show gbproxy bvc (bss|sgsn) [stats]", + SHOW_STR GBPROXY_STR + "Show BSSGP Virtual Connections\n" + "Display BSS-side BVCs\n" + "Display SGSN-side BVCs\n" + "Show statistics\n") { - int val = get_string_value(keep_modes, argv[0]); - OSMO_ASSERT(val >= GBPROX_KEEP_NEVER && val <= GBPROX_KEEP_ALWAYS); - g_cfg->keep_link_infos = val; + struct gbproxy_nse *nse; + bool show_stats = argc >= 2; + int i; + + if (show_stats) + vty_out_rate_ctr_group(vty, "", g_cfg->ctrg); + if (!strcmp(argv[0], "bss")) { + hash_for_each(g_cfg->bss_nses, i, nse, list) + gbproxy_vty_print_nse(vty, nse, show_stats); + } else { + hash_for_each(g_cfg->sgsn_nses, i, nse, list) + gbproxy_vty_print_nse(vty, nse, show_stats); + } return CMD_SUCCESS; } -DEFUN(cfg_gbproxy_link_stored_msgs_max_len, - cfg_gbproxy_link_stored_msgs_max_len_cmd, - "link stored-msgs-max-length <1-99999>", - GBPROXY_LINK_STR GBPROXY_MAX_LEN_STR - "Maximum number of msgb stored in the logical link waiting to acquire its IMSI\n") +DEFUN(show_gbproxy_cell, show_gbproxy_cell_cmd, "show gbproxy cell [stats]", + SHOW_STR GBPROXY_STR + "Show GPRS Cell Information\n" + "Show statistics\n") { - g_cfg->stored_msgs_max_len = (uint32_t) atoi(argv[0]); + struct gbproxy_cell *cell; + bool show_stats = argc >= 1; + int i; + + hash_for_each(g_cfg->cells, i, cell, list) + gbproxy_vty_print_cell(vty, cell, show_stats); return CMD_SUCCESS; } -DEFUN(cfg_gbproxy_link_no_stored_msgs_max_len, - cfg_gbproxy_link_no_stored_msgs_max_len_cmd, - "no link stored-msgs-max-length", - NO_STR GBPROXY_LINK_STR GBPROXY_MAX_LEN_STR) +DEFUN(show_gbproxy_links, show_gbproxy_links_cmd, "show gbproxy links", + SHOW_STR GBPROXY_STR "Show logical links\n") { - g_cfg->stored_msgs_max_len = 0; + struct gbproxy_nse *nse; + int i, j; + hash_for_each(g_cfg->bss_nses, i, nse, list) { + struct gbproxy_bvc *bvc; + hash_for_each(nse->bvcs, j, bvc, list) { + gbprox_vty_print_bvc(vty, bvc); + } + } return CMD_SUCCESS; } - -DEFUN(show_gbproxy, show_gbproxy_cmd, "show gbproxy [stats]", - SHOW_STR "Display information about the Gb proxy\n" "Show statistics\n") +DEFUN(show_gbproxy_tlli_cache, show_gbproxy_tlli_cache_cmd, + "show gbproxy tlli-cache", + SHOW_STR GBPROXY_STR "Show TLLI cache entries\n") { - struct gbproxy_peer *peer; - int show_stats = argc >= 1; + struct gbproxy_tlli_cache_entry *entry; + struct timespec now; + time_t expiry; + int i, count = 0; - if (show_stats) - vty_out_rate_ctr_group(vty, "", g_cfg->ctrg); + osmo_clock_gettime(CLOCK_MONOTONIC, &now); + expiry = now.tv_sec - g_cfg->tlli_cache.timeout; - llist_for_each_entry(peer, &g_cfg->bts_peers, list) { - gbprox_vty_print_peer(vty, peer); + vty_out(vty, "TLLI cache timeout %us%s", g_cfg->tlli_cache.timeout, VTY_NEWLINE); + hash_for_each(g_cfg->tlli_cache.entries, i, entry, list) { + time_t valid = entry->tstamp - expiry; + struct gbproxy_nse *nse = entry->nse; - if (show_stats) - vty_out_rate_ctr_group(vty, " ", peer->ctrg); + vty_out(vty, " TLLI %08x -> NSE(%05u/%s) valid %lds%s", entry->tlli, nse->nsei, + nse->sgsn_facing ? "SGSN" : "BSS", valid, VTY_NEWLINE); + count++; } + vty_out(vty, "TLLI cache contains %u entries%s", count, VTY_NEWLINE); return CMD_SUCCESS; } -DEFUN(show_gbproxy_links, show_gbproxy_links_cmd, "show gbproxy links", - SHOW_STR "Display information about the Gb proxy\n" "Show logical links\n") -{ - struct gbproxy_peer *peer; - time_t now; - struct timespec ts = {0,}; - - osmo_clock_gettime(CLOCK_MONOTONIC, &ts); - now = ts.tv_sec; - - llist_for_each_entry(peer, &g_cfg->bts_peers, list) { - struct gbproxy_link_info *link_info; - struct gbproxy_patch_state *state = &peer->patch_state; - - gbprox_vty_print_peer(vty, peer); - - llist_for_each_entry(link_info, &state->logical_links, list) { - time_t age = now - link_info->timestamp; - struct osmo_mobile_identity mi; - const char *imsi_str; - - if (link_info->imsi > 0) { - if (osmo_mobile_identity_decode(&mi, link_info->imsi, link_info->imsi_len, false) - || mi.type != GSM_MI_TYPE_IMSI) - imsi_str = "(invalid)"; - else - imsi_str = mi.imsi; - } else { - imsi_str = "(none)"; - } - vty_out(vty, " TLLI %08x, IMSI %s, AGE %d", - link_info->tlli.current, imsi_str, (int)age); - - if (link_info->stored_msgs_len) - vty_out(vty, ", STORED %"PRIu32"/%"PRIu32, - link_info->stored_msgs_len, - g_cfg->stored_msgs_max_len); - - if (g_cfg->route_to_sgsn2) - vty_out(vty, ", SGSN NSEI %d", - link_info->sgsn_nsei); +DEFUN(show_gbproxy_imsi_cache, show_gbproxy_imsi_cache_cmd, + "show gbproxy imsi-cache", + SHOW_STR GBPROXY_STR "Show IMSI cache entries\n") +{ + struct gbproxy_imsi_cache_entry *entry; + struct timespec now; + time_t expiry; + int i, count = 0; - if (link_info->is_deregistered) - vty_out(vty, ", DE-REGISTERED"); + osmo_clock_gettime(CLOCK_MONOTONIC, &now); + expiry = now.tv_sec - g_cfg->imsi_cache.timeout; - vty_out(vty, "%s", VTY_NEWLINE); - } + vty_out(vty, "IMSI cache timeout %us%s", g_cfg->imsi_cache.timeout, VTY_NEWLINE); + hash_for_each(g_cfg->imsi_cache.entries, i, entry, list) { + time_t valid = entry->tstamp - expiry; + struct gbproxy_nse *nse = entry->nse; + vty_out(vty, " IMSI %s -> NSE(%05u/%s): valid %lds%s", entry->imsi, nse->nsei, + nse->sgsn_facing ? "SGSN" : "BSS", valid, VTY_NEWLINE); + count++; } + vty_out(vty, "IMSI cache contains %u entries%s", count, VTY_NEWLINE); return CMD_SUCCESS; } DEFUN(delete_gb_bvci, delete_gb_bvci_cmd, "delete-gbproxy-peer <0-65534> bvci <2-65534>", - "Delete a GBProxy peer by NSEI and optionally BVCI\n" + "Delete a GBProxy bvc by NSEI and optionally BVCI\n" "NSEI number\n" - "Only delete peer with a matching BVCI\n" + "Only delete bvc with a matching BVCI\n" "BVCI number\n") { const uint16_t nsei = atoi(argv[0]); const uint16_t bvci = atoi(argv[1]); + struct gbproxy_nse *nse = gbproxy_nse_by_nsei(g_cfg, nsei, NSE_F_BSS); int counter; - counter = gbproxy_cleanup_peers(g_cfg, nsei, bvci); + if (!nse) { + vty_out(vty, "NSE not found%s", VTY_NEWLINE); + return CMD_WARNING; + } + + counter = gbproxy_cleanup_bvcs(nse, bvci); if (counter == 0) { vty_out(vty, "BVC not found%s", VTY_NEWLINE); @@ -624,7 +631,7 @@ DEFUN(delete_gb_bvci, delete_gb_bvci_cmd, DEFUN(delete_gb_nsei, delete_gb_nsei_cmd, "delete-gbproxy-peer <0-65534> (only-bvc|only-nsvc|all) [dry-run]", - "Delete a GBProxy peer by NSEI and optionally BVCI\n" + "Delete a GBProxy bvc by NSEI and optionally BVCI\n" "NSEI number\n" "Only delete BSSGP connections (BVC)\n" "Only delete dynamic NS connections (NS-VC)\n" @@ -647,18 +654,23 @@ DEFUN(delete_gb_nsei, delete_gb_nsei_cmd, delete_bvc = delete_nsvc = 1; if (delete_bvc) { - if (!dry_run) - counter = gbproxy_cleanup_peers(g_cfg, nsei, 0); - else { - struct gbproxy_peer *peer; + if (!dry_run) { + struct gbproxy_nse *nse = gbproxy_nse_by_nsei(g_cfg, nsei, NSE_F_BSS); + counter = gbproxy_cleanup_bvcs(nse, 0); + gbproxy_nse_free(nse); + } else { + struct gbproxy_nse *nse; + struct gbproxy_bvc *bvc; + int i, j; counter = 0; - llist_for_each_entry(peer, &g_cfg->bts_peers, list) { - if (peer->nsei != nsei) + hash_for_each(g_cfg->bss_nses, i, nse, list) { + if (nse->nsei != nsei) continue; - - vty_out(vty, "BVC: "); - gbprox_vty_print_peer(vty, peer); - counter += 1; + hash_for_each(nse->bvcs, j, bvc, list) { + vty_out(vty, "BVC: "); + gbprox_vty_print_bvc(vty, bvc); + counter += 1; + } } } vty_out(vty, "%sDeleted %d BVC%s", @@ -666,248 +678,87 @@ DEFUN(delete_gb_nsei, delete_gb_nsei_cmd, } if (delete_nsvc) { - struct gprs_ns_inst *nsi = g_cfg->nsi; - struct gprs_nsvc *nsvc, *nsvc2; - - counter = 0; - llist_for_each_entry_safe(nsvc, nsvc2, &nsi->gprs_nsvcs, list) { - if (nsvc->nsei != nsei) - continue; - if (nsvc->persistent) - continue; - - if (!dry_run) - gprs_nsvc_delete(nsvc); - else - vty_out(vty, "NS-VC: NSEI %5u, NS-VCI %5u, " - "remote %s%s", - nsvc->nsei, nsvc->nsvci, - gprs_ns_ll_str(nsvc), VTY_NEWLINE); - counter += 1; - } - vty_out(vty, "%sDeleted %d NS-VC%s", - dry_run ? "Not " : "", counter, VTY_NEWLINE); - } + struct gprs_ns2_inst *nsi = g_cfg->nsi; + struct gprs_ns2_nse *nse; - return CMD_SUCCESS; -} - -#define GBPROXY_DELETE_LINK_STR \ - "Delete a GBProxy logical link entry by NSEI and identification\nNSEI number\n" - -DEFUN(delete_gb_link_by_id, delete_gb_link_by_id_cmd, - "delete-gbproxy-link <0-65534> (tlli|imsi|sgsn-nsei) IDENT", - GBPROXY_DELETE_LINK_STR - "Delete entries with a matching TLLI (hex)\n" - "Delete entries with a matching IMSI\n" - "Delete entries with a matching SGSN NSEI\n" - "Identification to match\n") -{ - const uint16_t nsei = atoi(argv[0]); - enum {MATCH_TLLI = 't', MATCH_IMSI = 'i', MATCH_SGSN = 's'} match; - uint32_t ident = 0; - const char *imsi = NULL; - struct gbproxy_peer *peer = 0; - struct gbproxy_link_info *link_info, *nxt; - struct gbproxy_patch_state *state; - int found = 0; - - match = argv[1][0]; - - switch (match) { - case MATCH_TLLI: ident = strtoll(argv[2], NULL, 16); break; - case MATCH_IMSI: imsi = argv[2]; break; - case MATCH_SGSN: ident = strtoll(argv[2], NULL, 0); break; - }; - - peer = gbproxy_peer_by_nsei(g_cfg, nsei); - if (!peer) { - vty_out(vty, "Didn't find peer with NSEI %d%s", - nsei, VTY_NEWLINE); - return CMD_WARNING; - } - - state = &peer->patch_state; - - llist_for_each_entry_safe(link_info, nxt, &state->logical_links, list) { - struct osmo_mobile_identity mi; - - switch (match) { - case MATCH_TLLI: - if (link_info->tlli.current != ident) - continue; - break; - case MATCH_SGSN: - if (link_info->sgsn_nsei != ident) - continue; - break; - case MATCH_IMSI: - if (!link_info->imsi) - continue; - if (osmo_mobile_identity_decode(&mi, link_info->imsi, link_info->imsi_len, false) - || mi.type != GSM_MI_TYPE_IMSI) - continue; - if (strcmp(mi.imsi, imsi) != 0) - continue; - break; + nse = gprs_ns2_nse_by_nsei(nsi, nsei); + if (!nse) { + vty_out(vty, "NSEI not found%s", VTY_NEWLINE); + return CMD_WARNING; } - vty_out(vty, "Deleting link with TLLI %08x%s", link_info->tlli.current, - VTY_NEWLINE); - gbproxy_delete_link_info(peer, link_info); - found += 1; - } + /* TODO: We should NOT delete a persistent NSEI/NSVC as soon as we can check for these */ + if (!dry_run) + gprs_ns2_free_nse(nse); - if (!found && argc >= 2) { - vty_out(vty, "Didn't find link entry with %s %s%s", - argv[1], argv[2], VTY_NEWLINE); + vty_out(vty, "%sDeleted NS-VCs for NSEI %d%s", + dry_run ? "Not " : "", nsei, VTY_NEWLINE); } return CMD_SUCCESS; } -DEFUN(delete_gb_link, delete_gb_link_cmd, - "delete-gbproxy-link <0-65534> (stale|de-registered)", - GBPROXY_DELETE_LINK_STR - "Delete stale entries\n" - "Delete de-registered entries\n") +/* Only for ttcn3 testing */ +DEFUN_HIDDEN(sgsn_pool_nsf_fixed, sgsn_pool_nsf_fixed_cmd, + "sgsn-pool nsf fixed NAME", + "SGSN pooling: load balancing across multiple SGSNs.\n" + "Customize the Network Selection Function.\n" + "Set a fixed SGSN to use (for testing).\n" + "The name of the SGSN to use.\n") { - const uint16_t nsei = atoi(argv[0]); - enum {MATCH_STALE = 's', MATCH_DEREGISTERED = 'd'} match; - struct gbproxy_peer *peer = 0; - struct gbproxy_link_info *link_info, *nxt; - struct gbproxy_patch_state *state; - time_t now; - struct timespec ts = {0,}; - - int found = 0; + const char *name = argv[0]; + struct gbproxy_sgsn *sgsn = gbproxy_sgsn_by_name(g_cfg, name); - match = argv[1][0]; - - peer = gbproxy_peer_by_nsei(g_cfg, nsei); - if (!peer) { - vty_out(vty, "Didn't find peer with NSEI %d%s", - nsei, VTY_NEWLINE); + if (!sgsn) { + vty_out(vty, "%% Could not find SGSN with name %s%s", name, VTY_NEWLINE); return CMD_WARNING; } - state = &peer->patch_state; - - osmo_clock_gettime(CLOCK_MONOTONIC, &ts); - now = ts.tv_sec; - - if (match == MATCH_STALE) { - found = gbproxy_remove_stale_link_infos(peer, now); - if (found) - vty_out(vty, "Deleted %d stale logical link%s%s", - found, found == 1 ? "" : "s", VTY_NEWLINE); - } else { - llist_for_each_entry_safe(link_info, nxt, - &state->logical_links, list) { - if (!link_info->is_deregistered) - continue; - - gbproxy_delete_link_info(peer, link_info); - found += 1; - } - } - - if (found) - vty_out(vty, "Deleted %d %s logical link%s%s", - found, argv[1], found == 1 ? "" : "s", VTY_NEWLINE); - + g_cfg->pool.nsf_override = sgsn; return CMD_SUCCESS; } -/* - * legacy commands to provide an upgrade path from "broken" releases - * or pre-releases - */ -DEFUN_DEPRECATED(cfg_gbproxy_broken_apn_match, - cfg_gbproxy_broken_apn_match_cmd, - "core-access-point-name none match-imsi .REGEXP", - GBPROXY_CORE_APN_STR GBPROXY_MATCH_IMSI_STR "Remove APN\n" - "Patch MS related information elements on match only\n" - "Route to the secondary SGSN on match only\n" - "Regular expression for the IMSI match\n") -{ - const char *filter = argv[0]; - const char *err_msg = NULL; - struct gbproxy_match *match; - enum gbproxy_match_id match_id = get_string_value(match_ids, "patching"); - - /* apply APN none */ - set_core_apn(vty, ""); - - /* do the matching... with copy and paste */ - OSMO_ASSERT(match_id >= GBPROX_MATCH_PATCHING && - match_id < GBPROX_MATCH_LAST); - match = &g_cfg->matches[match_id]; - - if (gbproxy_set_patch_filter(match, filter, &err_msg) != 0) { - vty_out(vty, "Match expression invalid: %s%s", - err_msg, VTY_NEWLINE); - return CMD_WARNING; - } - - g_cfg->acquire_imsi = true; - - return CMD_SUCCESS; -} - -#define GBPROXY_TLLI_LIST_STR "Set TLLI list parameters\n" -#define GBPROXY_MAX_LEN_STR "Limit list length\n" -DEFUN_DEPRECATED(cfg_gbproxy_depr_tlli_list_max_len, - cfg_gbproxy_depr_tlli_list_max_len_cmd, - "tlli-list max-length <1-99999>", - GBPROXY_TLLI_LIST_STR GBPROXY_MAX_LEN_STR - "Maximum number of TLLIs in the list\n") +DEFUN_HIDDEN(sgsn_pool_nsf_normal, sgsn_pool_nsf_normal_cmd, + "sgsn-pool nsf normal", + "SGSN pooling: load balancing across multiple SGSNs.\n" + "Customize the Network Selection Function.\n" + "Reset the NSF back to regular operation (for testing).\n") { - g_cfg->tlli_max_len = atoi(argv[0]); - + g_cfg->pool.nsf_override = NULL; return CMD_SUCCESS; } int gbproxy_vty_init(void) { - install_element_ve(&show_gbproxy_cmd); + install_element_ve(&show_gbproxy_bvc_cmd); + install_element_ve(&show_gbproxy_cell_cmd); install_element_ve(&show_gbproxy_links_cmd); + install_element_ve(&show_gbproxy_tlli_cache_cmd); + install_element_ve(&show_gbproxy_imsi_cache_cmd); + install_element_ve(&show_nri_all_cmd); + install_element_ve(&show_nri_nsei_cmd); + install_element_ve(&logging_fltr_bvc_cmd); install_element(ENABLE_NODE, &delete_gb_bvci_cmd); install_element(ENABLE_NODE, &delete_gb_nsei_cmd); - install_element(ENABLE_NODE, &delete_gb_link_by_id_cmd); - install_element(ENABLE_NODE, &delete_gb_link_cmd); + install_element(ENABLE_NODE, &sgsn_pool_nsf_fixed_cmd); + install_element(ENABLE_NODE, &sgsn_pool_nsf_normal_cmd); install_element(CONFIG_NODE, &cfg_gbproxy_cmd); install_node(&gbproxy_node, config_write_gbproxy); - install_element(GBPROXY_NODE, &cfg_nsip_sgsn_nsei_cmd); - install_element(GBPROXY_NODE, &cfg_gbproxy_core_mcc_cmd); - install_element(GBPROXY_NODE, &cfg_gbproxy_core_mnc_cmd); - install_element(GBPROXY_NODE, &cfg_gbproxy_match_imsi_cmd); - install_element(GBPROXY_NODE, &cfg_gbproxy_core_apn_cmd); - install_element(GBPROXY_NODE, &cfg_gbproxy_secondary_sgsn_cmd); - install_element(GBPROXY_NODE, &cfg_gbproxy_patch_ptmsi_cmd); - install_element(GBPROXY_NODE, &cfg_gbproxy_acquire_imsi_cmd); - install_element(GBPROXY_NODE, &cfg_gbproxy_link_list_clean_stale_timer_cmd); - install_element(GBPROXY_NODE, &cfg_gbproxy_link_list_max_age_cmd); - install_element(GBPROXY_NODE, &cfg_gbproxy_link_list_max_len_cmd); - install_element(GBPROXY_NODE, &cfg_gbproxy_link_list_keep_mode_cmd); - install_element(GBPROXY_NODE, &cfg_gbproxy_link_stored_msgs_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_match_imsi_cmd); - install_element(GBPROXY_NODE, &cfg_gbproxy_no_core_apn_cmd); - install_element(GBPROXY_NODE, &cfg_gbproxy_no_secondary_sgsn_cmd); - install_element(GBPROXY_NODE, &cfg_gbproxy_no_patch_ptmsi_cmd); - install_element(GBPROXY_NODE, &cfg_gbproxy_no_acquire_imsi_cmd); - install_element(GBPROXY_NODE, &cfg_gbproxy_link_list_no_clean_stale_timer_cmd); - install_element(GBPROXY_NODE, &cfg_gbproxy_link_list_no_max_age_cmd); - install_element(GBPROXY_NODE, &cfg_gbproxy_link_list_no_max_len_cmd); - install_element(GBPROXY_NODE, &cfg_gbproxy_link_no_stored_msgs_max_len_cmd); - - /* broken or deprecated to allow an upgrade path */ - install_element(GBPROXY_NODE, &cfg_gbproxy_broken_apn_match_cmd); - install_element(GBPROXY_NODE, &cfg_gbproxy_depr_tlli_list_max_len_cmd); + install_element(GBPROXY_NODE, &cfg_pool_bvc_fc_ratio_cmd); + install_element(GBPROXY_NODE, &cfg_gbproxy_nri_bitlen_cmd); + install_element(GBPROXY_NODE, &cfg_gbproxy_nri_null_add_cmd); + install_element(GBPROXY_NODE, &cfg_gbproxy_nri_null_del_cmd); + + install_element(CONFIG_NODE, &cfg_sgsn_nsei_cmd); + install_node(&sgsn_node, config_write_sgsn); + install_element(SGSN_NODE, &cfg_sgsn_name_cmd); + install_element(SGSN_NODE, &cfg_sgsn_allow_attach_cmd); + install_element(SGSN_NODE, &cfg_sgsn_no_allow_attach_cmd); + install_element(SGSN_NODE, &cfg_sgsn_nri_add_cmd); + install_element(SGSN_NODE, &cfg_sgsn_nri_del_cmd); + return 0; } diff --git a/src/gprs/gprs_gb_parse.c b/src/gprs/gprs_gb_parse.c index e5de4d4c..e6a82acb 100644 --- a/src/gprs/gprs_gb_parse.c +++ b/src/gprs/gprs_gb_parse.c @@ -437,6 +437,47 @@ int gprs_gb_parse_llc(uint8_t *llc, size_t llc_len, return gprs_gb_parse_dtap(ghp->data, ghp->data_len, parse_ctx); } +/*! Determine the TLLI from the given BSSGP message. + * \param[in] bssgp pointer to start of BSSGP header + * \param[in] bssgp_len length of BSSGP message in octets + * \param[out] tlli TLLI (if any) in host byte order + * \returns 1 if TLLI found; 0 if none found; negative on parse error */ +int gprs_gb_parse_tlli(const uint8_t *bssgp, size_t bssgp_len, uint32_t *tlli) +{ + const struct bssgp_normal_hdr *bgph; + uint8_t pdu_type; + + if (bssgp_len < sizeof(struct bssgp_normal_hdr)) + return -EINVAL; + + bgph = (struct bssgp_normal_hdr *)bssgp; + pdu_type = bgph->pdu_type; + + if (pdu_type == BSSGP_PDUT_UL_UNITDATA || + pdu_type == BSSGP_PDUT_DL_UNITDATA) { + const struct bssgp_ud_hdr *budh = (struct bssgp_ud_hdr *)bssgp; + if (bssgp_len < sizeof(struct bssgp_ud_hdr)) + return -EINVAL; + *tlli = osmo_load32be((const uint8_t *)&budh->tlli); + return 1; + } else { + const uint8_t *data = bgph->data; + size_t data_len = bssgp_len - sizeof(*bgph); + struct tlv_parsed tp; + + if (bssgp_tlv_parse(&tp, data, data_len) < 0) + return -EINVAL; + + if (TLVP_PRESENT(&tp, BSSGP_IE_TLLI)) { + *tlli = osmo_load32be(TLVP_VAL(&tp, BSSGP_IE_TLLI)); + return 1; + } + } + + /* No TLLI present in message */ + return 0; +} + int gprs_gb_parse_bssgp(uint8_t *bssgp, size_t bssgp_len, struct gprs_gb_parse_context *parse_ctx) { diff --git a/src/gprs/gprs_utils.c b/src/gprs/gprs_utils.c index 13641c1e..632718aa 100644 --- a/src/gprs/gprs_utils.c +++ b/src/gprs/gprs_utils.c @@ -22,7 +22,7 @@ #include <osmocom/sgsn/gprs_utils.h> #include <osmocom/core/msgb.h> -#include <osmocom/gprs/gprs_ns.h> +#include <osmocom/gprs/gprs_ns2.h> #include <osmocom/gsm/protocol/gsm_04_08_gprs.h> #include <osmocom/gsm/protocol/gsm_04_08.h> diff --git a/src/gprs/sgsn_ares.c b/src/gprs/sgsn_ares.c index 38e31e13..87314f11 100644 --- a/src/gprs/sgsn_ares.c +++ b/src/gprs/sgsn_ares.c @@ -120,14 +120,14 @@ static void setup_ares_osmo_fd(void *data, int fd, int read, int write) update_fd: if (read) - ufd->fd.when |= OSMO_FD_READ; + osmo_fd_read_enable(&ufd->fd); else - ufd->fd.when &= ~OSMO_FD_READ; + osmo_fd_read_disable(&ufd->fd); if (write) - ufd->fd.when |= OSMO_FD_WRITE; + osmo_fd_write_enable(&ufd->fd); else - ufd->fd.when &= ~OSMO_FD_WRITE; + osmo_fd_write_disable(&ufd->fd); osmo_ares_reschedule(sgsn); } diff --git a/src/gtphub/gtphub_main.c b/src/gtphub/gtphub_main.c index 664c801e..a9a7529c 100644 --- a/src/gtphub/gtphub_main.c +++ b/src/gtphub/gtphub_main.c @@ -95,11 +95,11 @@ void log_cfg(struct gtphub_cfg *cfg) } } -static void signal_handler(int signal) +static void signal_handler(int signum) { - fprintf(stdout, "signal %d received\n", signal); + fprintf(stdout, "signal %d received\n", signum); - switch (signal) { + switch (signum) { case SIGINT: case SIGTERM: osmo_signal_dispatch(SS_L_GLOBAL, S_L_GLOBAL_SHUTDOWN, NULL); @@ -107,8 +107,16 @@ static void signal_handler(int signal) exit(0); break; case SIGABRT: - /* in case of abort, we want to obtain a talloc report - * and then return to the caller, who will abort the process */ + /* in case of abort, we want to obtain a talloc report and + * then run default SIGABRT handler, who will generate coredump + * and abort the process. abort() should do this for us after we + * return, but program wouldn't exit if an external SIGABRT is + * received. + */ + talloc_report_full(osmo_gtphub_ctx, stderr); + signal(SIGABRT, SIG_DFL); + raise(SIGABRT); + break; case SIGUSR1: case SIGUSR2: talloc_report_full(osmo_gtphub_ctx, stderr); @@ -118,44 +126,12 @@ static void signal_handler(int signal) } } -#if BUILD_IU -int gtphub_vty_go_parent(struct vty *vty) -{ - switch (vty->node) { - default: - osmo_ss7_vty_go_parent(vty); - } - - return vty->node; -} -#endif - -int gtphub_vty_is_config_node(struct vty *vty, int node) -{ - /* Check if libosmo-sccp declares the node in - * question as config node */ -#if BUILD_IU - if (osmo_ss7_is_config_node(vty, node)) - return 1; -#endif - - switch (node) { - /* add items that are not config */ - case CONFIG_NODE: - return 0; - - default: - return 1; - } -} - static struct vty_app_info vty_info = { .name = "OsmoGTPhub", .version = PACKAGE_VERSION, #if BUILD_IU - .go_parent_cb = gtphub_vty_go_parent, + .go_parent_cb = osmo_ss7_vty_go_parent, #endif - .is_config_node = gtphub_vty_is_config_node, }; struct cmdline_cfg { diff --git a/src/sgsn/gprs_gb.c b/src/sgsn/gprs_gb.c index d470cfab..c7d5c28b 100644 --- a/src/sgsn/gprs_gb.c +++ b/src/sgsn/gprs_gb.c @@ -25,6 +25,9 @@ #include <osmocom/gprs/gprs_msgb.h> #include <osmocom/gprs/gprs_bssgp.h> +#include <osmocom/gprs/gprs_ns2.h> +#include <osmocom/gprs/gprs_bssgp_bss.h> +#include <osmocom/sgsn/gprs_llc.h> #include "bscconfig.h" @@ -103,3 +106,83 @@ int gprs_gb_page_ps_ra(struct sgsn_mm_ctx *mmctx) return rc; } + +/* called by the bssgp layer to send NS PDUs */ +int gprs_gb_send_cb(void *ctx, struct msgb *msg) +{ + struct gprs_ns2_inst *nsi = (struct gprs_ns2_inst *) ctx; + struct osmo_gprs_ns2_prim nsp = {}; + nsp.nsei = msgb_nsei(msg); + nsp.bvci = msgb_bvci(msg); + osmo_prim_init(&nsp.oph, SAP_NS, PRIM_NS_UNIT_DATA, PRIM_OP_REQUEST, msg); + return gprs_ns2_recv_prim(nsi, &nsp.oph); +} + +void gprs_ns_prim_status_cb(struct osmo_gprs_ns2_prim *nsp) +{ + switch (nsp->u.status.cause) { + case NS_AFF_CAUSE_SNS_CONFIGURED: + LOGP(DGPRS, LOGL_NOTICE, "NS-E %d SNS configured.\n", nsp->nsei); + break; + case NS_AFF_CAUSE_RECOVERY: + LOGP(DGPRS, LOGL_NOTICE, "NS-E %d became available\n", nsp->nsei); + /* workaround for broken BSS which doesn't respond correct to BSSGP status message. + * Sent a BSSGP Reset when a persistent NSVC comes up for the first time. */ + if (nsp->u.status.first && nsp->u.status.persistent) { + struct bssgp_bvc_ctx bctx = { + .nsei = nsp->nsei, + }; + bssgp_tx_bvc_reset2(&bctx, BVCI_SIGNALLING, BSSGP_CAUSE_EQUIP_FAIL, false); + } + break; + case NS_AFF_CAUSE_FAILURE: + LOGP(DGPRS, LOGL_NOTICE, "NS-E %d became unavailable\n", nsp->nsei); + break; + default: + LOGP(DGPRS, LOGL_NOTICE, "NS: %s Unknown prim %d from NS\n", + get_value_string(osmo_prim_op_names, nsp->oph.operation), nsp->oph.primitive); + break; + } +} + +/* call-back function for the NS protocol */ +int gprs_ns_prim_cb(struct osmo_prim_hdr *oph, void *ctx) +{ + struct osmo_gprs_ns2_prim *nsp; + int rc = 0; + + if (oph->sap != SAP_NS) + return 0; + + nsp = container_of(oph, struct osmo_gprs_ns2_prim, oph); + + if (oph->operation != PRIM_OP_INDICATION) { + LOGP(DGPRS, LOGL_NOTICE, "NS: %s Unknown prim %d from NS\n", + get_value_string(osmo_prim_op_names, oph->operation), + oph->operation); + return 0; + } + + switch (oph->primitive) { + case PRIM_NS_UNIT_DATA: + /* hand the message into the BSSGP implementation */ + /* add required msg fields for Gb layer */ + msgb_bssgph(oph->msg) = oph->msg->l3h; + msgb_bvci(oph->msg) = nsp->bvci; + msgb_nsei(oph->msg) = nsp->nsei; + rc = bssgp_rcvmsg(oph->msg); + break; + case PRIM_NS_STATUS: + gprs_ns_prim_status_cb(nsp); + break; + default: + LOGP(DGPRS, LOGL_NOTICE, "NS: %s Unknown prim %d from NS\n", + get_value_string(osmo_prim_op_names, oph->operation), oph->primitive); + break; + } + + if (oph->msg) + msgb_free(oph->msg); + + return rc; +} diff --git a/src/sgsn/gprs_gmm.c b/src/sgsn/gprs_gmm.c index 0ad60037..2367338a 100644 --- a/src/sgsn/gprs_gmm.c +++ b/src/sgsn/gprs_gmm.c @@ -281,9 +281,11 @@ int gsm48_tx_gmm_att_ack(struct sgsn_mm_ctx *mm) struct gsm48_hdr *gh; struct gsm48_attach_ack *aa; unsigned long t; +#ifdef PTMSI_ALLOC struct osmo_mobile_identity mi; uint8_t *l; int rc; +#endif #if 0 uint8_t *ptsig; #endif @@ -340,6 +342,9 @@ int gsm48_tx_gmm_att_ack(struct sgsn_mm_ctx *mm) /* Optional: MS-identity (combined attach) */ /* Optional: GMM cause (partial attach result for combined attach) */ + /* Optional: Network feature support 10.5.5.23 */ + /* msgb_v_put(msg, GSM48_IE_GMM_NET_FEAT_SUPPORT | 0x00);*/ + return gsm48_gmm_sendmsg(msg, 0, mm, true); } @@ -922,9 +927,9 @@ int gsm48_gmm_authorize(struct sgsn_mm_ctx *ctx) ctx->t3350_mode = GMM_T3350_MODE_ATT; #else memset(&sig_data, 0, sizeof(sig_data)); - sig_data.mm = mmctx; + sig_data.mm = ctx; osmo_signal_dispatch(SS_SGSN, S_SGSN_ATTACH, &sig_data); - osmo_fsm_inst_dispatch(mm->gmm_fsm, E_GMM_ATTACH_SUCCESS, NULL); + osmo_fsm_inst_dispatch(ctx->gmm_fsm, E_GMM_ATTACH_SUCCESS, NULL); #endif return gsm48_tx_gmm_att_ack(ctx); @@ -1438,9 +1443,11 @@ static int gsm48_tx_gmm_ra_upd_ack(struct sgsn_mm_ctx *mm) struct gsm48_hdr *gh; struct gsm48_ra_upd_ack *rua; unsigned long t; +#ifdef PTMSI_ALLOC uint8_t *l; int rc; struct osmo_mobile_identity mi; +#endif rate_ctr_inc(&sgsn->rate_ctrs->ctr[CTR_GPRS_ROUTING_AREA_ACKED]); LOGMMCTXP(LOGL_INFO, mm, "<- ROUTING AREA UPDATE ACCEPT\n"); @@ -1533,7 +1540,10 @@ static void process_ms_ctx_status(struct sgsn_mm_ctx *mmctx, LOGMMCTXP(LOGL_NOTICE, mmctx, "Dropping PDP context for NSAPI=%u " "due to PDP CTX STATUS IE=0x%02x%02x\n", pdp->nsapi, pdp_status[1], pdp_status[0]); - sgsn_delete_pdp_ctx(pdp); + if (pdp->ggsn) + sgsn_delete_pdp_ctx(pdp); + else /* GTP side already detached, freeing */ + sgsn_pdp_ctx_free(pdp); } } @@ -1724,7 +1734,7 @@ static int gsm48_rx_gmm_ra_upd_req(struct sgsn_mm_ctx *mmctx, struct msgb *msg, mmctx_timer_start(mmctx, 3350); #else /* Make sure we are NORMAL (i.e. not SUSPENDED anymore) */ - osmo_fsm_inst_dispatch(mm->gmm_fsm, E_GMM_ATTACH_SUCCESS, NULL); + osmo_fsm_inst_dispatch(mmctx->gmm_fsm, E_GMM_ATTACH_SUCCESS, NULL); memset(&sig_data, 0, sizeof(sig_data)); sig_data.mm = mmctx; diff --git a/src/sgsn/gprs_mm_state_gb_fsm.c b/src/sgsn/gprs_mm_state_gb_fsm.c index 811f0c2f..d3f2ea32 100644 --- a/src/sgsn/gprs_mm_state_gb_fsm.c +++ b/src/sgsn/gprs_mm_state_gb_fsm.c @@ -68,6 +68,9 @@ static void st_mm_standby(struct osmo_fsm_inst *fi, uint32_t event, void *data) case E_MM_PDU_RECEPTION: mm_state_gb_fsm_state_chg(fi, ST_MM_READY); break; + case E_MM_IMPLICIT_DETACH: + mm_state_gb_fsm_state_chg(fi, ST_MM_IDLE); + break; } } @@ -86,7 +89,7 @@ static struct osmo_fsm_state mm_state_gb_fsm_states[] = { .action = st_mm_ready, }, [ST_MM_STANDBY] = { - .in_event_mask = X(E_MM_PDU_RECEPTION), + .in_event_mask = X(E_MM_PDU_RECEPTION) | X(E_MM_IMPLICIT_DETACH), .out_state_mask = X(ST_MM_IDLE) | X(ST_MM_READY), .name = "Standby", .action = st_mm_standby, diff --git a/src/sgsn/gprs_ranap.c b/src/sgsn/gprs_ranap.c index 7a334919..1f8ed97d 100644 --- a/src/sgsn/gprs_ranap.c +++ b/src/sgsn/gprs_ranap.c @@ -26,6 +26,7 @@ #include <osmocom/core/rate_ctr.h> #include <osmocom/core/tdef.h> +#include <osmocom/gprs/gprs_msgb.h> #include <osmocom/ranap/ranap_common.h> diff --git a/src/sgsn/gprs_sgsn.c b/src/sgsn/gprs_sgsn.c index 0b7c21e9..d4bc554c 100644 --- a/src/sgsn/gprs_sgsn.c +++ b/src/sgsn/gprs_sgsn.c @@ -27,7 +27,7 @@ #include <osmocom/core/rate_ctr.h> #include <osmocom/core/stats.h> #include <osmocom/core/backtrace.h> -#include <osmocom/gprs/gprs_ns.h> +#include <osmocom/gprs/gprs_ns2.h> #include <osmocom/gprs/gprs_bssgp.h> #include <osmocom/gsm/protocol/gsm_04_08_gprs.h> #include <osmocom/gsm/apn.h> diff --git a/src/sgsn/gprs_subscriber.c b/src/sgsn/gprs_subscriber.c index c23b332f..943fbc3d 100644 --- a/src/sgsn/gprs_subscriber.c +++ b/src/sgsn/gprs_subscriber.c @@ -870,6 +870,8 @@ struct gprs_subscr *gprs_subscr_get_or_create_by_mmctx(struct sgsn_mm_ctx *mmctx if (!subscr) { subscr = gprs_subscr_get_or_create(mmctx->imsi); + if (!subscr) + return NULL; subscr->flags |= GPRS_SUBSCRIBER_FIRST_CONTACT; subscr->flags &= ~GPRS_SUBSCRIBER_ENABLE_PURGE; } @@ -893,6 +895,8 @@ int gprs_subscr_request_update_location(struct sgsn_mm_ctx *mmctx) LOGMMCTXP(LOGL_DEBUG, mmctx, "Requesting subscriber data update\n"); subscr = gprs_subscr_get_or_create_by_mmctx(mmctx); + if (!subscr) + return -ENOMEM; subscr->flags |= GPRS_SUBSCRIBER_UPDATE_LOCATION_PENDING; @@ -918,6 +922,8 @@ int gprs_subscr_request_auth_info(struct sgsn_mm_ctx *mmctx, LOGMMCTXP(LOGL_DEBUG, mmctx, "Requesting subscriber authentication info\n"); subscr = gprs_subscr_get_or_create_by_mmctx(mmctx); + if (!subscr) + return -ENOMEM; subscr->flags |= GPRS_SUBSCRIBER_UPDATE_AUTH_INFO_PENDING; diff --git a/src/sgsn/sgsn_main.c b/src/sgsn/sgsn_main.c index 3044f95e..19039f69 100644 --- a/src/sgsn/sgsn_main.c +++ b/src/sgsn/sgsn_main.c @@ -39,8 +39,9 @@ #include <osmocom/core/rate_ctr.h> #include <osmocom/core/logging.h> #include <osmocom/core/stats.h> +#include <osmocom/core/sockaddr_str.h> -#include <osmocom/gprs/gprs_ns.h> +#include <osmocom/gprs/gprs_ns2.h> #include <osmocom/gprs/gprs_bssgp.h> #include <osmocom/gprs/gprs_bssgp_bss.h> @@ -60,6 +61,7 @@ #include <osmocom/sgsn/gprs_llc.h> #include <osmocom/sgsn/gprs_gmm.h> #include <osmocom/sgsn/gprs_ranap.h> +#include <osmocom/sgsn/gprs_gb.h> #include <osmocom/ctrl/control_if.h> #include <osmocom/ctrl/ports.h> @@ -80,7 +82,7 @@ void *tall_sgsn_ctx; struct ctrl_handle *g_ctrlh; -struct gprs_ns_inst *sgsn_nsi; +struct gprs_ns2_inst *sgsn_nsi; static int daemonize = 0; const char *openbsc_copyright = "Copyright (C) 2010 Harald Welte and On-Waves\r\n" @@ -94,27 +96,6 @@ const char *openbsc_copyright = struct sgsn_instance *sgsn; -/* call-back function for the NS protocol */ -static int sgsn_ns_cb(enum gprs_ns_evt event, struct gprs_nsvc *nsvc, - struct msgb *msg, uint16_t bvci) -{ - int rc = 0; - - switch (event) { - case GPRS_NS_EVT_UNIT_DATA: - /* hand the message into the BSSGP implementation */ - rc = bssgp_rcvmsg(msg); - break; - default: - LOGP(DGPRS, LOGL_ERROR, "SGSN: Unknown event %u from NS\n", event); - if (msg) - msgb_free(msg); - rc = -EIO; - break; - } - return rc; -} - /* call-back function for the BSSGP protocol */ int bssgp_prim_cb(struct osmo_prim_hdr *oph, void *ctx) { @@ -143,11 +124,11 @@ int bssgp_prim_cb(struct osmo_prim_hdr *oph, void *ctx) return 0; } -static void signal_handler(int signal) +static void signal_handler(int signum) { - fprintf(stdout, "signal %u received\n", signal); + fprintf(stdout, "signal %u received\n", signum); - switch (signal) { + switch (signum) { case SIGINT: case SIGTERM: osmo_signal_dispatch(SS_L_GLOBAL, S_L_GLOBAL_SHUTDOWN, NULL); @@ -155,8 +136,17 @@ static void signal_handler(int signal) exit(0); break; case SIGABRT: - /* in case of abort, we want to obtain a talloc report - * and then return to the caller, who will abort the process */ + /* in case of abort, we want to obtain a talloc report and + * then run default SIGABRT handler, who will generate coredump + * and abort the process. abort() should do this for us after we + * return, but program wouldn't exit if an external SIGABRT is + * received. + */ + talloc_report(tall_vty_ctx, stderr); + talloc_report_full(tall_sgsn_ctx, stderr); + signal(SIGABRT, SIG_DFL); + raise(SIGABRT); + break; case SIGUSR1: talloc_report(tall_vty_ctx, stderr); talloc_report_full(tall_sgsn_ctx, stderr); @@ -172,57 +162,12 @@ static void signal_handler(int signal) /* NSI that BSSGP uses when transmitting on NS */ extern struct gprs_ns_inst *bssgp_nsi; -int sgsn_vty_is_config_node(struct vty *vty, int node) -{ - /* So far the SGSN has no nested nodes that need parent node - * declaration, except for the ss7 vty nodes. */ - switch (node) { - case SGSN_NODE: - return 1; - default: -#if BUILD_IU - return osmo_ss7_is_config_node(vty, node); -#else - return 0; -#endif - } -} - -int sgsn_vty_go_parent(struct vty *vty) -{ - /* So far the SGSN has no nested nodes that need parent node - * declaration, except for the ss7 vty nodes. */ -#if BUILD_IU - return osmo_ss7_vty_go_parent(vty); -#else - vty->node = CONFIG_NODE; - vty->index = NULL; - return 0; -#endif -} - -static void bvc_reset_persistent_nsvcs(void) -{ - /* Send BVC-RESET on all persistent NSVCs */ - struct gprs_nsvc *nsvc; - - llist_for_each_entry(nsvc, &sgsn_nsi->gprs_nsvcs, list) { - struct bssgp_bvc_ctx bctx = { - .nsei = nsvc->nsei, - }; - if (!nsvc->persistent) - continue; - /* if it is not marked ALIVE, we cannot send any data over it. */ - nsvc->state |= NSE_S_ALIVE; - bssgp_tx_bvc_reset2(&bctx, BVCI_SIGNALLING, BSSGP_CAUSE_EQUIP_FAIL, false); - } -} - static struct vty_app_info vty_info = { .name = "OsmoSGSN", .version = PACKAGE_VERSION, - .go_parent_cb = sgsn_vty_go_parent, - .is_config_node = sgsn_vty_is_config_node, +#if BUILD_IU + .go_parent_cb = osmo_ss7_vty_go_parent, +#endif }; static void print_help(void) @@ -331,11 +276,6 @@ static struct log_info_cat gprs_categories[] = { .description = "GPRS Network Service (NS)", .enabled = 1, .loglevel = LOGL_NOTICE, }, - [DBSSGP] = { - .name = "DBSSGP", - .description = "GPRS BSS Gateway Protocol (BSSGP)", - .enabled = 1, .loglevel = LOGL_NOTICE, - }, [DLLC] = { .name = "DLLC", .description = "GPRS Logical Link Control Protocol (LLC)", @@ -388,6 +328,11 @@ static bool file_exists(const char *path) int main(int argc, char **argv) { int rc; + struct osmo_sockaddr_str bind_address = { + .af = AF_INET, + .ip = "0.0.0.0", + .port = 23000, + }; #if BUILD_IU struct osmo_sccp_instance *sccp; #endif @@ -442,27 +387,27 @@ int main(int argc, char **argv) rate_ctr_init(tall_sgsn_ctx); - gprs_ns_set_log_ss(DNS); - bssgp_set_log_ss(DBSSGP); + logging_vty_add_deprecated_subsys(tall_sgsn_ctx, "bssgp"); - sgsn_nsi = gprs_ns_instantiate(&sgsn_ns_cb, tall_sgsn_ctx); + sgsn_nsi = gprs_ns2_instantiate(tall_sgsn_ctx, &gprs_ns_prim_cb, NULL); if (!sgsn_nsi) { LOGP(DGPRS, LOGL_ERROR, "Unable to instantiate NS\n"); exit(1); } - bssgp_nsi = sgsn->cfg.nsi = sgsn_nsi; + sgsn->cfg.nsi = sgsn_nsi; + bssgp_set_bssgp_callback(gprs_gb_send_cb, sgsn_nsi); gprs_llc_init("/usr/local/lib/osmocom/crypt/"); sgsn_rate_ctr_init(); sgsn_inst_init(sgsn); - gprs_ns_vty_init(bssgp_nsi); + + gprs_ns2_vty_init(sgsn_nsi, &bind_address); bssgp_vty_init(); gprs_llc_vty_init(); gprs_sndcp_vty_init(); sgsn_auth_init(sgsn); sgsn_cdr_init(sgsn); - /* FIXME: register signal handler for SS_L_NS */ rc = sgsn_parse_config(sgsn->config_file); if (rc < 0) { @@ -504,18 +449,13 @@ int main(int argc, char **argv) exit(2); } - rc = gprs_ns_nsip_listen(sgsn_nsi); + rc = gprs_ns2_vty_create(); if (rc < 0) { LOGP(DGPRS, LOGL_FATAL, "Cannot bind/listen on NSIP socket\n"); exit(2); } - rc = gprs_ns_frgre_listen(sgsn_nsi); - if (rc < 0) { - LOGP(DGPRS, LOGL_FATAL, "Cannot bind/listen GRE " - "socket. Do you have CAP_NET_RAW?\n"); - exit(2); - } + gprs_ns2_dynamic_create_nse(sgsn_nsi, true); if (sgsn->cfg.dynamic_lookup) { if (sgsn_ares_init(sgsn) != 0) { @@ -542,8 +482,6 @@ int main(int argc, char **argv) ranap_iu_init(tall_sgsn_ctx, DRANAP, "OsmoSGSN-IuPS", sccp, gsm0408_gprs_rcvmsg_iu, sgsn_ranap_iu_event); #endif - bvc_reset_persistent_nsvcs(); - if (daemonize) { rc = osmo_daemonize(); if (rc < 0) { diff --git a/src/sgsn/sgsn_vty.c b/src/sgsn/sgsn_vty.c index 33a652c9..d7584bcb 100644 --- a/src/sgsn/sgsn_vty.c +++ b/src/sgsn/sgsn_vty.c @@ -34,7 +34,7 @@ #include <osmocom/sgsn/debug.h> #include <osmocom/sgsn/sgsn.h> -#include <osmocom/gprs/gprs_ns.h> +#include <osmocom/gprs/gprs_ns2.h> #include <osmocom/sgsn/gprs_gmm.h> #include <osmocom/sgsn/gprs_sgsn.h> #include <osmocom/sgsn/vty.h> @@ -1020,6 +1020,10 @@ DEFUN(update_subscr_create, update_subscr_create_cmd, } subscr = gprs_subscr_get_or_create(imsi); + if (!subscr) { + vty_out(vty, "Can not create subscriber. Out of memory.%s", imsi); + return CMD_WARNING; + } subscr->keep_in_ram = 1; gprs_subscr_put(subscr); diff --git a/tests/Makefile.am b/tests/Makefile.am index a23d9317..32ed4725 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -1,6 +1,5 @@ SUBDIRS = \ gprs \ - gbproxy \ gtphub \ sgsn \ xid \ @@ -33,7 +32,9 @@ EXTRA_DIST = \ $(TESTSUITE) \ vty_test_runner.py \ ctrl_test_runner.py \ - test_nodes.vty \ + osmo-sgsn_test-nodes.vty \ + osmo-gbproxy_test-nodes.vty \ + osmo-gbproxy-pool_test-nodes.vty \ $(NULL) TESTSUITE = $(srcdir)/testsuite @@ -62,9 +63,17 @@ vty-python-test: $(BUILT_SOURCES) # make vty-transcript-test U=-u vty-transcript-test: osmo_verify_transcript_vty.py -v \ + -n OsmoGbProxy -p 4246 \ + -r "$(top_builddir)/src/gbproxy/osmo-gbproxy -c $(top_srcdir)/doc/examples/osmo-gbproxy/osmo-gbproxy.cfg" \ + $(U) $${T:-$(srcdir)/osmo-gbproxy_test-nodes.vty} + osmo_verify_transcript_vty.py -v \ + -n OsmoGbProxy -p 4246 \ + -r "$(top_builddir)/src/gbproxy/osmo-gbproxy -c $(top_srcdir)/doc/examples/osmo-gbproxy/osmo-gbproxy-pool.cfg" \ + $(U) $${T:-$(srcdir)/osmo-gbproxy-pool_test-nodes.vty} + osmo_verify_transcript_vty.py -v \ -n OsmoSGSN -p 4245 \ -r "$(top_builddir)/src/sgsn/osmo-sgsn -c $(top_srcdir)/doc/examples/osmo-sgsn/osmo-sgsn.cfg" \ - $(U) $${T:-$(srcdir)/*.vty} + $(U) $${T:-$(srcdir)/osmo-sgsn*.vty} rm -f $(builddir)/sms.db $(builddir)/gsn_restart # don't run multiple tests concurrently so that the ports don't conflict diff --git a/tests/gbproxy/Makefile.am b/tests/gbproxy/Makefile.am deleted file mode 100644 index b9585acc..00000000 --- a/tests/gbproxy/Makefile.am +++ /dev/null @@ -1,51 +0,0 @@ -AM_CPPFLAGS = \ - $(all_includes) \ - -I$(top_srcdir)/include \ - $(NULL) - -AM_CFLAGS = \ - -Wall \ - -ggdb3 \ - $(LIBOSMOCORE_CFLAGS) \ - $(LIBOSMOGSM_CFLAGS) \ - $(LIBOSMOABIS_CFLAGS) \ - $(NULL) - -AM_LDFLAGS = \ - $(COVERAGE_LDFLAGS) \ - $(NULL) - -EXTRA_DIST = \ - gbproxy_test.ok \ - $(NULL) - -noinst_PROGRAMS = \ - gbproxy_test \ - $(NULL) - -gbproxy_test_SOURCES = \ - gbproxy_test.c \ - $(NULL) - -gbproxy_test_LDFLAGS = \ - -Wl,--wrap=osmo_get_rand_id \ - $(NULL) - -gbproxy_test_LDADD = \ - $(top_builddir)/src/gbproxy/gb_proxy.o \ - $(top_builddir)/src/gbproxy/gb_proxy_patch.o \ - $(top_builddir)/src/gbproxy/gb_proxy_peer.o \ - $(top_builddir)/src/gbproxy/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 \ - $(LIBOSMOCORE_LIBS) \ - $(LIBOSMOGB_LIBS) \ - $(LIBOSMOGSM_LIBS) \ - $(LIBOSMOVTY_LIBS) \ - $(LIBOSMOABIS_LIBS) \ - $(LIBRARY_DL) \ - $(LIBRARY_DLSYM) \ - -lrt \ - $(NULL) diff --git a/tests/gbproxy/gbproxy_test.c b/tests/gbproxy/gbproxy_test.c deleted file mode 100644 index 6433eb60..00000000 --- a/tests/gbproxy/gbproxy_test.c +++ /dev/null @@ -1,5082 +0,0 @@ -/* test routines for gbproxy - * send NS messages to the gbproxy and dumps what happens - * (C) 2013 by sysmocom s.f.m.c. GmbH - * Author: Jacob Erlbeck <jerlbeck@sysmocom.de> - */ - -#undef _GNU_SOURCE -#define _GNU_SOURCE - -#include <stdio.h> -#include <stdlib.h> -#include <stdint.h> -#include <string.h> -#include <getopt.h> -#include <dlfcn.h> -#include <time.h> -#include <sys/types.h> -#include <sys/socket.h> - -#include <osmocom/core/msgb.h> -#include <osmocom/core/application.h> -#include <osmocom/core/utils.h> -#include <osmocom/core/logging.h> -#include <osmocom/core/talloc.h> -#include <osmocom/core/signal.h> -#include <osmocom/core/rate_ctr.h> -#include <osmocom/gsm/tlv.h> -#include <osmocom/gsm/gsm_utils.h> -#include <osmocom/gsm/protocol/gsm_04_08_gprs.h> -#include <osmocom/gprs/gprs_msgb.h> -#include <osmocom/gprs/gprs_ns.h> -#include <osmocom/gprs/gprs_bssgp.h> - -#include <osmocom/sgsn/gb_proxy.h> -#include <osmocom/sgsn/gprs_utils.h> -#include <osmocom/sgsn/gprs_llc.h> -#include <osmocom/sgsn/gprs_gb_parse.h> -#include <osmocom/sgsn/debug.h> - -#define REMOTE_BSS_ADDR 0x01020304 -#define REMOTE_SGSN_ADDR 0x05060708 - -#define SGSN_NSEI 0x0100 - -#define REMOTE_SGSN2_ADDR 0x15161718 -#define SGSN2_NSEI 0x0102 - -#define MATCH_ANY (-1) - -void *tall_sgsn_ctx = NULL; - -struct gbproxy_config gbcfg = {0}; - -struct llist_head *received_messages = NULL; - -/* override, requires '-Wl,--wrap=osmo_get_rand_id' */ -int __real_osmo_get_rand_id(uint8_t *data, size_t len); -int mock_osmo_get_rand_id(uint8_t *data, size_t len); -int (*osmo_get_rand_id_cb)(uint8_t *, size_t) = - &mock_osmo_get_rand_id; - -int __wrap_osmo_get_rand_id(uint8_t *buf, size_t num) -{ - return (*osmo_get_rand_id_cb)(buf, num); -} - -static int rand_seq_num = 0; -int mock_osmo_get_rand_id(uint8_t *buf, size_t num) -{ - uint32_t val; - - OSMO_ASSERT(num == sizeof(val)); - - val = 0x00dead00 + rand_seq_num; - - rand_seq_num++; - - memcpy(buf, &val, num); - - return 1; -} - -static void cleanup_test() -{ - rand_seq_num = 0; -} - -static int dump_global(FILE *stream, int indent) -{ - unsigned int i; - const struct rate_ctr_group_desc *desc; - int rc; - - rc = fprintf(stream, "%*sGbproxy global:\n", indent, ""); - if (rc < 0) - return rc; - - desc = gbcfg.ctrg->desc; - - for (i = 0; i < desc->num_ctr; i++) { - struct rate_ctr *ctr = &gbcfg.ctrg->ctr[i]; - if (ctr->current) { - rc = fprintf(stream, "%*s %s: %llu\n", - indent, "", - desc->ctr_desc[i].description, - (long long)ctr->current); - - if (rc < 0) - return rc; - } - } - - return 0; -} - -static int dump_peers(FILE *stream, int indent, time_t now, - struct gbproxy_config *cfg) -{ - struct gbproxy_peer *peer; - struct gprs_ra_id raid; - unsigned int i; - const struct rate_ctr_group_desc *desc; - int rc; - - rc = fprintf(stream, "%*sPeers:\n", indent, ""); - if (rc < 0) - return rc; - - llist_for_each_entry(peer, &cfg->bts_peers, list) { - struct gbproxy_link_info *link_info; - struct gbproxy_patch_state *state = &peer->patch_state; - gsm48_parse_ra(&raid, peer->ra); - - rc = fprintf(stream, "%*s NSEI %u, BVCI %u, %sblocked, RAI %s\n", - indent, "", - peer->nsei, peer->bvci, - peer->blocked ? "" : "not ", - osmo_rai_name(&raid)); - - if (rc < 0) - return rc; - - desc = peer->ctrg->desc; - - for (i = 0; i < desc->num_ctr; i++) { - struct rate_ctr *ctr = &peer->ctrg->ctr[i]; - if (ctr->current) { - rc = fprintf(stream, "%*s %s: %llu\n", - indent, "", - desc->ctr_desc[i].description, - (long long)ctr->current); - - if (rc < 0) - return rc; - } - } - - fprintf(stream, "%*s TLLI-Cache: %d\n", - indent, "", state->logical_link_count); - llist_for_each_entry(link_info, &state->logical_links, list) { - struct osmo_mobile_identity mi; - const char *imsi_str; - time_t age = now ? now - link_info->timestamp : 0; - int stored_msgs = 0; - struct llist_head *iter; - enum gbproxy_match_id match_id; - llist_for_each(iter, &link_info->stored_msgs) - stored_msgs++; - - if (link_info->imsi > 0) { - if (osmo_mobile_identity_decode(&mi, link_info->imsi, link_info->imsi_len, false) - || mi.type != GSM_MI_TYPE_IMSI) - imsi_str = "(invalid)"; - else - imsi_str = mi.imsi; - } else { - imsi_str = "(none)"; - } - fprintf(stream, "%*s TLLI %08x", - indent, "", link_info->tlli.current); - if (link_info->tlli.assigned) - fprintf(stream, "/%08x", link_info->tlli.assigned); - if (link_info->sgsn_tlli.current) { - fprintf(stream, " -> %08x", - link_info->sgsn_tlli.current); - if (link_info->sgsn_tlli.assigned) - fprintf(stream, "/%08x", - link_info->sgsn_tlli.assigned); - } - fprintf(stream, ", IMSI %s, AGE %d", - imsi_str, (int)age); - - if (stored_msgs) - fprintf(stream, ", STORED %d", stored_msgs); - - for (match_id = 0; match_id < ARRAY_SIZE(cfg->matches); - ++match_id) { - if (cfg->matches[match_id].enable && - link_info->is_matching[match_id]) { - fprintf(stream, ", IMSI matches"); - break; - } - } - - if (link_info->imsi_acq_pending) - fprintf(stream, ", IMSI acquisition in progress"); - - if (cfg->route_to_sgsn2) - fprintf(stream, ", SGSN NSEI %d", - link_info->sgsn_nsei); - - if (link_info->is_deregistered) - fprintf(stream, ", DE-REGISTERED"); - - rc = fprintf(stream, "\n"); - if (rc < 0) - return rc; - } - } - - return 0; -} - -const uint8_t *convert_ra(struct gprs_ra_id *raid) -{ - static struct gsm48_ra_id r; - gsm48_encode_ra(&r, raid); - return (const uint8_t *)&r; -} - -/* DTAP - Attach Request */ -static const unsigned char dtap_attach_req[] = { - 0x08, 0x01, 0x02, 0xf5, 0xe0, 0x21, 0x08, 0x02, - 0x05, 0xf4, 0xfb, 0xc5, 0x46, 0x79, 0x11, 0x22, - 0x33, 0x40, 0x50, 0x60, 0x19, 0x18, 0xb3, 0x43, - 0x2b, 0x25, 0x96, 0x62, 0x00, 0x60, 0x80, 0x9a, - 0xc2, 0xc6, 0x62, 0x00, 0x60, 0x80, 0xba, 0xc8, - 0xc6, 0x62, 0x00, 0x60, 0x80, 0x00, -}; - -/* DTAP - Attach Request (invalid RAI) */ -static const unsigned char dtap_attach_req2[] = { - 0x08, 0x01, 0x02, 0xf5, 0xe0, 0x21, 0x08, 0x02, - 0x05, 0xf4, 0xfb, 0x00, 0xbe, 0xef, 0x99, 0x99, - 0x99, 0x40, 0x50, 0x60, 0x19, 0x18, 0xb3, 0x43, - 0x2b, 0x25, 0x96, 0x62, 0x00, 0x60, 0x80, 0x9a, - 0xc2, 0xc6, 0x62, 0x00, 0x60, 0x80, 0xba, 0xc8, - 0xc6, 0x62, 0x00, 0x60, 0x80, 0x00, -}; - -/* DTAP - Attach Request (P-TMSI 0x3f32b700) */ -static const unsigned char dtap_attach_req3[] = { - 0x08, 0x01, 0x02, 0xf5, 0xe0, 0x21, 0x08, 0x02, - 0x05, 0xf4, 0xef, 0xe2, 0xb7, 0x00, 0x11, 0x22, - 0x33, 0x40, 0x50, 0x60, 0x19, 0x18, 0xb3, 0x43, - 0x2b, 0x25, 0x96, 0x62, 0x00, 0x60, 0x80, 0x9a, - 0xc2, 0xc6, 0x62, 0x00, 0x60, 0x80, 0xba, 0xc8, - 0xc6, 0x62, 0x00, 0x60, 0x80, 0x00, -}; - -/* DTAP - Attach Request (IMSI 12131415161718) */ -static const unsigned char dtap_attach_req4[] = { - 0x08, 0x01, 0x02, 0xf5, 0xe0, 0x21, 0x08, 0x02, - 0x08, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, - 0xf8, 0x11, 0x22, 0x33, 0x40, 0x50, 0x60, 0x19, - 0x18, 0xb3, 0x43, 0x2b, 0x25, 0x96, 0x62, 0x00, - 0x60, 0x80, 0x9a, 0xc2, 0xc6, 0x62, 0x00, 0x60, - 0x80, 0xba, 0xc8, 0xc6, 0x62, 0x00, 0x60, 0x80, - 0x00, -}; - -/* DTAP - Identity Request */ -static const unsigned char dtap_identity_req[] = { - 0x08, 0x15, 0x01 -}; - -/* DTAP - Identity Response */ -static const unsigned char dtap_identity_resp[] = { - 0x08, 0x16, 0x08, 0x11, 0x12, 0x13, 0x14, 0x15, - 0x16, 0x17, 0xf8 -}; - -/* DTAP - Identity Response, IMSI 2 */ -static const unsigned char dtap_identity2_resp[] = { - 0x08, 0x16, 0x08, 0x11, 0x12, 0x99, 0x99, 0x99, - 0x16, 0x17, 0xf8 -}; - -/* DTAP - Identity Response, IMSI 3 */ -static const unsigned char dtap_identity3_resp[] = { - 0x08, 0x16, 0x08, 0x11, 0x12, 0x99, 0x99, 0x99, - 0x26, 0x27, 0xf8 -}; - -/* DTAP - Attach Accept */ -static const unsigned char dtap_attach_acc[] = { - 0x08, 0x02, 0x01, 0x49, 0x04, 0x21, 0x63, 0x54, - 0x40, 0x50, 0x60, 0x19, 0xcd, 0xd7, 0x08, 0x17, - 0x16, 0x18, 0x05, 0xf4, 0xef, 0xe2, 0xb7, 0x00 -}; - -/* DTAP - Attach Accept, P-TMSI 2 */ -static const unsigned char dtap_attach_acc2[] = { - 0x08, 0x02, 0x01, 0x49, 0x04, 0x21, 0x63, 0x54, - 0x40, 0x50, 0x60, 0x19, 0xcd, 0xd7, 0x08, 0x17, - 0x16, 0x18, 0x05, 0xf4, 0xe0, 0x98, 0x76, 0x54 -}; - -/* DTAP - Attach Complete */ -static const unsigned char dtap_attach_complete[] = { - 0x08, 0x03 -}; - -/* DTAP - Attach Reject (GPRS services not allowed) */ -static const unsigned char dtap_attach_rej7[] = { - 0x08, 0x04, 0x07 -}; - -/* DTAP - GMM Information */ -static const unsigned char dtap_gmm_information[] = { - 0x08, 0x21 -}; - -/* DTAP - Routing Area Update Request */ -static const unsigned char dtap_ra_upd_req[] = { - 0x08, 0x08, 0x10, 0x11, 0x22, 0x33, 0x40, 0x50, - 0x60, 0x1d, 0x19, 0x13, 0x42, 0x33, 0x57, 0x2b, - 0xf7, 0xc8, 0x48, 0x02, 0x13, 0x48, 0x50, 0xc8, - 0x48, 0x02, 0x14, 0x48, 0x50, 0xc8, 0x48, 0x02, - 0x17, 0x49, 0x10, 0xc8, 0x48, 0x02, 0x00, 0x19, - 0x8b, 0xb2, 0x92, 0x17, 0x16, 0x27, 0x07, 0x04, - 0x31, 0x02, 0xe5, 0xe0, 0x32, 0x02, 0x20, 0x00 -}; - -/* DTAP - Routing Area Update Accept */ -static const unsigned char dtap_ra_upd_acc[] = { - 0x08, 0x09, 0x00, 0x49, 0x21, 0x63, 0x54, - 0x40, 0x50, 0x60, 0x19, 0x54, 0xab, 0xb3, 0x18, - 0x05, 0xf4, 0xef, 0xe2, 0xb7, 0x00, 0x17, 0x16, -}; - -/* DTAP - Routing Area Update Accept, P-TMSI 2 */ -static const unsigned char dtap_ra_upd_acc2[] = { - 0x08, 0x09, 0x00, 0x49, 0x21, 0x63, 0x54, - 0x40, 0x50, 0x60, 0x19, 0x54, 0xab, 0xb3, 0x18, - 0x05, 0xf4, 0xe0, 0x98, 0x76, 0x54, 0x17, 0x16, -}; - -/* DTAP - Routing Area Update Accept, P-TMSI 3 */ -static const unsigned char dtap_ra_upd_acc3[] = { - 0x08, 0x09, 0x00, 0x49, 0x21, 0x63, 0x54, - 0x40, 0x50, 0x60, 0x19, 0x54, 0xab, 0xb3, 0x18, - 0x05, 0xf4, 0xe0, 0x54, 0x32, 0x10, 0x17, 0x16, -}; - -/* DTAP - Routing Area Update Complete */ -static const unsigned char dtap_ra_upd_complete[] = { - 0x08, 0x0a -}; - -/* DTAP - Routing Area Update Reject */ -/* cause = 10 ("Implicitly detached"), force_standby = 0 */ -static const unsigned char dtap_ra_upd_rej[] = { - 0x08, 0x0b, 0x0a, 0x00, -}; - -/* DTAP - Activate PDP Context Request */ -static const unsigned char dtap_act_pdp_ctx_req[] = { - 0x0a, 0x41, 0x05, 0x03, 0x0c, 0x00, - 0x00, 0x1f, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x02, 0x01, 0x21, 0x28, 0x03, - 0x02, 0x61, 0x62, 0x27, 0x14, 0x80, 0x80, 0x21, - 0x10, 0x01, 0x00, 0x00, 0x10, 0x81, 0x06, 0x00, - 0x00, 0x00, 0x00, 0x83, 0x06, 0x00, 0x00, 0x00, - 0x00 -}; - -/* DTAP - Detach Request (MO) */ -/* normal detach, power_off = 1 */ -static const unsigned char dtap_detach_po_req[] = { - 0x08, 0x05, 0x09, 0x18, 0x05, 0xf4, 0xef, 0xe2, - 0xb7, 0x00, 0x19, 0x03, 0xb9, 0x97, 0xcb -}; - -/* DTAP - Detach Request (MO) */ -/* normal detach, power_off = 0 */ -static const unsigned char dtap_detach_req[] = { - 0x08, 0x05, 0x01, 0x18, 0x05, 0xf4, 0xef, 0xe2, - 0xb7, 0x00, 0x19, 0x03, 0xb9, 0x97, 0xcb -}; - -/* DTAP - Detach Accept (MO) */ -static const unsigned char dtap_detach_acc[] = { - 0x08, 0x06, 0x00 -}; - -/* DTAP - Detach Request (MT) */ -/* normal detach, reattach required, implicitly detached */ -static const unsigned char dtap_mt_detach_rea_req[] = { - 0x08, 0x05, 0x01, 0x25, 0x0a -}; - -/* DTAP - Detach Request (MT) */ -/* normal detach, reattach not required, implicitly detached */ -static const unsigned char dtap_mt_detach_req[] = { - 0x08, 0x05, 0x02, 0x25, 0x0a -}; - -/* DTAP - Detach Accept (MT) */ -static const unsigned char dtap_mt_detach_acc[] = { - 0x08, 0x06 -}; - -/* GPRS-LLC - SAPI: LLGMM, U, XID */ -static const unsigned char llc_u_xid_ul[] = { - 0x41, 0xfb, 0x01, 0x00, 0x0e, 0x00, 0x64, 0x11, - 0x05, 0x16, 0x01, 0x90, 0x66, 0xb3, 0x28 -}; - -/* GPRS-LLC - SAPI: LLGMM, U, XID */ -static const unsigned char llc_u_xid_dl[] = { - 0x41, 0xfb, 0x30, 0x84, 0x10, 0x61, 0xb6, 0x64, - 0xe4, 0xa9, 0x1a, 0x9e -}; - -/* GPRS-LLC - SAPI: LL11, UI, NSAPI 5, DNS query */ -static const unsigned char llc_ui_ll11_dns_query_ul[] = { - 0x0b, 0xc0, 0x01, 0x65, 0x00, 0x00, 0x00, 0x45, - 0x00, 0x00, 0x38, 0x95, 0x72, 0x00, 0x00, 0x45, - 0x11, 0x20, 0x85, 0x0a, 0xc0, 0x07, 0xe4, 0xac, - 0x10, 0x01, 0x0a, 0xad, 0xab, 0x00, 0x35, 0x00, - 0x24, 0x0e, 0x1c, 0x3b, 0xe0, 0x01, 0x00, 0x00, - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, - 0x6d, 0x05, 0x68, 0x65, 0x69, 0x73, 0x65, 0x02, - 0x64, 0x65, 0x00, 0x00, 0x01, 0x00, 0x01, 0x47, - 0x8f, 0x07 -}; - -/* GPRS-LLC - SAPI: LL11, UI, NSAPI 5, DNS query */ -static const unsigned char llc_ui_ll11_dns_resp_dl[] = { - 0x4b, 0xc0, 0x01, 0x65, 0x00, 0x00, 0x00, 0x45, - 0x00, 0x00, 0xc6, 0x00, 0x00, 0x40, 0x00, 0x3e, - 0x11, 0x7c, 0x69, 0xac, 0x10, 0x01, 0x0a, 0x0a, - 0xc0, 0x07, 0xe4, 0x00, 0x35, 0xad, 0xab, 0x00, - 0xb2, 0x74, 0x4e, 0x3b, 0xe0, 0x81, 0x80, 0x00, - 0x01, 0x00, 0x01, 0x00, 0x05, 0x00, 0x00, 0x01, - 0x6d, 0x05, 0x68, 0x65, 0x69, 0x73, 0x65, 0x02, - 0x64, 0x65, 0x00, 0x00, 0x01, 0x00, 0x01, 0xc0, - 0x0c, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x0e, - 0x10, 0x00, 0x04, 0xc1, 0x63, 0x90, 0x58, 0xc0, - 0x0e, 0x00, 0x02, 0x00, 0x01, 0x00, 0x00, 0x0e, - 0x10, 0x00, 0x16, 0x03, 0x6e, 0x73, 0x32, 0x0c, - 0x70, 0x6f, 0x70, 0x2d, 0x68, 0x61, 0x6e, 0x6e, - 0x6f, 0x76, 0x65, 0x72, 0x03, 0x6e, 0x65, 0x74, - 0x00, 0xc0, 0x0e, 0x00, 0x02, 0x00, 0x01, 0x00, - 0x00, 0x0e, 0x10, 0x00, 0x10, 0x02, 0x6e, 0x73, - 0x01, 0x73, 0x08, 0x70, 0x6c, 0x75, 0x73, 0x6c, - 0x69, 0x6e, 0x65, 0xc0, 0x14, 0xc0, 0x0e, 0x00, - 0x02, 0x00, 0x01, 0x00, 0x00, 0x0e, 0x10, 0x00, - 0x05, 0x02, 0x6e, 0x73, 0xc0, 0x0e, 0xc0, 0x0e, - 0x00, 0x02, 0x00, 0x01, 0x00, 0x00, 0x0e, 0x10, - 0x00, 0x05, 0x02, 0x6e, 0x73, 0xc0, 0x5f, 0xc0, - 0x0e, 0x00, 0x02, 0x00, 0x01, 0x00, 0x00, 0x0e, - 0x10, 0x00, 0x12, 0x02, 0x6e, 0x73, 0x0c, 0x70, - 0x6f, 0x70, 0x2d, 0x68, 0x61, 0x6e, 0x6e, 0x6f, - 0x76, 0x65, 0x72, 0xc0, 0x14, 0xaa, 0xdf, 0x31 -}; - -static int gprs_process_message(struct gprs_ns_inst *nsi, const char *text, - struct sockaddr_in *peer, const unsigned char* data, - size_t data_len); - -static void send_ns_reset(struct gprs_ns_inst *nsi, struct sockaddr_in *src_addr, - enum ns_cause cause, uint16_t nsvci, uint16_t nsei) -{ - /* GPRS Network Service, PDU type: NS_RESET, - */ - unsigned char msg[12] = { - 0x02, 0x00, 0x81, 0x01, 0x01, 0x82, 0x11, 0x22, - 0x04, 0x82, 0x11, 0x22 - }; - - msg[3] = cause; - msg[6] = nsvci / 256; - msg[7] = nsvci % 256; - msg[10] = nsei / 256; - msg[11] = nsei % 256; - - gprs_process_message(nsi, "RESET", src_addr, msg, sizeof(msg)); -} - -static void send_ns_reset_ack(struct gprs_ns_inst *nsi, struct sockaddr_in *src_addr, - uint16_t nsvci, uint16_t nsei) -{ - /* GPRS Network Service, PDU type: NS_RESET_ACK, - */ - unsigned char msg[9] = { - 0x03, 0x01, 0x82, 0x11, 0x22, - 0x04, 0x82, 0x11, 0x22 - }; - - msg[3] = nsvci / 256; - msg[4] = nsvci % 256; - msg[7] = nsei / 256; - msg[8] = nsei % 256; - - gprs_process_message(nsi, "RESET_ACK", src_addr, msg, sizeof(msg)); -} - -static void send_ns_alive(struct gprs_ns_inst *nsi, struct sockaddr_in *src_addr) -{ - /* GPRS Network Service, PDU type: NS_ALIVE */ - unsigned char msg[1] = { - 0x0a - }; - - gprs_process_message(nsi, "ALIVE", src_addr, msg, sizeof(msg)); -} - -static void send_ns_alive_ack(struct gprs_ns_inst *nsi, struct sockaddr_in *src_addr) -{ - /* GPRS Network Service, PDU type: NS_ALIVE_ACK */ - unsigned char msg[1] = { - 0x0b - }; - - gprs_process_message(nsi, "ALIVE_ACK", src_addr, msg, sizeof(msg)); -} - -static void send_ns_unblock(struct gprs_ns_inst *nsi, struct sockaddr_in *src_addr) -{ - /* GPRS Network Service, PDU type: NS_UNBLOCK */ - unsigned char msg[1] = { - 0x06 - }; - - gprs_process_message(nsi, "UNBLOCK", src_addr, msg, sizeof(msg)); -} - -static void send_ns_unblock_ack(struct gprs_ns_inst *nsi, struct sockaddr_in *src_addr) -{ - /* GPRS Network Service, PDU type: NS_UNBLOCK_ACK */ - unsigned char msg[1] = { - 0x07 - }; - - gprs_process_message(nsi, "UNBLOCK_ACK", src_addr, msg, sizeof(msg)); -} - -static void send_ns_unitdata(struct gprs_ns_inst *nsi, const char *text, - struct sockaddr_in *src_addr, uint16_t nsbvci, - const unsigned char *bssgp_msg, size_t bssgp_msg_size) -{ - /* GPRS Network Service, PDU type: NS_UNITDATA */ - unsigned char msg[4096] = { - 0x00, 0x00, 0x00, 0x00 - }; - - OSMO_ASSERT(bssgp_msg_size <= sizeof(msg) - 4); - - msg[2] = nsbvci / 256; - msg[3] = nsbvci % 256; - memcpy(msg + 4, bssgp_msg, bssgp_msg_size); - - gprs_process_message(nsi, text ? text : "UNITDATA", src_addr, msg, bssgp_msg_size + 4); -} - -static void send_bssgp_ul_unitdata( - struct gprs_ns_inst *nsi, const char *text, - struct sockaddr_in *src_addr, uint16_t nsbvci, uint32_t tlli, - struct gprs_ra_id *raid, uint16_t cell_id, - const uint8_t *llc_msg, size_t llc_msg_size) -{ - /* GPRS Network Service, PDU type: NS_UNITDATA */ - /* Base Station Subsystem GPRS Protocol: UL_UNITDATA */ - unsigned char msg[4096] = { - 0x01, /* TLLI */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, - 0x08, 0x88, /* RAI */ 0x11, 0x22, 0x33, 0x40, 0x50, 0x60, - /* CELL ID */ 0x00, 0x00, 0x00, 0x80, 0x0e, /* LLC LEN */ 0x00, 0x00, - }; - - size_t bssgp_msg_size = 23 + llc_msg_size; - - OSMO_ASSERT(bssgp_msg_size <= sizeof(msg)); - - gsm48_encode_ra((struct gsm48_ra_id *)(msg + 10), raid); - msg[1] = (uint8_t)(tlli >> 24); - msg[2] = (uint8_t)(tlli >> 16); - msg[3] = (uint8_t)(tlli >> 8); - msg[4] = (uint8_t)(tlli >> 0); - msg[16] = cell_id / 256; - msg[17] = cell_id % 256; - msg[21] = llc_msg_size / 256; - msg[22] = llc_msg_size % 256; - memcpy(msg + 23, llc_msg, llc_msg_size); - - send_ns_unitdata(nsi, text ? text : "BSSGP UL UNITDATA", - src_addr, nsbvci, msg, bssgp_msg_size); -} - -static void send_bssgp_dl_unitdata( - struct gprs_ns_inst *nsi, const char *text, - struct sockaddr_in *src_addr, uint16_t nsbvci, uint32_t tlli, - int with_racap_drx, const uint8_t *imsi, size_t imsi_size, - const uint8_t *llc_msg, size_t llc_msg_size) -{ - /* Base Station Subsystem GPRS Protocol: DL_UNITDATA */ - unsigned char msg[4096] = { - 0x00, /* TLLI */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x20, - 0x16, 0x82, 0x02, 0x58, - }; - unsigned char racap_drx[] = { - 0x13, 0x99, 0x18, 0xb3, 0x43, 0x2b, 0x25, 0x96, - 0x62, 0x00, 0x60, 0x80, 0x9a, 0xc2, 0xc6, 0x62, - 0x00, 0x60, 0x80, 0xba, 0xc8, 0xc6, 0x62, 0x00, - 0x60, 0x80, 0x00, 0x0a, 0x82, 0x08, 0x02 - }; - - size_t bssgp_msg_size = 0; - - OSMO_ASSERT(51 + imsi_size + llc_msg_size <= sizeof(msg)); - - msg[1] = (uint8_t)(tlli >> 24); - msg[2] = (uint8_t)(tlli >> 16); - msg[3] = (uint8_t)(tlli >> 8); - msg[4] = (uint8_t)(tlli >> 0); - - bssgp_msg_size = 12; - - if (with_racap_drx) { - memcpy(msg + bssgp_msg_size, racap_drx, sizeof(racap_drx)); - bssgp_msg_size += sizeof(racap_drx); - } - - if (imsi) { - OSMO_ASSERT(imsi_size <= 127); - msg[bssgp_msg_size] = BSSGP_IE_IMSI; - msg[bssgp_msg_size + 1] = 0x80 | imsi_size; - memcpy(msg + bssgp_msg_size + 2, imsi, imsi_size); - bssgp_msg_size += 2 + imsi_size; - } - - if ((bssgp_msg_size % 4) != 0) { - size_t abytes = (4 - (bssgp_msg_size + 2) % 4) % 4; - msg[bssgp_msg_size] = BSSGP_IE_ALIGNMENT; - msg[bssgp_msg_size + 1] = 0x80 | abytes; - memset(msg + bssgp_msg_size + 2, 0, abytes); - bssgp_msg_size += 2 + abytes; - } - - msg[bssgp_msg_size] = BSSGP_IE_LLC_PDU; - if (llc_msg_size < 128) { - msg[bssgp_msg_size + 1] = 0x80 | llc_msg_size; - bssgp_msg_size += 2; - } else { - msg[bssgp_msg_size + 1] = llc_msg_size / 256; - msg[bssgp_msg_size + 2] = llc_msg_size % 256; - bssgp_msg_size += 3; - } - memcpy(msg + bssgp_msg_size, llc_msg, llc_msg_size); - bssgp_msg_size += llc_msg_size; - - - send_ns_unitdata(nsi, text ? text : "BSSGP DL UNITDATA", - src_addr, nsbvci, msg, bssgp_msg_size); -} - -static void send_bssgp_reset(struct gprs_ns_inst *nsi, struct sockaddr_in *src_addr, - uint16_t bvci) -{ - /* GPRS Network Service, PDU type: NS_UNITDATA, BVCI 0 - * BSSGP RESET */ - unsigned char msg[18] = { - 0x22, 0x04, 0x82, 0x4a, - 0x2e, 0x07, 0x81, 0x08, 0x08, 0x88, 0x11, 0x22, - 0x33, 0x40, 0x50, 0x60, 0x10, 0x00 - }; - - msg[3] = bvci / 256; - msg[4] = bvci % 256; - - send_ns_unitdata(nsi, "BVC_RESET", src_addr, 0, msg, sizeof(msg)); -} - -static void send_bssgp_reset_ack(struct gprs_ns_inst *nsi, - struct sockaddr_in *src_addr, uint16_t bvci) -{ - /* GPRS Network Service, PDU type: NS_UNITDATA, BVCI 0 - * BSSGP RESET_ACK */ - static unsigned char msg[5] = { - 0x23, 0x04, 0x82, 0x00, - 0x00 - }; - - msg[3] = bvci / 256; - msg[4] = bvci % 256; - - send_ns_unitdata(nsi, "BVC_RESET_ACK", src_addr, 0, msg, sizeof(msg)); -} - -static void send_bssgp_suspend(struct gprs_ns_inst *nsi, - struct sockaddr_in *src_addr, - uint32_t tlli, - struct gprs_ra_id *raid) -{ - /* Base Station Subsystem GPRS Protocol, BSSGP SUSPEND */ - unsigned char msg[15] = { - 0x0b, 0x1f, 0x84, /* TLLI */ 0xff, 0xff, 0xff, 0xff, 0x1b, - 0x86, /* RAI */ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff - }; - - msg[3] = (uint8_t)(tlli >> 24); - msg[4] = (uint8_t)(tlli >> 16); - msg[5] = (uint8_t)(tlli >> 8); - msg[6] = (uint8_t)(tlli >> 0); - - gsm48_encode_ra((struct gsm48_ra_id *)(msg + 9), raid); - - send_ns_unitdata(nsi, "BVC_SUSPEND", src_addr, 0, msg, sizeof(msg)); -} - -static void send_bssgp_suspend_ack(struct gprs_ns_inst *nsi, - struct sockaddr_in *src_addr, - uint32_t tlli, - struct gprs_ra_id *raid) -{ - /* Base Station Subsystem GPRS Protocol, BSSGP SUSPEND ACK */ - unsigned char msg[18] = { - 0x0c, 0x1f, 0x84, /* TLLI */ 0xff, 0xff, 0xff, 0xff, 0x1b, - 0x86, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x1d, - 0x81, 0x01 - }; - - msg[3] = (uint8_t)(tlli >> 24); - msg[4] = (uint8_t)(tlli >> 16); - msg[5] = (uint8_t)(tlli >> 8); - msg[6] = (uint8_t)(tlli >> 0); - - gsm48_encode_ra((struct gsm48_ra_id *)(msg + 9), raid); - - send_ns_unitdata(nsi, "BVC_SUSPEND_ACK", src_addr, 0, msg, sizeof(msg)); -} - -static void send_bssgp_llc_discarded(struct gprs_ns_inst *nsi, - struct sockaddr_in *src_addr, - uint16_t bvci, uint32_t tlli, - unsigned n_frames, unsigned n_octets) -{ - /* Base Station Subsystem GPRS Protocol: LLC-DISCARDED (0x2c) */ - unsigned char msg[] = { - 0x2c, 0x1f, 0x84, /* TLLI */ 0xff, 0xff, 0xff, 0xff, 0x0f, - 0x81, /* n frames */ 0xff, 0x04, 0x82, /* BVCI */ 0xff, 0xff, 0x25, 0x83, - /* n octets */ 0xff, 0xff, 0xff - }; - - msg[3] = (uint8_t)(tlli >> 24); - msg[4] = (uint8_t)(tlli >> 16); - msg[5] = (uint8_t)(tlli >> 8); - msg[6] = (uint8_t)(tlli >> 0); - msg[9] = (uint8_t)(n_frames); - msg[12] = (uint8_t)(bvci >> 8); - msg[13] = (uint8_t)(bvci >> 0); - msg[16] = (uint8_t)(n_octets >> 16); - msg[17] = (uint8_t)(n_octets >> 8); - msg[18] = (uint8_t)(n_octets >> 0); - - send_ns_unitdata(nsi, "LLC_DISCARDED", src_addr, 0, msg, sizeof(msg)); -} - -static void send_bssgp_paging(struct gprs_ns_inst *nsi, - struct sockaddr_in *src_addr, - const uint8_t *imsi, size_t imsi_size, - struct gprs_ra_id *raid, uint32_t ptmsi) -{ - /* Base Station Subsystem GPRS Protocol, BSSGP SUSPEND */ - unsigned char msg[100] = { - 0x06, - }; - - const unsigned char drx_ie[] = {0x0a, 0x82, 0x07, 0x04}; - const unsigned char qos_ie[] = {0x18, 0x83, 0x00, 0x00, 0x00}; - - size_t bssgp_msg_size = 1; - - if (imsi) { - OSMO_ASSERT(imsi_size <= 127); - msg[bssgp_msg_size] = BSSGP_IE_IMSI; - msg[bssgp_msg_size + 1] = 0x80 | imsi_size; - memcpy(msg + bssgp_msg_size + 2, imsi, imsi_size); - bssgp_msg_size += 2 + imsi_size; - } - - memcpy(msg + bssgp_msg_size, drx_ie, sizeof(drx_ie)); - bssgp_msg_size += sizeof(drx_ie); - - if (raid) { - msg[bssgp_msg_size] = BSSGP_IE_ROUTEING_AREA; - msg[bssgp_msg_size+1] = 0x86; - gsm48_encode_ra((struct gsm48_ra_id *)(msg + bssgp_msg_size + 2), raid); - bssgp_msg_size += 8; - } - - memcpy(msg + bssgp_msg_size, qos_ie, sizeof(qos_ie)); - bssgp_msg_size += sizeof(qos_ie); - - if (ptmsi != GSM_RESERVED_TMSI) { - const uint32_t ptmsi_be = htonl(ptmsi); - msg[bssgp_msg_size] = BSSGP_IE_TMSI; - msg[bssgp_msg_size+1] = 0x84; - memcpy(msg + bssgp_msg_size + 2, &ptmsi_be, 4); - bssgp_msg_size += 6; - } - - send_ns_unitdata(nsi, "PAGING_PS", src_addr, 0, msg, bssgp_msg_size); -} - -static void send_bssgp_flow_control_bvc(struct gprs_ns_inst *nsi, - struct sockaddr_in *src_addr, - uint16_t bvci, uint8_t tag) -{ - /* GPRS Network Service, PDU type: NS_UNITDATA, - * BSSGP FLOW_CONTROL_BVC */ - unsigned char msg[] = { - 0x26, 0x1e, 0x81, /* Tag */ 0xff, 0x05, 0x82, 0x01, 0xdc, - 0x03, 0x82, 0x02, 0x76, 0x01, 0x82, 0x00, 0x50, - 0x1c, 0x82, 0x02, 0x58, 0x06, 0x82, 0x00, 0x03 - }; - - msg[3] = tag; - - send_ns_unitdata(nsi, "FLOW_CONTROL_BVC", src_addr, bvci, - msg, sizeof(msg)); -} - -static void send_bssgp_flow_control_bvc_ack(struct gprs_ns_inst *nsi, - struct sockaddr_in *src_addr, - uint16_t bvci, uint8_t tag) -{ - /* GPRS Network Service, PDU type: NS_UNITDATA, - * BSSGP FLOW_CONTROL_BVC_ACK */ - unsigned char msg[] = { - 0x27, 0x1e, 0x81, /* Tag */ 0xce - }; - - msg[3] = tag; - - send_ns_unitdata(nsi, "FLOW_CONTROL_BVC_ACK", src_addr, bvci, - msg, sizeof(msg)); -} - -static void send_llc_ul_ui( - struct gprs_ns_inst *nsi, const char *text, - struct sockaddr_in *src_addr, uint16_t nsbvci, uint32_t tlli, - struct gprs_ra_id *raid, uint16_t cell_id, - unsigned sapi, unsigned nu, - const uint8_t *msg, size_t msg_size) -{ - unsigned char llc_msg[4096] = { - 0x00, 0xc0, 0x01 - }; - - size_t llc_msg_size = 3 + msg_size + 3; - uint8_t e_bit = 0; - uint8_t pm_bit = 1; - unsigned fcs; - - nu &= 0x01ff; - - OSMO_ASSERT(llc_msg_size <= sizeof(llc_msg)); - - llc_msg[0] = (sapi & 0x0f); - llc_msg[1] = 0xc0 | (nu >> 6); /* UI frame */ - llc_msg[2] = (nu << 2) | ((e_bit & 1) << 1) | (pm_bit & 1); - - memcpy(llc_msg + 3, msg, msg_size); - - fcs = gprs_llc_fcs(llc_msg, msg_size + 3); - llc_msg[3 + msg_size + 0] = (uint8_t)(fcs >> 0); - llc_msg[3 + msg_size + 1] = (uint8_t)(fcs >> 8); - llc_msg[3 + msg_size + 2] = (uint8_t)(fcs >> 16); - - send_bssgp_ul_unitdata(nsi, text ? text : "LLC UI", - src_addr, nsbvci, tlli, raid, cell_id, - llc_msg, llc_msg_size); -} - -static void send_llc_dl_ui( - struct gprs_ns_inst *nsi, const char *text, - struct sockaddr_in *src_addr, uint16_t nsbvci, uint32_t tlli, - int with_racap_drx, const uint8_t *imsi, size_t imsi_size, - unsigned sapi, unsigned nu, - const uint8_t *msg, size_t msg_size) -{ - /* GPRS Network Service, PDU type: NS_UNITDATA */ - /* Base Station Subsystem GPRS Protocol: UL_UNITDATA */ - unsigned char llc_msg[4096] = { - 0x00, 0x00, 0x01 - }; - - size_t llc_msg_size = 3 + msg_size + 3; - uint8_t e_bit = 0; - uint8_t pm_bit = 1; - unsigned fcs; - - nu &= 0x01ff; - - OSMO_ASSERT(llc_msg_size <= sizeof(llc_msg)); - - llc_msg[0] = 0x40 | (sapi & 0x0f); - llc_msg[1] = 0xc0 | (nu >> 6); /* UI frame */ - llc_msg[2] = (nu << 2) | ((e_bit & 1) << 1) | (pm_bit & 1); - - memcpy(llc_msg + 3, msg, msg_size); - - fcs = gprs_llc_fcs(llc_msg, msg_size + 3); - llc_msg[3 + msg_size + 0] = (uint8_t)(fcs >> 0); - llc_msg[3 + msg_size + 1] = (uint8_t)(fcs >> 8); - llc_msg[3 + msg_size + 2] = (uint8_t)(fcs >> 16); - - send_bssgp_dl_unitdata(nsi, text ? text : "LLC UI", - src_addr, nsbvci, tlli, - with_racap_drx, imsi, imsi_size, - llc_msg, llc_msg_size); -} - - -static void setup_ns(struct gprs_ns_inst *nsi, struct sockaddr_in *src_addr, - uint16_t nsvci, uint16_t nsei) -{ - printf("Setup NS-VC: remote 0x%08x:%d, " - "NSVCI 0x%04x(%d), NSEI 0x%04x(%d)\n\n", - ntohl(src_addr->sin_addr.s_addr), ntohs(src_addr->sin_port), - nsvci, nsvci, nsei, nsei); - - send_ns_reset(nsi, src_addr, NS_CAUSE_OM_INTERVENTION, nsvci, nsei); - send_ns_alive(nsi, src_addr); - send_ns_unblock(nsi, src_addr); - send_ns_alive_ack(nsi, src_addr); -} - -static void setup_bssgp(struct gprs_ns_inst *nsi, struct sockaddr_in *src_addr, - uint16_t bvci) -{ - printf("Setup BSSGP: remote 0x%08x:%d, " - "BVCI 0x%04x(%d)\n\n", - ntohl(src_addr->sin_addr.s_addr), ntohs(src_addr->sin_port), - bvci, bvci); - - send_bssgp_reset(nsi, src_addr, bvci); -} - -static void connect_sgsn(struct gprs_ns_inst *nsi, struct sockaddr_in *sgsn_peer, - uint32_t sgsn_nsei) -{ - gprs_ns_nsip_connect(nsi, sgsn_peer, sgsn_nsei, sgsn_nsei+1); - send_ns_reset_ack(nsi, sgsn_peer, sgsn_nsei+1, sgsn_nsei); - send_ns_alive_ack(nsi, sgsn_peer); - send_ns_unblock_ack(nsi, sgsn_peer); - send_ns_alive(nsi, sgsn_peer); -} - -static void configure_sgsn_peer(struct sockaddr_in *sgsn_peer) -{ - sgsn_peer->sin_family = AF_INET; - sgsn_peer->sin_port = htons(32000); - sgsn_peer->sin_addr.s_addr = htonl(REMOTE_SGSN_ADDR); -} - -static void configure_sgsn2_peer(struct sockaddr_in *sgsn_peer) -{ - sgsn_peer->sin_family = AF_INET; - sgsn_peer->sin_port = htons(32001); - sgsn_peer->sin_addr.s_addr = htonl(REMOTE_SGSN2_ADDR); -} - -static void configure_bss_peers(struct sockaddr_in *bss_peers, size_t size) -{ - size_t i; - - for (i = 0; i < size; ++i) { - bss_peers[i].sin_family = AF_INET; - bss_peers[i].sin_port = htons((i + 1) * 1111); - bss_peers[i].sin_addr.s_addr = htonl(REMOTE_BSS_ADDR); - } -} - -int gprs_ns_rcvmsg(struct gprs_ns_inst *nsi, struct msgb *msg, - struct sockaddr_in *saddr, enum gprs_ns_ll ll); - -/* override */ -int gprs_ns_callback(enum gprs_ns_evt event, struct gprs_nsvc *nsvc, - struct msgb *msg, uint16_t bvci) -{ - printf("CALLBACK, event %d, msg length %zu, bvci 0x%04x\n%s\n\n", - event, msgb_bssgp_len(msg), bvci, - osmo_hexdump(msgb_l2(msg), msgb_l2len(msg))); - - switch (event) { - case GPRS_NS_EVT_UNIT_DATA: - return gbprox_rcvmsg(&gbcfg, msg, nsvc->nsei, bvci, nsvc->nsvci); - default: - break; - } - return 0; -} - -/* override */ -ssize_t sendto(int sockfd, const void *buf, size_t len, int flags, - const struct sockaddr *dest_addr, socklen_t addrlen) -{ - typedef ssize_t (*sendto_t)(int, const void *, size_t, int, - const struct sockaddr *, socklen_t); - static sendto_t real_sendto = NULL; - uint32_t dest_host = htonl(((struct sockaddr_in *)dest_addr)->sin_addr.s_addr); - int dest_port = htons(((struct sockaddr_in *)dest_addr)->sin_port); - - if (!real_sendto) - real_sendto = dlsym(RTLD_NEXT, "sendto"); - - if (dest_host == REMOTE_BSS_ADDR) - printf("MESSAGE to BSS at 0x%08x:%d, msg length %zu\n%s\n\n", - dest_host, dest_port, - len, osmo_hexdump(buf, len)); - else if (dest_host == REMOTE_SGSN_ADDR) - printf("MESSAGE to SGSN at 0x%08x:%d, msg length %zu\n%s\n\n", - dest_host, dest_port, - len, osmo_hexdump(buf, len)); - else if (dest_host == REMOTE_SGSN2_ADDR) - printf("MESSAGE to SGSN 2 at 0x%08x:%d, msg length %zu\n%s\n\n", - dest_host, dest_port, - len, osmo_hexdump(buf, len)); - else - return real_sendto(sockfd, buf, len, flags, dest_addr, addrlen); - - return len; -} - -/* override */ -int gprs_ns_sendmsg(struct gprs_ns_inst *nsi, struct msgb *msg) -{ - typedef int (*gprs_ns_sendmsg_t)(struct gprs_ns_inst *nsi, struct msgb *msg); - static gprs_ns_sendmsg_t real_gprs_ns_sendmsg = NULL; - uint16_t bvci = msgb_bvci(msg); - uint16_t nsei = msgb_nsei(msg); - - size_t len = msgb_length(msg); - - if (!real_gprs_ns_sendmsg) - real_gprs_ns_sendmsg = dlsym(RTLD_NEXT, "gprs_ns_sendmsg"); - - if (nsei == SGSN_NSEI) - printf("NS UNITDATA MESSAGE to SGSN, BVCI 0x%04x, " - "msg length %zu (%s)\n", - bvci, len, __func__); - else if (nsei == SGSN2_NSEI) - printf("NS UNITDATA MESSAGE to SGSN 2, BVCI 0x%04x, " - "msg length %zu (%s)\n", - bvci, len, __func__); - else - printf("NS UNITDATA MESSAGE to BSS, BVCI 0x%04x, " - "msg length %zu (%s)\n", - bvci, len, __func__); - - if (received_messages) { - struct msgb *msg_copy; - msg_copy = bssgp_msgb_copy(msg, "received_messages"); - llist_add_tail(&msg_copy->list, received_messages); - } - - return real_gprs_ns_sendmsg(nsi, msg); -} - -/* Get the next message from the receive FIFO - * - * \returns a pointer to the message which will be invalidated at the next call - * to expect_msg. Returns NULL, if there is no message left. - */ -static struct msgb *expect_msg(void) -{ - static struct msgb *msg = NULL; - - msgb_free(msg); - msg = NULL; - - if (!received_messages) - return NULL; - - if (llist_empty(received_messages)) - return NULL; - - msg = llist_entry(received_messages->next, struct msgb, list); - llist_del(&msg->list); - - return msg; -} - -struct expect_result { - struct msgb *msg; - struct gprs_gb_parse_context parse_ctx; -}; - -static struct expect_result *expect_bssgp_msg( - int match_nsei, int match_bvci, int match_pdu_type) -{ - static struct expect_result result; - static const struct expect_result empty_result = {0,}; - static struct msgb *msg; - uint16_t nsei; - int rc; - - memcpy(&result, &empty_result, sizeof(result)); - - msg = expect_msg(); - if (!msg) - return NULL; - - nsei = msgb_nsei(msg); - - if (match_nsei != MATCH_ANY && match_nsei != nsei) { - fprintf(stderr, "%s: NSEI mismatch (expected %u, got %u)\n", - __func__, match_nsei, nsei); - return NULL; - } - - if (match_bvci != MATCH_ANY && match_bvci != msgb_bvci(msg)) { - fprintf(stderr, "%s: BVCI mismatch (expected %u, got %u)\n", - __func__, match_bvci, msgb_bvci(msg)); - return NULL; - } - - result.msg = msg; - - result.parse_ctx.to_bss = nsei != SGSN_NSEI && nsei != SGSN2_NSEI; - result.parse_ctx.peer_nsei = nsei; - - if (!msgb_bssgph(msg)) { - fprintf(stderr, "%s: Expected BSSGP\n", __func__); - return NULL; - } - - rc = gprs_gb_parse_bssgp(msgb_bssgph(msg), msgb_bssgp_len(msg), - &result.parse_ctx); - - if (!rc) { - fprintf(stderr, "%s: Failed to parse message\n", __func__); - return NULL; - } - - if (match_pdu_type != MATCH_ANY && - match_pdu_type != result.parse_ctx.pdu_type) { - fprintf(stderr, "%s: PDU type mismatch (expected %u, got %u)\n", - __func__, match_pdu_type, result.parse_ctx.pdu_type); - return NULL; - } - - return &result; -} - -static struct expect_result *expect_llc_msg( - int match_nsei, int match_bvci, int match_sapi, int match_type) -{ - static struct expect_result *result; - - result = expect_bssgp_msg(match_nsei, match_bvci, MATCH_ANY); - if (!result) - return NULL; - - if (!result->parse_ctx.llc) { - fprintf(stderr, "%s: Expected LLC message\n", __func__); - return NULL; - } - - if (match_sapi != MATCH_ANY && - match_sapi != result->parse_ctx.llc_hdr_parsed.sapi) { - fprintf(stderr, "%s: LLC SAPI mismatch (expected %u, got %u)\n", - __func__, match_sapi, result->parse_ctx.llc_hdr_parsed.sapi); - return NULL; - } - - if (match_type != MATCH_ANY && - match_type != result->parse_ctx.llc_hdr_parsed.cmd) { - fprintf(stderr, - "%s: LLC command/type mismatch (expected %u, got %u)\n", - __func__, match_type, result->parse_ctx.llc_hdr_parsed.cmd); - return NULL; - } - - return result; -} - -static struct expect_result *expect_gmm_msg(int match_nsei, int match_bvci, - int match_type) -{ - static struct expect_result *result; - - result = expect_llc_msg(match_nsei, match_bvci, GPRS_SAPI_GMM, GPRS_LLC_UI); - if (!result) - return NULL; - - if (!result->parse_ctx.g48_hdr) { - fprintf(stderr, "%s: Expected GSM 04.08 message\n", __func__); - return NULL; - } - - if (match_type != MATCH_ANY && - match_type != result->parse_ctx.g48_hdr->msg_type) { - fprintf(stderr, - "%s: GSM 04.08 message type mismatch (expected %u, got %u)\n", - __func__, match_type, result->parse_ctx.g48_hdr->msg_type); - return NULL; - } - - return result; -} - -static void dump_rate_ctr_group(FILE *stream, const char *prefix, - struct rate_ctr_group *ctrg) -{ - unsigned int i; - - for (i = 0; i < ctrg->desc->num_ctr; i++) { - struct rate_ctr *ctr = &ctrg->ctr[i]; - if (ctr->current && !strchr(ctrg->desc->ctr_desc[i].name, '.')) - fprintf(stream, " %s%s: %llu%s", - prefix, ctrg->desc->ctr_desc[i].description, - (long long)ctr->current, - "\n"); - }; -} - -/* Signal handler for signals from NS layer */ -static int test_signal(unsigned int subsys, unsigned int signal, - void *handler_data, void *signal_data) -{ - struct ns_signal_data *nssd = signal_data; - int rc; - - if (subsys != SS_L_NS) - return 0; - - switch (signal) { - case S_NS_RESET: - printf("==> got signal NS_RESET, NS-VC 0x%04x/%s\n", - nssd->nsvc->nsvci, - gprs_ns_ll_str(nssd->nsvc)); - break; - - case S_NS_ALIVE_EXP: - printf("==> got signal NS_ALIVE_EXP, NS-VC 0x%04x/%s\n", - nssd->nsvc->nsvci, - gprs_ns_ll_str(nssd->nsvc)); - break; - - case S_NS_BLOCK: - printf("==> got signal NS_BLOCK, NS-VC 0x%04x/%s\n", - nssd->nsvc->nsvci, - gprs_ns_ll_str(nssd->nsvc)); - break; - - case S_NS_UNBLOCK: - printf("==> got signal NS_UNBLOCK, NS-VC 0x%04x/%s\n", - nssd->nsvc->nsvci, - gprs_ns_ll_str(nssd->nsvc)); - break; - - case S_NS_REPLACED: - printf("==> got signal NS_REPLACED: 0x%04x/%s", - nssd->nsvc->nsvci, - gprs_ns_ll_str(nssd->nsvc)); - printf(" -> 0x%04x/%s\n", - nssd->old_nsvc->nsvci, - gprs_ns_ll_str(nssd->old_nsvc)); - break; - - default: - printf("==> got signal %d, NS-VC 0x%04x/%s\n", signal, - nssd->nsvc->nsvci, - gprs_ns_ll_str(nssd->nsvc)); - break; - } - printf("\n"); - rc = gbprox_signal(subsys, signal, handler_data, signal_data); - return rc; -} - -static int gprs_process_message(struct gprs_ns_inst *nsi, const char *text, struct sockaddr_in *peer, const unsigned char* data, size_t data_len) -{ - struct msgb *msg; - int ret; - if (data_len > NS_ALLOC_SIZE - NS_ALLOC_HEADROOM) { - fprintf(stderr, "message too long: %zu\n", data_len); - return -1; - } - - msg = gprs_ns_msgb_alloc(); - OSMO_ASSERT(msg); - memmove(msg->data, data, data_len); - msg->l2h = msg->data; - msgb_put(msg, data_len); - - printf("PROCESSING %s from 0x%08x:%d\n%s\n\n", - text, ntohl(peer->sin_addr.s_addr), ntohs(peer->sin_port), - osmo_hexdump(data, data_len)); - - ret = gprs_ns_rcvmsg(nsi, msg, peer, GPRS_NS_LL_UDP); - - /* gprs_ns_rcvmsg() in old libosmocore returns "number of bytes - * transmitted by any response PDU we sent as a result of the - * received message", while modern libosmocore simply retunrs '0' - * for any successfully received message. Let's make sure any - * non-negative responses lead to a reproducible test output - * with both old and new libosmocore. */ - printf("result (%s) = %d\n\n", text, ret < 0 ? ret : 0); - - msgb_free(msg); - - return ret; -} - -static void gprs_dump_nsi(struct gprs_ns_inst *nsi) -{ - struct gprs_nsvc *nsvc; - - printf("Current NS-VCIs:\n"); - llist_for_each_entry(nsvc, &nsi->gprs_nsvcs, list) { - struct sockaddr_in *peer = &(nsvc->ip.bts_addr); - printf(" VCI 0x%04x, NSEI 0x%04x, peer 0x%08x:%d%s%s\n", - nsvc->nsvci, nsvc->nsei, - ntohl(peer->sin_addr.s_addr), ntohs(peer->sin_port), - nsvc->state & NSE_S_BLOCKED ? ", blocked" : "", - nsvc->state & NSE_S_ALIVE ? "" : ", dead" - ); - dump_rate_ctr_group(stdout, " ", nsvc->ctrg); - } - printf("\n"); -} - -static void test_gbproxy() -{ - struct gprs_ns_inst *nsi = gprs_ns_instantiate(gprs_ns_callback, tall_sgsn_ctx); - struct sockaddr_in bss_peer[4] = {{0},}; - struct sockaddr_in sgsn_peer= {0}; - - bssgp_nsi = nsi; - gbcfg.nsi = bssgp_nsi; - gbcfg.nsip_sgsn_nsei = SGSN_NSEI; - - configure_sgsn_peer(&sgsn_peer); - configure_bss_peers(bss_peer, ARRAY_SIZE(bss_peer)); - - printf("=== %s ===\n", __func__); - printf("--- Initialise SGSN ---\n\n"); - - connect_sgsn(nsi, &sgsn_peer, SGSN_NSEI); - gprs_dump_nsi(nsi); - - printf("--- Initialise BSS 1 ---\n\n"); - - setup_ns(nsi, &bss_peer[0], 0x1001, 0x1000); - setup_bssgp(nsi, &bss_peer[0], 0x1002); - gprs_dump_nsi(nsi); - dump_peers(stdout, 0, 0, &gbcfg); - - send_bssgp_reset_ack(nsi, &sgsn_peer, 0x1002); - - printf("--- Initialise BSS 2 ---\n\n"); - - setup_ns(nsi, &bss_peer[1], 0x2001, 0x2000); - setup_bssgp(nsi, &bss_peer[1], 0x2002); - gprs_dump_nsi(nsi); - dump_peers(stdout, 0, 0, &gbcfg); - - send_bssgp_reset_ack(nsi, &sgsn_peer, 0x2002); - - printf("--- Move BSS 1 to new port ---\n\n"); - - setup_ns(nsi, &bss_peer[2], 0x1001, 0x1000); - gprs_dump_nsi(nsi); - dump_peers(stdout, 0, 0, &gbcfg); - - printf("--- Move BSS 2 to former BSS 1 port ---\n\n"); - - setup_ns(nsi, &bss_peer[0], 0x2001, 0x2000); - gprs_dump_nsi(nsi); - dump_peers(stdout, 0, 0, &gbcfg); - - printf("--- Move BSS 1 to current BSS 2 port ---\n\n"); - - setup_ns(nsi, &bss_peer[0], 0x2001, 0x2000); - gprs_dump_nsi(nsi); - dump_peers(stdout, 0, 0, &gbcfg); - - printf("--- Move BSS 2 to new port ---\n\n"); - - setup_ns(nsi, &bss_peer[3], 0x2001, 0x2000); - gprs_dump_nsi(nsi); - dump_peers(stdout, 0, 0, &gbcfg); - - printf("--- Move BSS 2 to former BSS 1 port ---\n\n"); - - setup_ns(nsi, &bss_peer[2], 0x2001, 0x2000); - gprs_dump_nsi(nsi); - dump_peers(stdout, 0, 0, &gbcfg); - - printf("--- Move BSS 1 to original BSS 1 port ---\n\n"); - - setup_ns(nsi, &bss_peer[0], 0x1001, 0x1000); - gprs_dump_nsi(nsi); - dump_peers(stdout, 0, 0, &gbcfg); - - printf("--- Reset BSS 1 with a new BVCI ---\n\n"); - - setup_bssgp(nsi, &bss_peer[0], 0x1012); - gprs_dump_nsi(nsi); - dump_peers(stdout, 0, 0, &gbcfg); - - send_bssgp_reset_ack(nsi, &sgsn_peer, 0x1012); - - printf("--- Reset BSS 1 with the old BVCI ---\n\n"); - - setup_bssgp(nsi, &bss_peer[0], 0x1002); - gprs_dump_nsi(nsi); - dump_peers(stdout, 0, 0, &gbcfg); - - send_bssgp_reset_ack(nsi, &sgsn_peer, 0x1002); - - printf("--- Reset BSS 1 with the old BVCI again ---\n\n"); - - setup_bssgp(nsi, &bss_peer[0], 0x1002); - gprs_dump_nsi(nsi); - dump_peers(stdout, 0, 0, &gbcfg); - - send_bssgp_reset_ack(nsi, &sgsn_peer, 0x1002); - - printf("--- Send message from BSS 1 to SGSN, BVCI 0x1012 ---\n\n"); - - send_ns_unitdata(nsi, NULL, &bss_peer[0], 0x1012, (uint8_t *)"", 0); - - printf("--- Send message from SGSN to BSS 1, BVCI 0x1012 ---\n\n"); - - send_ns_unitdata(nsi, NULL, &sgsn_peer, 0x1012, (uint8_t *)"", 0); - - printf("--- Send message from BSS 1 to SGSN, BVCI 0x1002 ---\n\n"); - - send_ns_unitdata(nsi, NULL, &bss_peer[0], 0x1012, (uint8_t *)"", 0); - - printf("--- Send message from SGSN to BSS 1, BVCI 0x1002 ---\n\n"); - - send_ns_unitdata(nsi, NULL, &sgsn_peer, 0x1012, (uint8_t *)"", 0); - - printf("--- Send message from BSS 2 to SGSN, BVCI 0x2002 ---\n\n"); - - send_ns_unitdata(nsi, NULL, &bss_peer[0], 0x2002, (uint8_t *)"", 0); - - printf("--- Send message from SGSN to BSS 2, BVCI 0x2002 ---\n\n"); - - send_ns_unitdata(nsi, NULL, &sgsn_peer, 0x2002, (uint8_t *)"", 0); - - printf("--- Reset BSS 1 with the old BVCI on BSS2's link ---\n\n"); - - setup_bssgp(nsi, &bss_peer[2], 0x1002); - gprs_dump_nsi(nsi); - dump_peers(stdout, 0, 0, &gbcfg); - - dump_global(stdout, 0); - - send_bssgp_reset_ack(nsi, &sgsn_peer, 0x1002); - - printf("--- Send message from BSS 1 to SGSN, BVCI 0x1002 ---\n\n"); - - send_ns_unitdata(nsi, NULL, &bss_peer[0], 0x1012, (uint8_t *)"", 0); - - printf("--- Send message from SGSN to BSS 1, BVCI 0x1002 ---\n\n"); - - send_ns_unitdata(nsi, NULL, &sgsn_peer, 0x1012, (uint8_t *)"", 0); - - printf("--- Send message from SGSN to BSS 1, BVCI 0x10ff (invalid) ---\n\n"); - - send_ns_unitdata(nsi, NULL, &sgsn_peer, 0x10ff, (uint8_t *)"", 0); - - /* Find peer */ - OSMO_ASSERT(gbproxy_peer_by_bvci(&gbcfg, 0xeeee) == NULL); - OSMO_ASSERT(gbproxy_peer_by_bvci(&gbcfg, 0x1000) == NULL); - OSMO_ASSERT(gbproxy_peer_by_bvci(&gbcfg, 0x1012) != NULL); - OSMO_ASSERT(gbproxy_peer_by_nsei(&gbcfg, 0xeeee) == NULL); - OSMO_ASSERT(gbproxy_peer_by_nsei(&gbcfg, 0x1012) == NULL); - OSMO_ASSERT(gbproxy_peer_by_nsei(&gbcfg, 0x1000) != NULL); - - - /* Cleanup */ - OSMO_ASSERT(gbproxy_cleanup_peers(&gbcfg, 0, 0) == 0); - OSMO_ASSERT(gbproxy_cleanup_peers(&gbcfg, 0x1000, 0xeeee) == 0); - OSMO_ASSERT(gbproxy_cleanup_peers(&gbcfg, 0, 0x1002) == 0); - OSMO_ASSERT(gbproxy_cleanup_peers(&gbcfg, 0x1000, 0x1012) == 1); - OSMO_ASSERT(gbproxy_cleanup_peers(&gbcfg, 0x1000, 0x1012) == 0); - - dump_peers(stdout, 0, 0, &gbcfg); - - dump_global(stdout, 0); - - gbprox_reset(&gbcfg); - gprs_ns_destroy(nsi); - nsi = NULL; -} - -static void test_gbproxy_ident_changes() -{ - struct gprs_ns_inst *nsi = gprs_ns_instantiate(gprs_ns_callback, tall_sgsn_ctx); - struct sockaddr_in bss_peer[1] = {{0},}; - struct sockaddr_in sgsn_peer= {0}; - uint16_t nsei[2] = {0x1000, 0x2000}; - uint16_t nsvci[2] = {0x1001, 0x2001}; - uint16_t bvci[4] = {0x1002, 0x2002, 0x3002, 0x4002}; - - bssgp_nsi = nsi; - gbcfg.nsi = bssgp_nsi; - gbcfg.nsip_sgsn_nsei = SGSN_NSEI; - - configure_sgsn_peer(&sgsn_peer); - configure_bss_peers(bss_peer, ARRAY_SIZE(bss_peer)); - - printf("=== %s ===\n", __func__); - printf("--- Initialise SGSN ---\n\n"); - - connect_sgsn(nsi, &sgsn_peer, SGSN_NSEI); - gprs_dump_nsi(nsi); - - printf("--- Initialise BSS 1 ---\n\n"); - - setup_ns(nsi, &bss_peer[0], nsvci[0], nsei[0]); - gprs_dump_nsi(nsi); - - printf("--- Setup BVCI 1 ---\n\n"); - - setup_bssgp(nsi, &bss_peer[0], bvci[0]); - send_bssgp_reset_ack(nsi, &sgsn_peer, bvci[0]); - dump_peers(stdout, 0, 0, &gbcfg); - - printf("--- Setup BVCI 2 ---\n\n"); - - setup_bssgp(nsi, &bss_peer[0], bvci[1]); - send_bssgp_reset_ack(nsi, &sgsn_peer, bvci[1]); - dump_peers(stdout, 0, 0, &gbcfg); - - printf("--- Send message from BSS 1 to SGSN and back, BVCI 1 ---\n\n"); - - send_ns_unitdata(nsi, NULL, &bss_peer[0], bvci[0], (uint8_t *)"", 0); - send_ns_unitdata(nsi, NULL, &sgsn_peer, bvci[0], (uint8_t *)"", 0); - - printf("--- Send message from BSS 1 to SGSN and back, BVCI 2 ---\n\n"); - - send_ns_unitdata(nsi, NULL, &bss_peer[0], bvci[1], (uint8_t *)"", 0); - send_ns_unitdata(nsi, NULL, &sgsn_peer, bvci[1], (uint8_t *)"", 0); - - printf("--- Change NSEI ---\n\n"); - - setup_ns(nsi, &bss_peer[0], nsvci[0], nsei[1]); - gprs_dump_nsi(nsi); - - printf("--- Setup BVCI 1 ---\n\n"); - - setup_bssgp(nsi, &bss_peer[0], bvci[0]); - send_bssgp_reset_ack(nsi, &sgsn_peer, bvci[0]); - dump_peers(stdout, 0, 0, &gbcfg); - - printf("--- Setup BVCI 3 ---\n\n"); - - setup_bssgp(nsi, &bss_peer[0], bvci[2]); - send_bssgp_reset_ack(nsi, &sgsn_peer, bvci[2]); - dump_peers(stdout, 0, 0, &gbcfg); - - printf("--- Send message from BSS 1 to SGSN and back, BVCI 1 ---\n\n"); - - send_ns_unitdata(nsi, NULL, &bss_peer[0], bvci[0], (uint8_t *)"", 0); - send_ns_unitdata(nsi, NULL, &sgsn_peer, bvci[0], (uint8_t *)"", 0); - - printf("--- Send message from BSS 1 to SGSN and back, BVCI 2 " - " (should fail) ---\n\n"); - - send_ns_unitdata(nsi, NULL, &bss_peer[0], bvci[1], (uint8_t *)"", 0); - dump_peers(stdout, 0, 0, &gbcfg); - send_ns_unitdata(nsi, NULL, &sgsn_peer, bvci[1], (uint8_t *)"", 0); - dump_peers(stdout, 0, 0, &gbcfg); - - printf("--- Send message from BSS 1 to SGSN and back, BVCI 3 ---\n\n"); - - send_ns_unitdata(nsi, NULL, &bss_peer[0], bvci[2], (uint8_t *)"", 0); - send_ns_unitdata(nsi, NULL, &sgsn_peer, bvci[2], (uint8_t *)"", 0); - - printf("--- Change NSVCI ---\n\n"); - - setup_ns(nsi, &bss_peer[0], nsvci[1], nsei[1]); - gprs_dump_nsi(nsi); - - printf("--- Setup BVCI 1 ---\n\n"); - - setup_bssgp(nsi, &bss_peer[0], bvci[0]); - send_bssgp_reset_ack(nsi, &sgsn_peer, bvci[0]); - dump_peers(stdout, 0, 0, &gbcfg); - - printf("--- Setup BVCI 4 ---\n\n"); - - setup_bssgp(nsi, &bss_peer[0], bvci[3]); - send_bssgp_reset_ack(nsi, &sgsn_peer, bvci[3]); - dump_peers(stdout, 0, 0, &gbcfg); - - printf("--- Send message from BSS 1 to SGSN and back, BVCI 1 ---\n\n"); - - send_ns_unitdata(nsi, NULL, &bss_peer[0], bvci[0], (uint8_t *)"", 0); - send_ns_unitdata(nsi, NULL, &sgsn_peer, bvci[0], (uint8_t *)"", 0); - - printf("--- Send message from BSS 1 to SGSN and back, BVCI 2 " - " (should fail) ---\n\n"); - - send_ns_unitdata(nsi, NULL, &bss_peer[0], bvci[1], (uint8_t *)"", 0); - dump_peers(stdout, 0, 0, &gbcfg); - send_ns_unitdata(nsi, NULL, &sgsn_peer, bvci[1], (uint8_t *)"", 0); - dump_peers(stdout, 0, 0, &gbcfg); - - printf("--- Send message from BSS 1 to SGSN and back, BVCI 3 ---\n\n"); - - send_ns_unitdata(nsi, NULL, &bss_peer[0], bvci[2], (uint8_t *)"", 0); - send_ns_unitdata(nsi, NULL, &sgsn_peer, bvci[2], (uint8_t *)"", 0); - - printf("--- Send message from BSS 1 to SGSN and back, BVCI 4 ---\n\n"); - - send_ns_unitdata(nsi, NULL, &bss_peer[0], bvci[3], (uint8_t *)"", 0); - send_ns_unitdata(nsi, NULL, &sgsn_peer, bvci[3], (uint8_t *)"", 0); - - dump_global(stdout, 0); - dump_peers(stdout, 0, 0, &gbcfg); - - gbprox_reset(&gbcfg); - gprs_ns_destroy(nsi); - nsi = NULL; -} - -static void test_gbproxy_ra_patching() -{ - struct gprs_ns_inst *nsi = gprs_ns_instantiate(gprs_ns_callback, tall_sgsn_ctx); - struct sockaddr_in bss_peer[1] = {{0},}; - struct sockaddr_in sgsn_peer= {0}; - struct gprs_ra_id rai_bss = - {.mcc = 112, .mnc = 332, .lac = 16464, .rac = 96}; - struct gprs_ra_id rai_sgsn = - {.mcc = 123, .mnc = 456, .lac = 16464, .rac = 96}; - struct gprs_ra_id rai_unknown = - {.mcc = 1, .mnc = 99, .lac = 99, .rac = 96}; - uint16_t cell_id = 0x7530; - const char *err_msg = NULL; - const uint32_t ptmsi = 0xefe2b700; - const uint32_t local_tlli = 0xefe2b700; - const uint32_t foreign_tlli = 0xbbc54679; - const uint32_t foreign_tlli2 = 0xbb00beef; - const uint8_t imsi[] = {0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0xf8}; - const char *patch_re = "^9898|^121314"; - struct gbproxy_link_info *link_info; - struct gbproxy_peer *peer; - LLIST_HEAD(rcv_list); - struct expect_result *expect_res; - - OSMO_ASSERT(local_tlli == gprs_tmsi2tlli(ptmsi, TLLI_LOCAL)); - - bssgp_nsi = nsi; - gbcfg.nsi = bssgp_nsi; - gbcfg.nsip_sgsn_nsei = SGSN_NSEI; - gbcfg.core_plmn = (struct osmo_plmn_id){ .mcc = 123, .mnc = 456 }; - gbcfg.core_apn = talloc_zero_size(tall_sgsn_ctx, 100); - gbcfg.core_apn_size = gprs_str_to_apn(gbcfg.core_apn, 100, "foo.bar"); - gbcfg.patch_ptmsi = 0; - - configure_sgsn_peer(&sgsn_peer); - configure_bss_peers(bss_peer, ARRAY_SIZE(bss_peer)); - - if (gbproxy_set_patch_filter(&gbcfg.matches[GBPROX_MATCH_PATCHING], - patch_re, &err_msg) != 0) { - fprintf(stderr, "Failed to compile RE '%s': %s\n", - patch_re, err_msg); - exit(1); - } - - - printf("=== %s ===\n", __func__); - printf("--- Initialise SGSN ---\n\n"); - - connect_sgsn(nsi, &sgsn_peer, SGSN_NSEI); - gprs_dump_nsi(nsi); - - printf("--- Initialise BSS 1 ---\n\n"); - - setup_ns(nsi, &bss_peer[0], 0x1001, 0x1000); - - received_messages = &rcv_list; - - setup_bssgp(nsi, &bss_peer[0], 0x1002); - gprs_dump_nsi(nsi); - dump_peers(stdout, 0, 0, &gbcfg); - - peer = gbproxy_peer_by_nsei(&gbcfg, 0x1000); - OSMO_ASSERT(peer != NULL); - - OSMO_ASSERT(expect_bssgp_msg(SGSN_NSEI, 0, BSSGP_PDUT_BVC_RESET)); - - send_bssgp_reset_ack(nsi, &sgsn_peer, 0x1002); - - OSMO_ASSERT(expect_bssgp_msg(0x1000, 0, BSSGP_PDUT_BVC_RESET_ACK)); - - send_bssgp_suspend(nsi, &bss_peer[0], 0xccd1758b, &rai_bss); - - OSMO_ASSERT(expect_bssgp_msg(SGSN_NSEI, 0, BSSGP_PDUT_SUSPEND)); - - send_bssgp_suspend_ack(nsi, &sgsn_peer, 0xccd1758b, &rai_sgsn); - - OSMO_ASSERT(expect_bssgp_msg(0x1000, 0, BSSGP_PDUT_SUSPEND_ACK)); - - dump_global(stdout, 0); - dump_peers(stdout, 0, 0, &gbcfg); - - OSMO_ASSERT(2 == peer->ctrg->ctr[GBPROX_PEER_CTR_RAID_PATCHED_BSS].current); - OSMO_ASSERT(1 == peer->ctrg->ctr[GBPROX_PEER_CTR_RAID_PATCHED_SGSN].current); - - printf("--- Send message from BSS 1 to SGSN, BVCI 0x1002 ---\n\n"); - - send_llc_ul_ui(nsi, "ATTACH REQUEST", &bss_peer[0], 0x1002, - foreign_tlli, &rai_bss, cell_id, - GPRS_SAPI_GMM, 0, - dtap_attach_req, sizeof(dtap_attach_req)); - - OSMO_ASSERT(4 == peer->ctrg->ctr[GBPROX_PEER_CTR_RAID_PATCHED_BSS].current); - OSMO_ASSERT(expect_gmm_msg(SGSN_NSEI, 0x1002, GSM48_MT_GMM_ATTACH_REQ)); - - send_llc_dl_ui(nsi, "IDENT REQUEST", &sgsn_peer, 0x1002, - foreign_tlli, 0, NULL, 0, - GPRS_SAPI_GMM, 0, - dtap_identity_req, sizeof(dtap_identity_req)); - - OSMO_ASSERT(expect_gmm_msg(0x1000, 0x1002, GSM48_MT_GMM_ID_REQ)); - - send_llc_ul_ui(nsi, "IDENT RESPONSE", &bss_peer[0], 0x1002, - foreign_tlli, &rai_bss, cell_id, - GPRS_SAPI_GMM, 3, - dtap_identity_resp, sizeof(dtap_identity_resp)); - - OSMO_ASSERT(expect_gmm_msg(SGSN_NSEI, 0x1002, GSM48_MT_GMM_ID_RESP)); - - OSMO_ASSERT(5 == peer->ctrg->ctr[GBPROX_PEER_CTR_RAID_PATCHED_BSS].current); - OSMO_ASSERT(1 == peer->ctrg->ctr[GBPROX_PEER_CTR_RAID_PATCHED_SGSN].current); - - send_llc_dl_ui(nsi, "ATTACH ACCEPT", &sgsn_peer, 0x1002, - foreign_tlli, 1, imsi, sizeof(imsi), - GPRS_SAPI_GMM, 1, - dtap_attach_acc, sizeof(dtap_attach_acc)); - - OSMO_ASSERT(expect_gmm_msg(0x1000, 0x1002, GSM48_MT_GMM_ATTACH_ACK)); - - OSMO_ASSERT(2 == peer->ctrg->ctr[GBPROX_PEER_CTR_RAID_PATCHED_SGSN].current); - - OSMO_ASSERT(gbproxy_peer_by_rai(&gbcfg, convert_ra(&rai_bss)) != NULL); - OSMO_ASSERT(gbproxy_peer_by_rai(&gbcfg, convert_ra(&rai_sgsn)) == NULL); - OSMO_ASSERT(gbproxy_peer_by_rai(&gbcfg, convert_ra(&rai_unknown)) == NULL); - - OSMO_ASSERT(gbproxy_peer_by_lai(&gbcfg, convert_ra(&rai_bss)) != NULL); - OSMO_ASSERT(gbproxy_peer_by_lai(&gbcfg, convert_ra(&rai_sgsn)) == NULL); - OSMO_ASSERT(gbproxy_peer_by_lai(&gbcfg, convert_ra(&rai_unknown)) == NULL); - - OSMO_ASSERT(gbproxy_peer_by_lac(&gbcfg, convert_ra(&rai_bss)) != NULL); - OSMO_ASSERT(gbproxy_peer_by_lac(&gbcfg, convert_ra(&rai_sgsn)) != NULL); - OSMO_ASSERT(gbproxy_peer_by_lac(&gbcfg, convert_ra(&rai_unknown)) == NULL); - - link_info = gbproxy_link_info_by_sgsn_tlli(peer, local_tlli, SGSN_NSEI); - OSMO_ASSERT(link_info); - OSMO_ASSERT(link_info->tlli.assigned == local_tlli); - OSMO_ASSERT(link_info->tlli.current != local_tlli); - OSMO_ASSERT(!link_info->tlli.bss_validated); - OSMO_ASSERT(!link_info->tlli.net_validated); - OSMO_ASSERT(link_info->sgsn_tlli.assigned == local_tlli); - OSMO_ASSERT(link_info->sgsn_tlli.current != local_tlli); - OSMO_ASSERT(!link_info->sgsn_tlli.bss_validated); - OSMO_ASSERT(!link_info->sgsn_tlli.net_validated); - - send_llc_ul_ui(nsi, "ATTACH COMPLETE", &bss_peer[0], 0x1002, - local_tlli, &rai_bss, cell_id, - GPRS_SAPI_GMM, 4, - dtap_attach_complete, sizeof(dtap_attach_complete)); - - OSMO_ASSERT(expect_gmm_msg(SGSN_NSEI, 0x1002, GSM48_MT_GMM_ATTACH_COMPL)); - - OSMO_ASSERT(6 == peer->ctrg->ctr[GBPROX_PEER_CTR_RAID_PATCHED_BSS].current); - - link_info = gbproxy_link_info_by_sgsn_tlli(peer, local_tlli, SGSN_NSEI); - OSMO_ASSERT(link_info); - OSMO_ASSERT(link_info->tlli.assigned == local_tlli); - OSMO_ASSERT(link_info->tlli.current != local_tlli); - OSMO_ASSERT(link_info->tlli.bss_validated); - OSMO_ASSERT(!link_info->tlli.net_validated); - OSMO_ASSERT(link_info->sgsn_tlli.assigned == local_tlli); - OSMO_ASSERT(link_info->sgsn_tlli.current != local_tlli); - OSMO_ASSERT(link_info->sgsn_tlli.bss_validated); - OSMO_ASSERT(!link_info->sgsn_tlli.net_validated); - - /* Replace APN (1) */ - send_llc_ul_ui(nsi, "ACT PDP CTX REQ (REPLACE APN)", &bss_peer[0], 0x1002, - local_tlli, &rai_bss, cell_id, - GPRS_SAPI_GMM, 3, - dtap_act_pdp_ctx_req, sizeof(dtap_act_pdp_ctx_req)); - - OSMO_ASSERT(expect_gmm_msg(SGSN_NSEI, 0x1002, GSM48_MT_GSM_ACT_PDP_REQ)); - - OSMO_ASSERT(7 == peer->ctrg->ctr[GBPROX_PEER_CTR_RAID_PATCHED_BSS].current); - - link_info = gbproxy_link_info_by_sgsn_tlli(peer, local_tlli, SGSN_NSEI); - OSMO_ASSERT(link_info); - OSMO_ASSERT(link_info->tlli.assigned == local_tlli); - OSMO_ASSERT(link_info->tlli.current != local_tlli); - OSMO_ASSERT(link_info->tlli.bss_validated); - OSMO_ASSERT(!link_info->tlli.net_validated); - OSMO_ASSERT(link_info->sgsn_tlli.assigned == local_tlli); - OSMO_ASSERT(link_info->sgsn_tlli.current != local_tlli); - OSMO_ASSERT(link_info->sgsn_tlli.bss_validated); - OSMO_ASSERT(!link_info->sgsn_tlli.net_validated); - - send_llc_dl_ui(nsi, "GMM INFO", &sgsn_peer, 0x1002, - local_tlli, 1, imsi, sizeof(imsi), - GPRS_SAPI_GMM, 2, - dtap_gmm_information, sizeof(dtap_gmm_information)); - - OSMO_ASSERT(expect_gmm_msg(0x1000, 0x1002, GSM48_MT_GMM_INFO)); - - OSMO_ASSERT(2 == peer->ctrg->ctr[GBPROX_PEER_CTR_RAID_PATCHED_SGSN].current); - - link_info = gbproxy_link_info_by_sgsn_tlli(peer, local_tlli, SGSN_NSEI); - OSMO_ASSERT(link_info); - OSMO_ASSERT(link_info->tlli.assigned == 0); - OSMO_ASSERT(link_info->tlli.current == local_tlli); - OSMO_ASSERT(link_info->sgsn_tlli.assigned == 0); - OSMO_ASSERT(link_info->sgsn_tlli.current == local_tlli); - - /* Replace APN (2) */ - send_llc_ul_ui(nsi, "ACT PDP CTX REQ (REPLACE APN)", &bss_peer[0], 0x1002, - local_tlli, &rai_bss, cell_id, - GPRS_SAPI_GMM, 3, - dtap_act_pdp_ctx_req, sizeof(dtap_act_pdp_ctx_req)); - - expect_res = expect_gmm_msg(SGSN_NSEI, 0x1002, GSM48_MT_GSM_ACT_PDP_REQ); - OSMO_ASSERT(expect_res != NULL); - OSMO_ASSERT(expect_res->parse_ctx.apn_ie_len == gbcfg.core_apn_size + 2); - - OSMO_ASSERT(8 == peer->ctrg->ctr[GBPROX_PEER_CTR_RAID_PATCHED_BSS].current); - - gbcfg.core_apn[0] = 0; - gbcfg.core_apn_size = 0; - - /* Remove APN */ - send_llc_ul_ui(nsi, "ACT PDP CTX REQ (REMOVE APN)", &bss_peer[0], 0x1002, - local_tlli, &rai_bss, cell_id, - GPRS_SAPI_GMM, 3, - dtap_act_pdp_ctx_req, sizeof(dtap_act_pdp_ctx_req)); - - expect_res = expect_gmm_msg(SGSN_NSEI, 0x1002, GSM48_MT_GSM_ACT_PDP_REQ); - OSMO_ASSERT(expect_res != NULL); - OSMO_ASSERT(expect_res->parse_ctx.apn_ie_len == 0); - - OSMO_ASSERT(9 == peer->ctrg->ctr[GBPROX_PEER_CTR_RAID_PATCHED_BSS].current); - - dump_peers(stdout, 0, 0, &gbcfg); - - /* Detach */ - send_llc_ul_ui(nsi, "DETACH REQ", &bss_peer[0], 0x1002, - local_tlli, &rai_bss, cell_id, - GPRS_SAPI_GMM, 6, - dtap_detach_req, sizeof(dtap_detach_req)); - - OSMO_ASSERT(expect_gmm_msg(SGSN_NSEI, 0x1002, GSM48_MT_GMM_DETACH_REQ)); - - OSMO_ASSERT(10 == peer->ctrg->ctr[GBPROX_PEER_CTR_RAID_PATCHED_BSS].current); - OSMO_ASSERT(2 == peer->ctrg->ctr[GBPROX_PEER_CTR_RAID_PATCHED_SGSN].current); - - send_llc_dl_ui(nsi, "DETACH ACC", &sgsn_peer, 0x1002, - local_tlli, 1, imsi, sizeof(imsi), - GPRS_SAPI_GMM, 5, - dtap_detach_acc, sizeof(dtap_detach_acc)); - - OSMO_ASSERT(expect_gmm_msg(0x1000, 0x1002, GSM48_MT_GMM_DETACH_ACK)); - - dump_peers(stdout, 0, 0, &gbcfg); - - printf("--- RA update ---\n\n"); - - send_llc_ul_ui(nsi, "RA UPD REQ", &bss_peer[0], 0x1002, - foreign_tlli, &rai_bss, 0x7080, - GPRS_SAPI_GMM, 5, - dtap_ra_upd_req, sizeof(dtap_ra_upd_req)); - - OSMO_ASSERT(expect_gmm_msg(SGSN_NSEI, 0x1002, GSM48_MT_GMM_RA_UPD_REQ)); - - OSMO_ASSERT(12 == peer->ctrg->ctr[GBPROX_PEER_CTR_RAID_PATCHED_BSS].current); - - send_llc_dl_ui(nsi, "RA UPD ACC", &sgsn_peer, 0x1002, - foreign_tlli, 1, imsi, sizeof(imsi), - GPRS_SAPI_GMM, 6, - dtap_ra_upd_acc, sizeof(dtap_ra_upd_acc)); - - OSMO_ASSERT(expect_gmm_msg(0x1000, 0x1002, GSM48_MT_GMM_RA_UPD_ACK)); - - OSMO_ASSERT(3 == peer->ctrg->ctr[GBPROX_PEER_CTR_RAID_PATCHED_SGSN].current); - - /* Remove APN */ - send_llc_ul_ui(nsi, "ACT PDP CTX REQ (REMOVE APN)", &bss_peer[0], 0x1002, - local_tlli, &rai_bss, cell_id, - GPRS_SAPI_GMM, 3, - dtap_act_pdp_ctx_req, sizeof(dtap_act_pdp_ctx_req)); - - expect_res = expect_gmm_msg(SGSN_NSEI, 0x1002, GSM48_MT_GSM_ACT_PDP_REQ); - OSMO_ASSERT(expect_res != NULL); - OSMO_ASSERT(expect_res->parse_ctx.apn_ie_len == 0); - - OSMO_ASSERT(13 == peer->ctrg->ctr[GBPROX_PEER_CTR_RAID_PATCHED_BSS].current); - - dump_peers(stdout, 0, 0, &gbcfg); - - /* Detach (power off -> no Detach Accept) */ - send_llc_ul_ui(nsi, "DETACH REQ (PWR OFF)", &bss_peer[0], 0x1002, - local_tlli, &rai_bss, cell_id, - GPRS_SAPI_GMM, 6, - dtap_detach_po_req, sizeof(dtap_detach_po_req)); - - OSMO_ASSERT(expect_gmm_msg(SGSN_NSEI, 0x1002, GSM48_MT_GMM_DETACH_REQ)); - - OSMO_ASSERT(14 == peer->ctrg->ctr[GBPROX_PEER_CTR_RAID_PATCHED_BSS].current); - - dump_global(stdout, 0); - dump_peers(stdout, 0, 0, &gbcfg); - - printf("--- Bad cases ---\n\n"); - - /* The RAI in the Attach Request message differs from the RAI in the - * BSSGP message, only patch the latter */ - - send_llc_ul_ui(nsi, "ATTACH REQUEST (foreign RAI)", &bss_peer[0], 0x1002, - foreign_tlli2, &rai_bss, cell_id, - GPRS_SAPI_GMM, 0, - dtap_attach_req2, sizeof(dtap_attach_req2)); - - OSMO_ASSERT(expect_gmm_msg(SGSN_NSEI, 0x1002, GSM48_MT_GMM_ATTACH_REQ)); - - OSMO_ASSERT(15 == peer->ctrg->ctr[GBPROX_PEER_CTR_RAID_PATCHED_BSS].current); - - printf("TLLI is already detached, shouldn't patch\n"); - send_llc_ul_ui(nsi, "ACT PDP CTX REQ", &bss_peer[0], 0x1002, - local_tlli, &rai_bss, cell_id, - GPRS_SAPI_GMM, 3, - dtap_act_pdp_ctx_req, sizeof(dtap_act_pdp_ctx_req)); - - OSMO_ASSERT(expect_gmm_msg(SGSN_NSEI, 0x1002, GSM48_MT_GSM_ACT_PDP_REQ)); - - printf("Invalid RAI, shouldn't patch\n"); - send_bssgp_suspend_ack(nsi, &sgsn_peer, 0xccd1758b, &rai_unknown); - - /* TODO: The following breaks with the current libosmocore, enable it - * again (and remove the plain expect_msg), when the msgb_bssgph patch - * is integrated */ - /* OSMO_ASSERT(expect_bssgp_msg(SGSN_NSEI, 0, BSSGP_PDUT_STATUS)); */ - OSMO_ASSERT(expect_msg()); - - dump_global(stdout, 0); - dump_peers(stdout, 0, 0, &gbcfg); - - OSMO_ASSERT(!expect_msg()); - received_messages = NULL; - - talloc_free(gbcfg.core_apn); - gbcfg.core_apn = NULL; - - gbproxy_clear_patch_filter(&gbcfg.matches[GBPROX_MATCH_PATCHING]); - gbprox_reset(&gbcfg); - gprs_ns_destroy(nsi); - nsi = NULL; -} - -static void test_gbproxy_ptmsi_assignment() -{ - struct gprs_ns_inst *nsi = gprs_ns_instantiate(gprs_ns_callback, tall_sgsn_ctx); - struct sockaddr_in bss_peer[1] = {{0},}; - struct sockaddr_in sgsn_peer= {0}; - struct gprs_ra_id rai_bss = - {.mcc = 112, .mnc = 332, .lac = 16464, .rac = 96}; - struct gprs_ra_id rai_unknown = - {.mcc = 1, .mnc = 99, .lac = 99, .rac = 96}; - uint16_t cell_id = 0x1234; - - const uint32_t ptmsi = 0xefe2b700; - const uint32_t local_tlli = 0xefe2b700; - - const uint32_t foreign_tlli1 = 0x8000dead; - const uint32_t foreign_tlli2 = 0x8000beef; - - const uint8_t imsi1[] = {0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0xf8}; - const uint8_t imsi2[] = {0x11, 0x12, 0x99, 0x99, 0x99, 0x16, 0x17, 0xf8}; - - struct gbproxy_link_info *link_info, *link_info2; - struct gbproxy_peer *peer; - unsigned bss_nu = 0; - unsigned sgsn_nu = 0; - - OSMO_ASSERT(local_tlli == gprs_tmsi2tlli(ptmsi, TLLI_LOCAL)); - - bssgp_nsi = nsi; - gbcfg.nsi = bssgp_nsi; - gbcfg.nsip_sgsn_nsei = SGSN_NSEI; - gbcfg.core_plmn = (struct osmo_plmn_id){}; - gbcfg.core_apn = talloc_zero_size(tall_sgsn_ctx, 100); - gbcfg.core_apn_size = gprs_str_to_apn(gbcfg.core_apn, 100, "foo.bar"); - gbcfg.patch_ptmsi = 0; - - configure_sgsn_peer(&sgsn_peer); - configure_bss_peers(bss_peer, ARRAY_SIZE(bss_peer)); - - printf("=== %s ===\n", __func__); - printf("--- Initialise SGSN ---\n\n"); - - connect_sgsn(nsi, &sgsn_peer, SGSN_NSEI); - - printf("--- Initialise BSS 1 ---\n\n"); - - setup_ns(nsi, &bss_peer[0], 0x1001, 0x1000); - setup_bssgp(nsi, &bss_peer[0], 0x1002); - - peer = gbproxy_peer_by_nsei(&gbcfg, 0x1000); - OSMO_ASSERT(peer != NULL); - - send_bssgp_reset_ack(nsi, &sgsn_peer, 0x1002); - - gprs_dump_nsi(nsi); - dump_global(stdout, 0); - dump_peers(stdout, 0, 0, &gbcfg); - - printf("--- Establish first LLC connection ---\n\n"); - - send_llc_ul_ui(nsi, "ATTACH REQUEST", &bss_peer[0], 0x1002, - foreign_tlli1, &rai_unknown, cell_id, - GPRS_SAPI_GMM, bss_nu++, - dtap_attach_req, sizeof(dtap_attach_req)); - - dump_peers(stdout, 0, 0, &gbcfg); - - send_llc_dl_ui(nsi, "IDENT REQUEST", &sgsn_peer, 0x1002, - foreign_tlli1, 0, NULL, 0, - GPRS_SAPI_GMM, sgsn_nu++, - dtap_identity_req, sizeof(dtap_identity_req)); - - dump_peers(stdout, 0, 0, &gbcfg); - - send_llc_ul_ui(nsi, "IDENT RESPONSE", &bss_peer[0], 0x1002, - foreign_tlli1, &rai_bss, cell_id, - GPRS_SAPI_GMM, bss_nu++, - dtap_identity_resp, sizeof(dtap_identity_resp)); - - dump_peers(stdout, 0, 0, &gbcfg); - - send_llc_dl_ui(nsi, "ATTACH ACCEPT", &sgsn_peer, 0x1002, - foreign_tlli1, 1, imsi1, sizeof(imsi1), - GPRS_SAPI_GMM, sgsn_nu++, - dtap_attach_acc, sizeof(dtap_attach_acc)); - - dump_peers(stdout, 0, 0, &gbcfg); - - link_info = gbproxy_link_info_by_tlli(peer, foreign_tlli1); - link_info2 = gbproxy_link_info_by_tlli(peer, local_tlli); - OSMO_ASSERT(link_info); - OSMO_ASSERT(link_info == link_info2); - OSMO_ASSERT(link_info->tlli.assigned == local_tlli); - OSMO_ASSERT(link_info->tlli.current == foreign_tlli1); - OSMO_ASSERT(!link_info->tlli.bss_validated); - OSMO_ASSERT(!link_info->tlli.net_validated); - OSMO_ASSERT(link_info->tlli.ptmsi == ptmsi); - - send_llc_ul_ui(nsi, "ATTACH COMPLETE", &bss_peer[0], 0x1002, - local_tlli, &rai_bss, cell_id, - GPRS_SAPI_GMM, bss_nu++, - dtap_attach_complete, sizeof(dtap_attach_complete)); - - dump_peers(stdout, 0, 0, &gbcfg); - - link_info = gbproxy_link_info_by_tlli(peer, local_tlli); - OSMO_ASSERT(link_info); - OSMO_ASSERT(link_info->tlli.assigned == local_tlli); - OSMO_ASSERT(link_info->tlli.current == foreign_tlli1); - OSMO_ASSERT(link_info->tlli.bss_validated); - OSMO_ASSERT(!link_info->tlli.net_validated); - OSMO_ASSERT(link_info->tlli.ptmsi == ptmsi); - - - send_llc_dl_ui(nsi, "GMM INFO", &sgsn_peer, 0x1002, - local_tlli, 1, imsi1, sizeof(imsi1), - GPRS_SAPI_GMM, sgsn_nu++, - dtap_gmm_information, sizeof(dtap_gmm_information)); - - dump_peers(stdout, 0, 0, &gbcfg); - - link_info = gbproxy_link_info_by_imsi(peer, imsi1, ARRAY_SIZE(imsi1)); - OSMO_ASSERT(link_info); - OSMO_ASSERT(link_info->tlli.ptmsi == ptmsi); - OSMO_ASSERT(!gbproxy_link_info_by_imsi(peer, imsi2, ARRAY_SIZE(imsi2))); - - link_info2 = gbproxy_link_info_by_tlli(peer, local_tlli); - OSMO_ASSERT(link_info == link_info2); - OSMO_ASSERT(link_info->tlli.assigned == 0); - OSMO_ASSERT(link_info->tlli.current == local_tlli); - OSMO_ASSERT(link_info->tlli.ptmsi == ptmsi); - - printf("--- Establish second LLC connection with the same P-TMSI ---\n\n"); - - send_llc_ul_ui(nsi, "ATTACH REQUEST", &bss_peer[0], 0x1002, - foreign_tlli2, &rai_unknown, cell_id, - GPRS_SAPI_GMM, bss_nu++, - dtap_attach_req, sizeof(dtap_attach_req)); - - dump_peers(stdout, 0, 0, &gbcfg); - - send_llc_dl_ui(nsi, "IDENT REQUEST", &sgsn_peer, 0x1002, - foreign_tlli2, 0, NULL, 0, - GPRS_SAPI_GMM, sgsn_nu++, - dtap_identity_req, sizeof(dtap_identity_req)); - - dump_peers(stdout, 0, 0, &gbcfg); - - send_llc_ul_ui(nsi, "IDENT RESPONSE", &bss_peer[0], 0x1002, - foreign_tlli2, &rai_bss, cell_id, - GPRS_SAPI_GMM, bss_nu++, - dtap_identity2_resp, sizeof(dtap_identity2_resp)); - - dump_peers(stdout, 0, 0, &gbcfg); - - send_llc_dl_ui(nsi, "ATTACH ACCEPT", &sgsn_peer, 0x1002, - foreign_tlli2, 1, imsi2, sizeof(imsi2), - GPRS_SAPI_GMM, sgsn_nu++, - dtap_attach_acc, sizeof(dtap_attach_acc)); - - dump_peers(stdout, 0, 0, &gbcfg); - - link_info = gbproxy_link_info_by_tlli(peer, foreign_tlli2); - link_info2 = gbproxy_link_info_by_tlli(peer, local_tlli); - OSMO_ASSERT(link_info); - OSMO_ASSERT(link_info == link_info2); - OSMO_ASSERT(link_info->tlli.assigned == local_tlli); - OSMO_ASSERT(link_info->tlli.current == foreign_tlli2); - OSMO_ASSERT(!link_info->tlli.bss_validated); - OSMO_ASSERT(!link_info->tlli.net_validated); - OSMO_ASSERT(link_info->tlli.ptmsi == ptmsi); - - send_llc_ul_ui(nsi, "ATTACH COMPLETE", &bss_peer[0], 0x1002, - local_tlli, &rai_bss, cell_id, - GPRS_SAPI_GMM, bss_nu++, - dtap_attach_complete, sizeof(dtap_attach_complete)); - - dump_peers(stdout, 0, 0, &gbcfg); - - link_info = gbproxy_link_info_by_tlli(peer, local_tlli); - OSMO_ASSERT(link_info); - OSMO_ASSERT(link_info->tlli.assigned == local_tlli); - OSMO_ASSERT(link_info->tlli.current == foreign_tlli2); - OSMO_ASSERT(link_info->tlli.bss_validated); - OSMO_ASSERT(!link_info->tlli.net_validated); - OSMO_ASSERT(link_info->tlli.ptmsi == ptmsi); - - send_llc_dl_ui(nsi, "GMM INFO", &sgsn_peer, 0x1002, - local_tlli, 1, imsi2, sizeof(imsi2), - GPRS_SAPI_GMM, sgsn_nu++, - dtap_gmm_information, sizeof(dtap_gmm_information)); - - dump_peers(stdout, 0, 0, &gbcfg); - - link_info = gbproxy_link_info_by_imsi(peer, imsi2, ARRAY_SIZE(imsi2)); - OSMO_ASSERT(link_info); - OSMO_ASSERT(link_info->tlli.ptmsi == ptmsi); - OSMO_ASSERT(!gbproxy_link_info_by_imsi(peer, imsi1, ARRAY_SIZE(imsi1))); - - link_info2 = gbproxy_link_info_by_tlli(peer, local_tlli); - OSMO_ASSERT(link_info == link_info2); - OSMO_ASSERT(link_info->tlli.assigned == 0); - OSMO_ASSERT(link_info->tlli.current == local_tlli); - OSMO_ASSERT(link_info->tlli.ptmsi == ptmsi); - - dump_global(stdout, 0); - - talloc_free(gbcfg.core_apn); - gbcfg.core_apn = NULL; - - gbprox_reset(&gbcfg); - gprs_ns_destroy(nsi); - nsi = NULL; - - cleanup_test(); -} - -static void test_gbproxy_ptmsi_patching() -{ - struct gprs_ns_inst *nsi = gprs_ns_instantiate(gprs_ns_callback, tall_sgsn_ctx); - struct sockaddr_in bss_peer[1] = {{0},}; - struct sockaddr_in sgsn_peer= {0}; - struct gprs_ra_id rai_bss = - {.mcc = 112, .mnc = 332, .lac = 16464, .rac = 96}; - struct gprs_ra_id rai_sgsn = - {.mcc = 123, .mnc = 456, .lac = 16464, .rac = 96}; - struct gprs_ra_id rai_wrong_mcc_sgsn = - {.mcc = 999, .mnc = 456, .lac = 16464, .rac = 96}; - struct gprs_ra_id rai_unknown = - {.mcc = 1, .mnc = 99, .lac = 99, .rac = 96}; - uint16_t cell_id = 0x1234; - - const uint32_t sgsn_ptmsi = 0xefe2b700; - const uint32_t sgsn_ptmsi2 = 0xe0987654; - const uint32_t sgsn_ptmsi3 = 0xe0543210; - const uint32_t local_sgsn_tlli = 0xefe2b700; - const uint32_t local_sgsn_tlli2 = 0xe0987654; - const uint32_t local_sgsn_tlli3 = 0xe0543210; - const uint32_t random_sgsn_tlli = 0x78dead00; - const uint32_t unknown_sgsn_tlli = 0xeebadbad; - - const uint32_t bss_ptmsi = 0xc0dead01; - const uint32_t bss_ptmsi2 = 0xc0dead02; - const uint32_t bss_ptmsi3 = 0xc0dead03; - const uint32_t local_bss_tlli = 0xc0dead01; - const uint32_t local_bss_tlli2 = 0xc0dead02; - const uint32_t local_bss_tlli3 = 0xc0dead03; - const uint32_t foreign_bss_tlli = 0x8000dead; - - - const uint8_t imsi[] = {0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0xf8}; - struct gbproxy_link_info *link_info; - struct gbproxy_peer *peer; - unsigned bss_nu = 0; - unsigned sgsn_nu = 0; - int old_ctr; - - OSMO_ASSERT(local_sgsn_tlli == gprs_tmsi2tlli(sgsn_ptmsi, TLLI_LOCAL)); - OSMO_ASSERT(local_sgsn_tlli2 == gprs_tmsi2tlli(sgsn_ptmsi2, TLLI_LOCAL)); - OSMO_ASSERT(local_sgsn_tlli3 == gprs_tmsi2tlli(sgsn_ptmsi3, TLLI_LOCAL)); - OSMO_ASSERT(local_bss_tlli == gprs_tmsi2tlli(bss_ptmsi, TLLI_LOCAL)); - OSMO_ASSERT(local_bss_tlli2 == gprs_tmsi2tlli(bss_ptmsi2, TLLI_LOCAL)); - OSMO_ASSERT(local_bss_tlli3 == gprs_tmsi2tlli(bss_ptmsi3, TLLI_LOCAL)); - - bssgp_nsi = nsi; - gbcfg.nsi = bssgp_nsi; - gbcfg.nsip_sgsn_nsei = SGSN_NSEI; - gbcfg.core_plmn = (struct osmo_plmn_id){ .mcc = 123, .mnc = 456 }; - gbcfg.core_apn = talloc_zero_size(tall_sgsn_ctx, 100); - gbcfg.core_apn_size = gprs_str_to_apn(gbcfg.core_apn, 100, "foo.bar"); - gbcfg.patch_ptmsi = 1; - - configure_sgsn_peer(&sgsn_peer); - configure_bss_peers(bss_peer, ARRAY_SIZE(bss_peer)); - - printf("=== %s ===\n", __func__); - printf("--- Initialise SGSN ---\n\n"); - - connect_sgsn(nsi, &sgsn_peer, SGSN_NSEI); - - printf("--- Initialise BSS 1 ---\n\n"); - - setup_ns(nsi, &bss_peer[0], 0x1001, 0x1000); - setup_bssgp(nsi, &bss_peer[0], 0x1002); - - peer = gbproxy_peer_by_nsei(&gbcfg, 0x1000); - OSMO_ASSERT(peer != NULL); - - send_bssgp_reset_ack(nsi, &sgsn_peer, 0x1002); - - gprs_dump_nsi(nsi); - dump_global(stdout, 0); - dump_peers(stdout, 0, 0, &gbcfg); - - printf("--- Send message from BSS 1 to SGSN, BVCI 0x1002 ---\n\n"); - - send_llc_ul_ui(nsi, "ATTACH REQUEST", &bss_peer[0], 0x1002, - foreign_bss_tlli, &rai_unknown, cell_id, - GPRS_SAPI_GMM, bss_nu++, - dtap_attach_req, sizeof(dtap_attach_req)); - - dump_peers(stdout, 0, 0, &gbcfg); - - send_llc_dl_ui(nsi, "IDENT REQUEST", &sgsn_peer, 0x1002, - random_sgsn_tlli, 0, NULL, 0, - GPRS_SAPI_GMM, sgsn_nu++, - dtap_identity_req, sizeof(dtap_identity_req)); - - dump_peers(stdout, 0, 0, &gbcfg); - - send_llc_ul_ui(nsi, "IDENT RESPONSE", &bss_peer[0], 0x1002, - foreign_bss_tlli, &rai_bss, cell_id, - GPRS_SAPI_GMM, bss_nu++, - dtap_identity_resp, sizeof(dtap_identity_resp)); - - dump_peers(stdout, 0, 0, &gbcfg); - - send_llc_dl_ui(nsi, "ATTACH ACCEPT", &sgsn_peer, 0x1002, - random_sgsn_tlli, 1, imsi, sizeof(imsi), - GPRS_SAPI_GMM, sgsn_nu++, - dtap_attach_acc, sizeof(dtap_attach_acc)); - - dump_peers(stdout, 0, 0, &gbcfg); - - link_info = gbproxy_link_info_by_sgsn_tlli(peer, random_sgsn_tlli, SGSN_NSEI); - OSMO_ASSERT(link_info); - OSMO_ASSERT(link_info->tlli.assigned == local_bss_tlli); - OSMO_ASSERT(link_info->tlli.current == foreign_bss_tlli); - OSMO_ASSERT(!link_info->tlli.bss_validated); - OSMO_ASSERT(!link_info->tlli.net_validated); - OSMO_ASSERT(link_info->tlli.ptmsi == bss_ptmsi); - OSMO_ASSERT(link_info->sgsn_tlli.assigned == local_sgsn_tlli); - OSMO_ASSERT(link_info->sgsn_tlli.current == random_sgsn_tlli); - OSMO_ASSERT(!link_info->sgsn_tlli.bss_validated); - OSMO_ASSERT(!link_info->sgsn_tlli.net_validated); - OSMO_ASSERT(link_info->sgsn_tlli.ptmsi == sgsn_ptmsi); - - send_llc_ul_ui(nsi, "ATTACH COMPLETE", &bss_peer[0], 0x1002, - local_bss_tlli, &rai_bss, cell_id, - GPRS_SAPI_GMM, bss_nu++, - dtap_attach_complete, sizeof(dtap_attach_complete)); - - dump_peers(stdout, 0, 0, &gbcfg); - - link_info = gbproxy_link_info_by_sgsn_tlli(peer, local_sgsn_tlli, SGSN_NSEI); - OSMO_ASSERT(link_info); - OSMO_ASSERT(link_info->tlli.assigned == local_bss_tlli); - OSMO_ASSERT(link_info->tlli.current == foreign_bss_tlli); - OSMO_ASSERT(link_info->tlli.bss_validated); - OSMO_ASSERT(!link_info->tlli.net_validated); - OSMO_ASSERT(link_info->sgsn_tlli.assigned == local_sgsn_tlli); - OSMO_ASSERT(link_info->sgsn_tlli.current == random_sgsn_tlli); - OSMO_ASSERT(link_info->sgsn_tlli.bss_validated); - OSMO_ASSERT(!link_info->sgsn_tlli.net_validated); - - send_llc_dl_ui(nsi, "GMM INFO", &sgsn_peer, 0x1002, - local_sgsn_tlli, 1, imsi, sizeof(imsi), - GPRS_SAPI_GMM, sgsn_nu++, - dtap_gmm_information, sizeof(dtap_gmm_information)); - - dump_peers(stdout, 0, 0, &gbcfg); - - link_info = gbproxy_link_info_by_sgsn_tlli(peer, local_sgsn_tlli, SGSN_NSEI); - OSMO_ASSERT(link_info); - OSMO_ASSERT(link_info->tlli.current == local_bss_tlli); - OSMO_ASSERT(link_info->tlli.assigned == 0); - OSMO_ASSERT(link_info->sgsn_tlli.current == local_sgsn_tlli); - OSMO_ASSERT(link_info->sgsn_tlli.assigned == 0); - - send_llc_ul_ui(nsi, "ACT PDP CTX REQ (REPLACE APN)", &bss_peer[0], 0x1002, - local_bss_tlli, &rai_bss, cell_id, - GPRS_SAPI_GMM, bss_nu++, - dtap_act_pdp_ctx_req, sizeof(dtap_act_pdp_ctx_req)); - - dump_peers(stdout, 0, 0, &gbcfg); - - /* Non-DTAP */ - send_bssgp_ul_unitdata(nsi, "XID (UL)", &bss_peer[0], 0x1002, - local_bss_tlli, &rai_bss, cell_id, - llc_u_xid_ul, sizeof(llc_u_xid_ul)); - - send_bssgp_dl_unitdata(nsi, "XID (DL)", &sgsn_peer, 0x1002, - local_sgsn_tlli, 1, imsi, sizeof(imsi), - llc_u_xid_dl, sizeof(llc_u_xid_dl)); - - send_bssgp_ul_unitdata(nsi, "LL11 DNS QUERY (UL)", &bss_peer[0], 0x1002, - local_bss_tlli, &rai_bss, cell_id, - llc_ui_ll11_dns_query_ul, - sizeof(llc_ui_ll11_dns_query_ul)); - - send_bssgp_dl_unitdata(nsi, "LL11 DNS RESP (DL)", &sgsn_peer, 0x1002, - local_sgsn_tlli, 1, imsi, sizeof(imsi), - llc_ui_ll11_dns_resp_dl, - sizeof(llc_ui_ll11_dns_resp_dl)); - - dump_peers(stdout, 0, 0, &gbcfg); - - /* Repeated RA Update Requests */ - send_llc_ul_ui(nsi, "RA UPD REQ (P-TMSI 2)", &bss_peer[0], 0x1002, - local_bss_tlli, &rai_bss, 0x7080, - GPRS_SAPI_GMM, bss_nu++, - dtap_ra_upd_req, sizeof(dtap_ra_upd_req)); - - send_llc_dl_ui(nsi, "RA UDP ACC (P-TMSI 2)", &sgsn_peer, 0x1002, - local_sgsn_tlli, 1, imsi, sizeof(imsi), - GPRS_SAPI_GMM, sgsn_nu++, - dtap_ra_upd_acc2, sizeof(dtap_ra_upd_acc2)); - - dump_peers(stdout, 0, 0, &gbcfg); - - OSMO_ASSERT(gbproxy_link_info_by_sgsn_tlli(peer, local_sgsn_tlli2, SGSN_NSEI) != NULL); - link_info = gbproxy_link_info_by_sgsn_tlli(peer, local_sgsn_tlli, SGSN_NSEI); - OSMO_ASSERT(link_info); - OSMO_ASSERT(link_info->tlli.assigned == local_bss_tlli2); - OSMO_ASSERT(link_info->tlli.current == local_bss_tlli); - OSMO_ASSERT(!link_info->tlli.bss_validated); - OSMO_ASSERT(!link_info->tlli.net_validated); - OSMO_ASSERT(link_info->tlli.ptmsi == bss_ptmsi2); - OSMO_ASSERT(link_info->sgsn_tlli.assigned == local_sgsn_tlli2); - OSMO_ASSERT(link_info->sgsn_tlli.current == local_sgsn_tlli); - OSMO_ASSERT(!link_info->sgsn_tlli.bss_validated); - OSMO_ASSERT(!link_info->sgsn_tlli.net_validated); - OSMO_ASSERT(link_info->sgsn_tlli.ptmsi == sgsn_ptmsi2); - - send_llc_ul_ui(nsi, "RA UPD REQ (P-TMSI 3)", &bss_peer[0], 0x1002, - local_bss_tlli2, &rai_bss, 0x7080, - GPRS_SAPI_GMM, bss_nu++, - dtap_ra_upd_req, sizeof(dtap_ra_upd_req)); - - send_llc_dl_ui(nsi, "RA UDP ACC (P-TMSI 3)", &sgsn_peer, 0x1002, - local_sgsn_tlli2, 1, imsi, sizeof(imsi), - GPRS_SAPI_GMM, sgsn_nu++, - dtap_ra_upd_acc3, sizeof(dtap_ra_upd_acc3)); - - dump_peers(stdout, 0, 0, &gbcfg); - - OSMO_ASSERT(gbproxy_link_info_by_sgsn_tlli(peer, local_sgsn_tlli2, SGSN_NSEI) == NULL); - OSMO_ASSERT(gbproxy_link_info_by_sgsn_tlli(peer, local_sgsn_tlli3, SGSN_NSEI) != NULL); - link_info = gbproxy_link_info_by_sgsn_tlli(peer, local_sgsn_tlli, SGSN_NSEI); - OSMO_ASSERT(link_info); - OSMO_ASSERT(link_info->tlli.assigned == local_bss_tlli3); - OSMO_ASSERT(link_info->tlli.current == local_bss_tlli); - OSMO_ASSERT(!link_info->tlli.bss_validated); - OSMO_ASSERT(!link_info->tlli.net_validated); - OSMO_ASSERT(link_info->tlli.ptmsi == bss_ptmsi3); - OSMO_ASSERT(link_info->sgsn_tlli.assigned == local_sgsn_tlli3); - OSMO_ASSERT(link_info->sgsn_tlli.current == local_sgsn_tlli); - OSMO_ASSERT(!link_info->sgsn_tlli.bss_validated); - OSMO_ASSERT(!link_info->sgsn_tlli.net_validated); - OSMO_ASSERT(link_info->sgsn_tlli.ptmsi == sgsn_ptmsi3); - - send_llc_ul_ui(nsi, "RA UPD COMPLETE", &bss_peer[0], 0x1002, - local_bss_tlli3, &rai_bss, 0x7080, - GPRS_SAPI_GMM, bss_nu++, - dtap_ra_upd_complete, sizeof(dtap_ra_upd_complete)); - - link_info = gbproxy_link_info_by_tlli(peer, local_bss_tlli3); - - OSMO_ASSERT(link_info); - OSMO_ASSERT(link_info->tlli.bss_validated); - OSMO_ASSERT(!link_info->tlli.net_validated); - OSMO_ASSERT(link_info->sgsn_tlli.bss_validated); - OSMO_ASSERT(!link_info->sgsn_tlli.net_validated); - - send_llc_dl_ui(nsi, "GMM INFO", &sgsn_peer, 0x1002, - local_sgsn_tlli3, 1, imsi, sizeof(imsi), - GPRS_SAPI_GMM, sgsn_nu++, - dtap_gmm_information, sizeof(dtap_gmm_information)); - - dump_peers(stdout, 0, 0, &gbcfg); - - link_info = gbproxy_link_info_by_sgsn_tlli(peer, local_sgsn_tlli3, SGSN_NSEI); - OSMO_ASSERT(link_info); - OSMO_ASSERT(link_info->tlli.current == local_bss_tlli3); - OSMO_ASSERT(link_info->tlli.assigned == 0); - OSMO_ASSERT(link_info->sgsn_tlli.current == local_sgsn_tlli3); - OSMO_ASSERT(link_info->sgsn_tlli.assigned == 0); - - /* Other messages */ - send_bssgp_llc_discarded(nsi, &bss_peer[0], 0x1002, - local_bss_tlli3, 1, 12); - - dump_peers(stdout, 0, 0, &gbcfg); - - send_bssgp_suspend(nsi, &bss_peer[0], local_bss_tlli3, &rai_bss); - - dump_peers(stdout, 0, 0, &gbcfg); - - send_bssgp_suspend_ack(nsi, &sgsn_peer, local_sgsn_tlli3, &rai_sgsn); - - dump_peers(stdout, 0, 0, &gbcfg); - - old_ctr = peer->ctrg->ctr[GBPROX_PEER_CTR_PTMSI_PATCHED_SGSN].current; - - send_bssgp_paging(nsi, &sgsn_peer, imsi, sizeof(imsi), &rai_bss, sgsn_ptmsi3); - - dump_peers(stdout, 0, 0, &gbcfg); - - OSMO_ASSERT(old_ctr + 1 == - peer->ctrg->ctr[GBPROX_PEER_CTR_PTMSI_PATCHED_SGSN].current); - - /* Bad case: Invalid BVCI */ - send_bssgp_llc_discarded(nsi, &bss_peer[0], 0xeee1, - local_bss_tlli3, 1, 12); - dump_global(stdout, 0); - - /* Bad case: Invalid RAI */ - send_bssgp_suspend_ack(nsi, &sgsn_peer, local_sgsn_tlli3, &rai_unknown); - - dump_global(stdout, 0); - - /* Bad case: Invalid MCC (LAC ok) */ - send_bssgp_suspend_ack(nsi, &sgsn_peer, local_sgsn_tlli3, - &rai_wrong_mcc_sgsn); - - dump_global(stdout, 0); - - /* Bad case: Invalid TLLI from SGSN (IMSI unknown) */ - send_llc_dl_ui(nsi, "GMM INFO", &sgsn_peer, 0x1002, - unknown_sgsn_tlli, 1, NULL, 0, - GPRS_SAPI_GMM, 2, - dtap_gmm_information, sizeof(dtap_gmm_information)); - - /* Bad case: Invalid TLLI from SGSN (IMSI known) */ - send_llc_dl_ui(nsi, "GMM INFO", &sgsn_peer, 0x1002, - unknown_sgsn_tlli, 1, imsi, sizeof(imsi), - GPRS_SAPI_GMM, 3, - dtap_gmm_information, sizeof(dtap_gmm_information)); - - /* Detach */ - send_llc_ul_ui(nsi, "DETACH REQ", &bss_peer[0], 0x1002, - local_bss_tlli3, &rai_bss, cell_id, - GPRS_SAPI_GMM, bss_nu++, - dtap_detach_req, sizeof(dtap_detach_req)); - - dump_peers(stdout, 0, 0, &gbcfg); - - send_llc_dl_ui(nsi, "DETACH ACC", &sgsn_peer, 0x1002, - local_sgsn_tlli3, 1, imsi, sizeof(imsi), - GPRS_SAPI_GMM, sgsn_nu++, - dtap_detach_acc, sizeof(dtap_detach_acc)); - - dump_peers(stdout, 0, 0, &gbcfg); - - dump_global(stdout, 0); - - talloc_free(gbcfg.core_apn); - gbcfg.core_apn = NULL; - - gbprox_reset(&gbcfg); - gprs_ns_destroy(nsi); - nsi = NULL; - - cleanup_test(); -} - -static void test_gbproxy_ptmsi_patching_bad_cases() -{ - struct gprs_ns_inst *nsi = gprs_ns_instantiate(gprs_ns_callback, tall_sgsn_ctx); - struct sockaddr_in bss_peer[1] = {{0},}; - struct sockaddr_in sgsn_peer= {0}; - struct gprs_ra_id rai_bss = - {.mcc = 112, .mnc = 332, .lac = 16464, .rac = 96}; - struct gprs_ra_id rai_unknown = - {.mcc = 1, .mnc = 99, .lac = 99, .rac = 96}; - uint16_t cell_id = 0x1234; - - const uint32_t sgsn_ptmsi = 0xefe2b700; - const uint32_t local_sgsn_tlli = 0xefe2b700; - const uint32_t random_sgsn_tlli = 0x78dead00; - - const uint32_t bss_ptmsi = 0xc0dead01; - const uint32_t local_bss_tlli = 0xc0dead01; - const uint32_t foreign_bss_tlli = 0x8000dead; - - - const uint8_t imsi[] = {0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0xf8}; - struct gbproxy_link_info *link_info; - struct gbproxy_peer *peer; - unsigned bss_nu = 0; - unsigned sgsn_nu = 0; - - OSMO_ASSERT(local_sgsn_tlli == gprs_tmsi2tlli(sgsn_ptmsi, TLLI_LOCAL)); - OSMO_ASSERT(local_bss_tlli == gprs_tmsi2tlli(bss_ptmsi, TLLI_LOCAL)); - - bssgp_nsi = nsi; - gbcfg.nsi = bssgp_nsi; - gbcfg.nsip_sgsn_nsei = SGSN_NSEI; - gbcfg.core_plmn = (struct osmo_plmn_id){ .mcc = 123, .mnc = 456 }; - gbcfg.core_apn = talloc_zero_size(tall_sgsn_ctx, 100); - gbcfg.core_apn_size = gprs_str_to_apn(gbcfg.core_apn, 100, "foo.bar"); - gbcfg.patch_ptmsi = 1; - - configure_sgsn_peer(&sgsn_peer); - configure_bss_peers(bss_peer, ARRAY_SIZE(bss_peer)); - - printf("=== %s ===\n", __func__); - printf("--- Initialise SGSN ---\n\n"); - - connect_sgsn(nsi, &sgsn_peer, SGSN_NSEI); - - printf("--- Initialise BSS 1 ---\n\n"); - - setup_ns(nsi, &bss_peer[0], 0x1001, 0x1000); - setup_bssgp(nsi, &bss_peer[0], 0x1002); - - peer = gbproxy_peer_by_nsei(&gbcfg, 0x1000); - OSMO_ASSERT(peer != NULL); - - send_bssgp_reset_ack(nsi, &sgsn_peer, 0x1002); - - gprs_dump_nsi(nsi); - dump_global(stdout, 0); - dump_peers(stdout, 0, 0, &gbcfg); - - printf("--- Send message from BSS 1 to SGSN, BVCI 0x1002 ---\n\n"); - - send_llc_ul_ui(nsi, "ATTACH REQUEST", &bss_peer[0], 0x1002, - foreign_bss_tlli, &rai_unknown, cell_id, - GPRS_SAPI_GMM, bss_nu++, - dtap_attach_req, sizeof(dtap_attach_req)); - - dump_peers(stdout, 0, 0, &gbcfg); - - send_llc_dl_ui(nsi, "IDENT REQUEST", &sgsn_peer, 0x1002, - random_sgsn_tlli, 0, NULL, 0, - GPRS_SAPI_GMM, sgsn_nu++, - dtap_identity_req, sizeof(dtap_identity_req)); - - dump_peers(stdout, 0, 0, &gbcfg); - - send_llc_ul_ui(nsi, "IDENT RESPONSE", &bss_peer[0], 0x1002, - foreign_bss_tlli, &rai_bss, cell_id, - GPRS_SAPI_GMM, bss_nu++, - dtap_identity_resp, sizeof(dtap_identity_resp)); - - dump_peers(stdout, 0, 0, &gbcfg); - - send_llc_dl_ui(nsi, "ATTACH ACCEPT", &sgsn_peer, 0x1002, - random_sgsn_tlli, 1, imsi, sizeof(imsi), - GPRS_SAPI_GMM, sgsn_nu++, - dtap_attach_acc, sizeof(dtap_attach_acc)); - - dump_peers(stdout, 0, 0, &gbcfg); - - link_info = gbproxy_link_info_by_sgsn_tlli(peer, random_sgsn_tlli, SGSN_NSEI); - OSMO_ASSERT(link_info); - OSMO_ASSERT(link_info->tlli.assigned == local_bss_tlli); - OSMO_ASSERT(link_info->tlli.current == foreign_bss_tlli); - OSMO_ASSERT(!link_info->tlli.bss_validated); - OSMO_ASSERT(!link_info->tlli.net_validated); - OSMO_ASSERT(link_info->tlli.ptmsi == bss_ptmsi); - OSMO_ASSERT(link_info->sgsn_tlli.assigned == local_sgsn_tlli); - OSMO_ASSERT(link_info->sgsn_tlli.current == random_sgsn_tlli); - OSMO_ASSERT(!link_info->sgsn_tlli.bss_validated); - OSMO_ASSERT(!link_info->sgsn_tlli.net_validated); - OSMO_ASSERT(link_info->sgsn_tlli.ptmsi == sgsn_ptmsi); - - send_llc_dl_ui(nsi, "ATTACH ACCEPT (duplicated)", &sgsn_peer, 0x1002, - random_sgsn_tlli, 1, imsi, sizeof(imsi), - GPRS_SAPI_GMM, sgsn_nu++, - dtap_attach_acc, sizeof(dtap_attach_acc)); - - dump_peers(stdout, 0, 0, &gbcfg); - - link_info = gbproxy_link_info_by_sgsn_tlli(peer, random_sgsn_tlli, SGSN_NSEI); - OSMO_ASSERT(link_info); - OSMO_ASSERT(link_info->tlli.assigned == local_bss_tlli); - OSMO_ASSERT(link_info->tlli.current == foreign_bss_tlli); - OSMO_ASSERT(!link_info->tlli.bss_validated); - OSMO_ASSERT(!link_info->tlli.net_validated); - OSMO_ASSERT(link_info->tlli.ptmsi == bss_ptmsi); - OSMO_ASSERT(link_info->sgsn_tlli.assigned == local_sgsn_tlli); - OSMO_ASSERT(link_info->sgsn_tlli.current == random_sgsn_tlli); - OSMO_ASSERT(!link_info->sgsn_tlli.bss_validated); - OSMO_ASSERT(!link_info->sgsn_tlli.net_validated); - OSMO_ASSERT(link_info->sgsn_tlli.ptmsi == sgsn_ptmsi); - - send_llc_ul_ui(nsi, "ATTACH COMPLETE", &bss_peer[0], 0x1002, - local_bss_tlli, &rai_bss, cell_id, - GPRS_SAPI_GMM, bss_nu++, - dtap_attach_complete, sizeof(dtap_attach_complete)); - - dump_peers(stdout, 0, 0, &gbcfg); - - link_info = gbproxy_link_info_by_sgsn_tlli(peer, local_sgsn_tlli, SGSN_NSEI); - OSMO_ASSERT(link_info); - OSMO_ASSERT(link_info->tlli.assigned == local_bss_tlli); - OSMO_ASSERT(link_info->tlli.current == foreign_bss_tlli); - OSMO_ASSERT(link_info->tlli.bss_validated); - OSMO_ASSERT(!link_info->tlli.net_validated); - OSMO_ASSERT(link_info->sgsn_tlli.assigned == local_sgsn_tlli); - OSMO_ASSERT(link_info->sgsn_tlli.current == random_sgsn_tlli); - OSMO_ASSERT(link_info->sgsn_tlli.bss_validated); - OSMO_ASSERT(!link_info->sgsn_tlli.net_validated); - - send_llc_dl_ui(nsi, "GMM INFO", &sgsn_peer, 0x1002, - local_sgsn_tlli, 1, imsi, sizeof(imsi), - GPRS_SAPI_GMM, sgsn_nu++, - dtap_gmm_information, sizeof(dtap_gmm_information)); - - dump_peers(stdout, 0, 0, &gbcfg); - - link_info = gbproxy_link_info_by_sgsn_tlli(peer, local_sgsn_tlli, SGSN_NSEI); - OSMO_ASSERT(link_info); - OSMO_ASSERT(link_info->tlli.current == local_bss_tlli); - OSMO_ASSERT(link_info->tlli.assigned == 0); - OSMO_ASSERT(link_info->sgsn_tlli.current == local_sgsn_tlli); - OSMO_ASSERT(link_info->sgsn_tlli.assigned == 0); - - /* Detach */ - send_llc_ul_ui(nsi, "DETACH REQ", &bss_peer[0], 0x1002, - local_bss_tlli, &rai_bss, cell_id, - GPRS_SAPI_GMM, bss_nu++, - dtap_detach_req, sizeof(dtap_detach_req)); - - dump_peers(stdout, 0, 0, &gbcfg); - - send_llc_dl_ui(nsi, "DETACH ACC", &sgsn_peer, 0x1002, - local_sgsn_tlli, 1, imsi, sizeof(imsi), - GPRS_SAPI_GMM, sgsn_nu++, - dtap_detach_acc, sizeof(dtap_detach_acc)); - - dump_peers(stdout, 0, 0, &gbcfg); - - dump_global(stdout, 0); - - talloc_free(gbcfg.core_apn); - gbcfg.core_apn = NULL; - - gbprox_reset(&gbcfg); - gprs_ns_destroy(nsi); - nsi = NULL; - - cleanup_test(); -} - - -static void test_gbproxy_imsi_acquisition() -{ - struct gprs_ns_inst *nsi = gprs_ns_instantiate(gprs_ns_callback, tall_sgsn_ctx); - struct sockaddr_in bss_peer[1] = {{0},}; - struct sockaddr_in sgsn_peer= {0}; - struct gprs_ra_id rai_bss = - {.mcc = 112, .mnc = 332, .lac = 16464, .rac = 96}; - struct gprs_ra_id rai_sgsn = - {.mcc = 123, .mnc = 456, .lac = 16464, .rac = 96}; - struct gprs_ra_id rai_wrong_mcc_sgsn = - {.mcc = 999, .mnc = 456, .lac = 16464, .rac = 96}; - struct gprs_ra_id rai_unknown = - {.mcc = 1, .mnc = 99, .lac = 99, .rac = 96}; - uint16_t cell_id = 0x1234; - - const uint32_t sgsn_ptmsi = 0xefe2b700; - const uint32_t local_sgsn_tlli = 0xefe2b700; - const uint32_t random_sgsn_tlli = 0x78dead00; - const uint32_t random_sgsn_tlli2 = 0x78dead02; - - const uint32_t bss_ptmsi = 0xc0dead01; - const uint32_t local_bss_tlli = 0xc0dead01; - const uint32_t foreign_bss_tlli = 0x8000dead; - const uint32_t other_bss_tlli = 0x8000beef; - - const uint8_t imsi[] = {0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0xf8}; - struct gbproxy_link_info *link_info; - struct gbproxy_peer *peer; - unsigned bss_nu = 0; - unsigned sgsn_nu = 0; - - OSMO_ASSERT(local_sgsn_tlli == gprs_tmsi2tlli(sgsn_ptmsi, TLLI_LOCAL)); - - bssgp_nsi = nsi; - gbcfg.nsi = bssgp_nsi; - gbcfg.nsip_sgsn_nsei = SGSN_NSEI; - gbcfg.core_plmn = (struct osmo_plmn_id){ .mcc = 123, .mnc = 456 }; - gbcfg.core_apn = talloc_zero_size(tall_sgsn_ctx, 100); - gbcfg.core_apn_size = gprs_str_to_apn(gbcfg.core_apn, 100, "foo.bar"); - gbcfg.patch_ptmsi = 1; - gbcfg.acquire_imsi = 1; - - configure_sgsn_peer(&sgsn_peer); - configure_bss_peers(bss_peer, ARRAY_SIZE(bss_peer)); - - printf("=== %s ===\n", __func__); - printf("--- Initialise SGSN ---\n\n"); - - connect_sgsn(nsi, &sgsn_peer, SGSN_NSEI); - - printf("--- Initialise BSS 1 ---\n\n"); - - setup_ns(nsi, &bss_peer[0], 0x1001, 0x1000); - setup_bssgp(nsi, &bss_peer[0], 0x1002); - - peer = gbproxy_peer_by_nsei(&gbcfg, 0x1000); - OSMO_ASSERT(peer != NULL); - - send_bssgp_reset_ack(nsi, &sgsn_peer, 0x1002); - - gprs_dump_nsi(nsi); - dump_global(stdout, 0); - dump_peers(stdout, 0, 0, &gbcfg); - - printf("--- Send message from BSS 1 to SGSN, BVCI 0x1002 ---\n\n"); - - send_llc_ul_ui(nsi, "ATTACH REQUEST", &bss_peer[0], 0x1002, - foreign_bss_tlli, &rai_bss, cell_id, - GPRS_SAPI_GMM, bss_nu++, - dtap_attach_req, sizeof(dtap_attach_req)); - - dump_peers(stdout, 0, 0, &gbcfg); - - send_llc_ul_ui(nsi, "IDENT RESPONSE", &bss_peer[0], 0x1002, - foreign_bss_tlli, &rai_bss, cell_id, - GPRS_SAPI_GMM, bss_nu++, - dtap_identity_resp, sizeof(dtap_identity_resp)); - - dump_peers(stdout, 0, 0, &gbcfg); - - send_llc_dl_ui(nsi, "IDENT REQUEST", &sgsn_peer, 0x1002, - random_sgsn_tlli, 0, NULL, 0, - GPRS_SAPI_GMM, sgsn_nu++, - dtap_identity_req, sizeof(dtap_identity_req)); - - dump_peers(stdout, 0, 0, &gbcfg); - - send_llc_ul_ui(nsi, "IDENT RESPONSE", &bss_peer[0], 0x1002, - foreign_bss_tlli, &rai_bss, cell_id, - GPRS_SAPI_GMM, bss_nu++, - dtap_identity_resp, sizeof(dtap_identity_resp)); - - dump_peers(stdout, 0, 0, &gbcfg); - - send_llc_dl_ui(nsi, "ATTACH ACCEPT", &sgsn_peer, 0x1002, - random_sgsn_tlli, 1, imsi, sizeof(imsi), - GPRS_SAPI_GMM, sgsn_nu++, - dtap_attach_acc, sizeof(dtap_attach_acc)); - - dump_peers(stdout, 0, 0, &gbcfg); - - link_info = gbproxy_link_info_by_sgsn_tlli(peer, random_sgsn_tlli, SGSN_NSEI); - OSMO_ASSERT(link_info); - OSMO_ASSERT(link_info->tlli.assigned == local_bss_tlli); - OSMO_ASSERT(link_info->tlli.current == foreign_bss_tlli); - OSMO_ASSERT(!link_info->tlli.bss_validated); - OSMO_ASSERT(!link_info->tlli.net_validated); - OSMO_ASSERT(link_info->tlli.ptmsi == bss_ptmsi); - OSMO_ASSERT(link_info->sgsn_tlli.assigned == local_sgsn_tlli); - OSMO_ASSERT(link_info->sgsn_tlli.current == random_sgsn_tlli); - OSMO_ASSERT(!link_info->sgsn_tlli.bss_validated); - OSMO_ASSERT(!link_info->sgsn_tlli.net_validated); - OSMO_ASSERT(link_info->sgsn_tlli.ptmsi == sgsn_ptmsi); - - send_llc_ul_ui(nsi, "ATTACH COMPLETE", &bss_peer[0], 0x1002, - local_bss_tlli, &rai_bss, cell_id, - GPRS_SAPI_GMM, bss_nu++, - dtap_attach_complete, sizeof(dtap_attach_complete)); - - dump_peers(stdout, 0, 0, &gbcfg); - - link_info = gbproxy_link_info_by_sgsn_tlli(peer, local_sgsn_tlli, SGSN_NSEI); - OSMO_ASSERT(link_info); - OSMO_ASSERT(link_info->tlli.assigned == local_bss_tlli); - OSMO_ASSERT(link_info->tlli.current == foreign_bss_tlli); - OSMO_ASSERT(link_info->tlli.bss_validated); - OSMO_ASSERT(!link_info->tlli.net_validated); - OSMO_ASSERT(link_info->sgsn_tlli.assigned == local_sgsn_tlli); - OSMO_ASSERT(link_info->sgsn_tlli.current == random_sgsn_tlli); - OSMO_ASSERT(link_info->sgsn_tlli.bss_validated); - OSMO_ASSERT(!link_info->sgsn_tlli.net_validated); - - send_llc_dl_ui(nsi, "GMM INFO", &sgsn_peer, 0x1002, - local_sgsn_tlli, 1, imsi, sizeof(imsi), - GPRS_SAPI_GMM, sgsn_nu++, - dtap_gmm_information, sizeof(dtap_gmm_information)); - - dump_peers(stdout, 0, 0, &gbcfg); - - link_info = gbproxy_link_info_by_sgsn_tlli(peer, local_sgsn_tlli, SGSN_NSEI); - OSMO_ASSERT(link_info); - OSMO_ASSERT(link_info->tlli.current == local_bss_tlli); - OSMO_ASSERT(link_info->tlli.assigned == 0); - OSMO_ASSERT(link_info->sgsn_tlli.current == local_sgsn_tlli); - OSMO_ASSERT(link_info->sgsn_tlli.assigned == 0); - - /* Non-DTAP */ - send_bssgp_ul_unitdata(nsi, "XID (UL)", &bss_peer[0], 0x1002, - local_bss_tlli, &rai_bss, cell_id, - llc_u_xid_ul, sizeof(llc_u_xid_ul)); - - send_bssgp_dl_unitdata(nsi, "XID (DL)", &sgsn_peer, 0x1002, - local_sgsn_tlli, 1, imsi, sizeof(imsi), - llc_u_xid_dl, sizeof(llc_u_xid_dl)); - - send_bssgp_ul_unitdata(nsi, "LL11 DNS QUERY (UL)", &bss_peer[0], 0x1002, - local_bss_tlli, &rai_bss, cell_id, - llc_ui_ll11_dns_query_ul, - sizeof(llc_ui_ll11_dns_query_ul)); - - send_bssgp_dl_unitdata(nsi, "LL11 DNS RESP (DL)", &sgsn_peer, 0x1002, - local_sgsn_tlli, 1, imsi, sizeof(imsi), - llc_ui_ll11_dns_resp_dl, - sizeof(llc_ui_ll11_dns_resp_dl)); - - dump_peers(stdout, 0, 0, &gbcfg); - - /* Other messages */ - send_bssgp_llc_discarded(nsi, &bss_peer[0], 0x1002, - local_bss_tlli, 1, 12); - - dump_peers(stdout, 0, 0, &gbcfg); - - send_bssgp_llc_discarded(nsi, &sgsn_peer, 0x1002, - local_sgsn_tlli, 1, 12); - - dump_peers(stdout, 0, 0, &gbcfg); - - send_bssgp_suspend(nsi, &bss_peer[0], local_bss_tlli, &rai_bss); - - dump_peers(stdout, 0, 0, &gbcfg); - - send_bssgp_suspend_ack(nsi, &sgsn_peer, local_sgsn_tlli, &rai_sgsn); - - dump_peers(stdout, 0, 0, &gbcfg); - - /* Bad case: Invalid BVCI */ - send_bssgp_llc_discarded(nsi, &bss_peer[0], 0xeee1, - local_bss_tlli, 1, 12); - dump_global(stdout, 0); - - /* Bad case: Invalid RAI */ - send_bssgp_suspend_ack(nsi, &sgsn_peer, local_sgsn_tlli, &rai_unknown); - - dump_global(stdout, 0); - - /* Bad case: Invalid MCC (LAC ok) */ - send_bssgp_suspend_ack(nsi, &sgsn_peer, local_sgsn_tlli, - &rai_wrong_mcc_sgsn); - - dump_global(stdout, 0); - - /* Detach */ - send_llc_ul_ui(nsi, "DETACH REQ", &bss_peer[0], 0x1002, - local_bss_tlli, &rai_bss, cell_id, - GPRS_SAPI_GMM, bss_nu++, - dtap_detach_req, sizeof(dtap_detach_req)); - - dump_peers(stdout, 0, 0, &gbcfg); - - send_llc_dl_ui(nsi, "DETACH ACC", &sgsn_peer, 0x1002, - local_sgsn_tlli, 1, imsi, sizeof(imsi), - GPRS_SAPI_GMM, sgsn_nu++, - dtap_detach_acc, sizeof(dtap_detach_acc)); - - dump_peers(stdout, 0, 0, &gbcfg); - - /* RA Update request */ - - send_llc_ul_ui(nsi, "RA UPD REQ", &bss_peer[0], 0x1002, - foreign_bss_tlli, &rai_unknown, 0x7080, - GPRS_SAPI_GMM, bss_nu++, - dtap_ra_upd_req, sizeof(dtap_ra_upd_req)); - - send_llc_ul_ui(nsi, "IDENT RESPONSE", &bss_peer[0], 0x1002, - foreign_bss_tlli, &rai_bss, cell_id, - GPRS_SAPI_GMM, bss_nu++, - dtap_identity_resp, sizeof(dtap_identity_resp)); - - dump_peers(stdout, 0, 0, &gbcfg); - - send_llc_dl_ui(nsi, "RA UDP ACC", &sgsn_peer, 0x1002, - random_sgsn_tlli2, 1, imsi, sizeof(imsi), - GPRS_SAPI_GMM, sgsn_nu++, - dtap_ra_upd_acc, sizeof(dtap_ra_upd_acc)); - - dump_peers(stdout, 0, 0, &gbcfg); - - /* Detach */ - - send_llc_ul_ui(nsi, "DETACH REQ", &bss_peer[0], 0x1002, - local_bss_tlli, &rai_bss, cell_id, - GPRS_SAPI_GMM, bss_nu++, - dtap_detach_req, sizeof(dtap_detach_req)); - - dump_peers(stdout, 0, 0, &gbcfg); - - send_llc_dl_ui(nsi, "DETACH ACC", &sgsn_peer, 0x1002, - local_sgsn_tlli, 1, imsi, sizeof(imsi), - GPRS_SAPI_GMM, sgsn_nu++, - dtap_detach_acc, sizeof(dtap_detach_acc)); - - dump_peers(stdout, 0, 0, &gbcfg); - - /* Special case: Repeated Attach Requests */ - - send_llc_ul_ui(nsi, "ATTACH REQUEST", &bss_peer[0], 0x1002, - foreign_bss_tlli, &rai_unknown, cell_id, - GPRS_SAPI_GMM, bss_nu++, - dtap_attach_req, sizeof(dtap_attach_req)); - - send_llc_ul_ui(nsi, "ATTACH REQUEST", &bss_peer[0], 0x1002, - foreign_bss_tlli, &rai_unknown, cell_id, - GPRS_SAPI_GMM, bss_nu++, - dtap_attach_req, sizeof(dtap_attach_req)); - - send_llc_ul_ui(nsi, "DETACH REQ", &bss_peer[0], 0x1002, - foreign_bss_tlli, &rai_bss, cell_id, - GPRS_SAPI_GMM, bss_nu++, - dtap_detach_req, sizeof(dtap_detach_req)); - - dump_peers(stdout, 0, 0, &gbcfg); - - /* Special case: Detach from an unknown TLLI */ - - send_llc_ul_ui(nsi, "DETACH REQ (unknown TLLI)", &bss_peer[0], 0x1002, - other_bss_tlli, &rai_bss, cell_id, - GPRS_SAPI_GMM, bss_nu++, - dtap_detach_req, sizeof(dtap_detach_req)); - - dump_peers(stdout, 0, 0, &gbcfg); - - /* Special case: Repeated RA Update Requests */ - - send_llc_ul_ui(nsi, "RA UPD REQ", &bss_peer[0], 0x1002, - foreign_bss_tlli, &rai_unknown, 0x7080, - GPRS_SAPI_GMM, bss_nu++, - dtap_ra_upd_req, sizeof(dtap_ra_upd_req)); - - send_llc_ul_ui(nsi, "RA UPD REQ", &bss_peer[0], 0x1002, - foreign_bss_tlli, &rai_unknown, 0x7080, - GPRS_SAPI_GMM, bss_nu++, - dtap_ra_upd_req, sizeof(dtap_ra_upd_req)); - - send_llc_ul_ui(nsi, "DETACH REQ", &bss_peer[0], 0x1002, - foreign_bss_tlli, &rai_bss, cell_id, - GPRS_SAPI_GMM, bss_nu++, - dtap_detach_req, sizeof(dtap_detach_req)); - - dump_peers(stdout, 0, 0, &gbcfg); - - dump_global(stdout, 0); - - talloc_free(gbcfg.core_apn); - gbcfg.core_apn = NULL; - - gbprox_reset(&gbcfg); - gprs_ns_destroy(nsi); - nsi = NULL; - - cleanup_test(); -} - -static void test_gbproxy_secondary_sgsn() -{ - struct gprs_ns_inst *nsi = gprs_ns_instantiate(gprs_ns_callback, tall_sgsn_ctx); - struct sockaddr_in bss_peer[1] = {{0},}; - struct sockaddr_in sgsn_peer[2]= {{0},}; - struct gprs_ra_id rai_bss = - {.mcc = 112, .mnc = 332, .lac = 16464, .rac = 96}; - struct gprs_ra_id rai_sgsn = - {.mcc = 123, .mnc = 456, .lac = 16464, .rac = 96}; - struct gprs_ra_id rai_unknown = - {.mcc = 1, .mnc = 99, .lac = 99, .rac = 96}; - uint16_t cell_id = 0x1234; - - const uint32_t sgsn_ptmsi = 0xefe2b700; - const uint32_t local_sgsn_tlli = 0xefe2b700; - const uint32_t random_sgsn_tlli = 0x78dead00; - - const uint32_t bss_ptmsi = 0xc0dead01; - const uint32_t local_bss_tlli = 0xc0dead01; - const uint32_t foreign_bss_tlli = 0x8000dead; - - const uint32_t sgsn_ptmsi2 = 0xe0987654; - const uint32_t local_sgsn_tlli2 = 0xe0987654; - const uint32_t random_sgsn_tlli2 = 0x78dead02; - const uint32_t bss_ptmsi2 = 0xc0dead03; - const uint32_t local_bss_tlli2 = 0xc0dead03; - const uint32_t foreign_bss_tlli2 = 0x8000beef; - - const uint32_t random_sgsn_tlli3 = 0x78dead04; - const uint32_t bss_ptmsi3 = 0xc0dead05; - const uint32_t local_bss_tlli3 = 0xc0dead05; - const uint32_t foreign_bss_tlli3 = 0x8000feed; - - const uint8_t imsi1[] = {0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0xf8}; - const uint8_t imsi2[] = {0x11, 0x12, 0x99, 0x99, 0x99, 0x16, 0x17, 0xf8}; - const uint8_t imsi3[] = {0x11, 0x12, 0x99, 0x99, 0x99, 0x26, 0x27, 0xf8}; - struct gbproxy_link_info *link_info; - struct gbproxy_link_info *other_info; - struct gbproxy_peer *peer; - unsigned bss_nu = 0; - unsigned sgsn_nu = 0; - - const char *err_msg = NULL; - const char *filter_re = "999999"; - - OSMO_ASSERT(local_sgsn_tlli == gprs_tmsi2tlli(sgsn_ptmsi, TLLI_LOCAL)); - OSMO_ASSERT(local_sgsn_tlli2 == gprs_tmsi2tlli(sgsn_ptmsi2, TLLI_LOCAL)); - - bssgp_nsi = nsi; - gbcfg.nsi = bssgp_nsi; - gbcfg.nsip_sgsn_nsei = SGSN_NSEI; - gbcfg.core_plmn = (struct osmo_plmn_id){ .mcc = 123, .mnc = 456 }; - gbcfg.core_apn = talloc_zero_size(tall_sgsn_ctx, 100); - gbcfg.core_apn_size = gprs_str_to_apn(gbcfg.core_apn, 100, "foo.bar"); - gbcfg.patch_ptmsi = 1; - gbcfg.acquire_imsi = 1; - - gbcfg.route_to_sgsn2 = 1; - gbcfg.nsip_sgsn2_nsei = SGSN2_NSEI; - - if (gbproxy_set_patch_filter(&gbcfg.matches[GBPROX_MATCH_ROUTING], - filter_re, &err_msg) != 0) { - fprintf(stderr, "gbprox_set_patch_filter: got error: %s\n", - err_msg); - OSMO_ASSERT(err_msg == NULL); - } - - configure_sgsn_peer(&sgsn_peer[0]); - configure_sgsn2_peer(&sgsn_peer[1]); - configure_bss_peers(bss_peer, ARRAY_SIZE(bss_peer)); - - printf("=== %s ===\n", __func__); - printf("--- Initialise SGSN 1 ---\n\n"); - - connect_sgsn(nsi, &sgsn_peer[0], SGSN_NSEI); - - printf("--- Initialise SGSN 2 ---\n\n"); - - connect_sgsn(nsi, &sgsn_peer[1], SGSN2_NSEI); - - printf("--- Initialise BSS 1 ---\n\n"); - - setup_ns(nsi, &bss_peer[0], 0x1001, 0x1000); - setup_bssgp(nsi, &bss_peer[0], 0x0); - send_bssgp_reset_ack(nsi, &sgsn_peer[0], 0x0); - setup_bssgp(nsi, &bss_peer[0], 0x1002); - send_bssgp_reset_ack(nsi, &sgsn_peer[0], 0x1002); - send_bssgp_reset_ack(nsi, &sgsn_peer[1], 0x1002); - - peer = gbproxy_peer_by_nsei(&gbcfg, 0x1000); - OSMO_ASSERT(peer != NULL); - - gprs_dump_nsi(nsi); - dump_global(stdout, 0); - dump_peers(stdout, 0, 0, &gbcfg); - - printf("--- Flow control ---\n\n"); - - send_bssgp_flow_control_bvc(nsi, &bss_peer[0], 0x1002, 1); - send_bssgp_flow_control_bvc_ack(nsi, &sgsn_peer[0], 0x1002, 1); - send_bssgp_flow_control_bvc_ack(nsi, &sgsn_peer[1], 0x1002, 1); - - printf("--- Establish GPRS connection (SGSN 1) ---\n\n"); - - send_llc_ul_ui(nsi, "ATTACH REQUEST", &bss_peer[0], 0x1002, - foreign_bss_tlli, &rai_unknown, cell_id, - GPRS_SAPI_GMM, bss_nu++, - dtap_attach_req, sizeof(dtap_attach_req)); - - dump_peers(stdout, 0, 0, &gbcfg); - - send_llc_ul_ui(nsi, "IDENT RESPONSE", &bss_peer[0], 0x1002, - foreign_bss_tlli, &rai_bss, cell_id, - GPRS_SAPI_GMM, bss_nu++, - dtap_identity_resp, sizeof(dtap_identity_resp)); - - dump_peers(stdout, 0, 0, &gbcfg); - - send_llc_dl_ui(nsi, "IDENT REQUEST", &sgsn_peer[0], 0x1002, - random_sgsn_tlli, 0, NULL, 0, - GPRS_SAPI_GMM, sgsn_nu++, - dtap_identity_req, sizeof(dtap_identity_req)); - - dump_peers(stdout, 0, 0, &gbcfg); - - send_llc_ul_ui(nsi, "IDENT RESPONSE", &bss_peer[0], 0x1002, - foreign_bss_tlli, &rai_bss, cell_id, - GPRS_SAPI_GMM, bss_nu++, - dtap_identity_resp, sizeof(dtap_identity_resp)); - - dump_peers(stdout, 0, 0, &gbcfg); - - send_llc_dl_ui(nsi, "ATTACH ACCEPT", &sgsn_peer[0], 0x1002, - random_sgsn_tlli, 1, imsi1, sizeof(imsi1), - GPRS_SAPI_GMM, sgsn_nu++, - dtap_attach_acc, sizeof(dtap_attach_acc)); - - dump_peers(stdout, 0, 0, &gbcfg); - - OSMO_ASSERT(!gbproxy_link_info_by_sgsn_tlli(peer, local_sgsn_tlli, SGSN2_NSEI)); - link_info = gbproxy_link_info_by_sgsn_tlli(peer, random_sgsn_tlli, SGSN_NSEI); - OSMO_ASSERT(link_info); - OSMO_ASSERT(link_info->tlli.assigned == local_bss_tlli); - OSMO_ASSERT(link_info->tlli.current == foreign_bss_tlli); - OSMO_ASSERT(!link_info->tlli.bss_validated); - OSMO_ASSERT(!link_info->tlli.net_validated); - OSMO_ASSERT(link_info->tlli.ptmsi == bss_ptmsi); - OSMO_ASSERT(link_info->sgsn_tlli.assigned == local_sgsn_tlli); - OSMO_ASSERT(link_info->sgsn_tlli.current == random_sgsn_tlli); - OSMO_ASSERT(!link_info->sgsn_tlli.bss_validated); - OSMO_ASSERT(!link_info->sgsn_tlli.net_validated); - OSMO_ASSERT(link_info->sgsn_tlli.ptmsi == sgsn_ptmsi); - - send_llc_ul_ui(nsi, "ATTACH COMPLETE", &bss_peer[0], 0x1002, - local_bss_tlli, &rai_bss, cell_id, - GPRS_SAPI_GMM, bss_nu++, - dtap_attach_complete, sizeof(dtap_attach_complete)); - - dump_peers(stdout, 0, 0, &gbcfg); - - OSMO_ASSERT(!gbproxy_link_info_by_sgsn_tlli(peer, local_sgsn_tlli, SGSN2_NSEI)); - link_info = gbproxy_link_info_by_sgsn_tlli(peer, local_sgsn_tlli, SGSN_NSEI); - OSMO_ASSERT(link_info); - OSMO_ASSERT(link_info->tlli.assigned == local_bss_tlli); - OSMO_ASSERT(link_info->tlli.current == foreign_bss_tlli); - OSMO_ASSERT(link_info->tlli.bss_validated); - OSMO_ASSERT(!link_info->tlli.net_validated); - OSMO_ASSERT(link_info->sgsn_tlli.assigned == local_sgsn_tlli); - OSMO_ASSERT(link_info->sgsn_tlli.current == random_sgsn_tlli); - OSMO_ASSERT(link_info->sgsn_tlli.bss_validated); - OSMO_ASSERT(!link_info->sgsn_tlli.net_validated); - - send_llc_dl_ui(nsi, "GMM INFO", &sgsn_peer[0], 0x1002, - local_sgsn_tlli, 1, imsi1, sizeof(imsi1), - GPRS_SAPI_GMM, sgsn_nu++, - dtap_gmm_information, sizeof(dtap_gmm_information)); - - dump_peers(stdout, 0, 0, &gbcfg); - - OSMO_ASSERT(!gbproxy_link_info_by_sgsn_tlli(peer, local_sgsn_tlli, SGSN2_NSEI)); - link_info = gbproxy_link_info_by_sgsn_tlli(peer, local_sgsn_tlli, SGSN_NSEI); - OSMO_ASSERT(link_info); - OSMO_ASSERT(link_info->tlli.current == local_bss_tlli); - OSMO_ASSERT(link_info->tlli.assigned == 0); - OSMO_ASSERT(link_info->sgsn_tlli.current == local_sgsn_tlli); - OSMO_ASSERT(link_info->sgsn_tlli.assigned == 0); - - /* Non-DTAP */ - send_bssgp_ul_unitdata(nsi, "XID (UL)", &bss_peer[0], 0x1002, - local_bss_tlli, &rai_bss, cell_id, - llc_u_xid_ul, sizeof(llc_u_xid_ul)); - - send_bssgp_dl_unitdata(nsi, "XID (DL)", &sgsn_peer[0], 0x1002, - local_sgsn_tlli, 1, imsi1, sizeof(imsi1), - llc_u_xid_dl, sizeof(llc_u_xid_dl)); - - send_bssgp_ul_unitdata(nsi, "LL11 DNS QUERY (UL)", &bss_peer[0], 0x1002, - local_bss_tlli, &rai_bss, cell_id, - llc_ui_ll11_dns_query_ul, - sizeof(llc_ui_ll11_dns_query_ul)); - - send_bssgp_dl_unitdata(nsi, "LL11 DNS RESP (DL)", &sgsn_peer[0], 0x1002, - local_sgsn_tlli, 1, imsi1, sizeof(imsi1), - llc_ui_ll11_dns_resp_dl, - sizeof(llc_ui_ll11_dns_resp_dl)); - - dump_peers(stdout, 0, 0, &gbcfg); - - /* Other messages */ - send_bssgp_llc_discarded(nsi, &bss_peer[0], 0x1002, - local_bss_tlli, 1, 12); - - dump_peers(stdout, 0, 0, &gbcfg); - - send_bssgp_llc_discarded(nsi, &sgsn_peer[0], 0x1002, - local_sgsn_tlli, 1, 12); - - dump_peers(stdout, 0, 0, &gbcfg); - - send_bssgp_suspend(nsi, &bss_peer[0], local_bss_tlli, &rai_bss); - - dump_peers(stdout, 0, 0, &gbcfg); - - send_bssgp_suspend_ack(nsi, &sgsn_peer[0], local_sgsn_tlli, &rai_sgsn); - - dump_peers(stdout, 0, 0, &gbcfg); - - printf("--- Establish GPRS connection (SGSN 2) ---\n\n"); - - send_llc_ul_ui(nsi, "ATTACH REQUEST", &bss_peer[0], 0x1002, - foreign_bss_tlli2, &rai_unknown, cell_id, - GPRS_SAPI_GMM, bss_nu++, - dtap_attach_req, sizeof(dtap_attach_req)); - - dump_peers(stdout, 0, 0, &gbcfg); - - send_llc_ul_ui(nsi, "IDENT RESPONSE", &bss_peer[0], 0x1002, - foreign_bss_tlli2, &rai_bss, cell_id, - GPRS_SAPI_GMM, bss_nu++, - dtap_identity2_resp, sizeof(dtap_identity2_resp)); - - dump_peers(stdout, 0, 0, &gbcfg); - - send_llc_dl_ui(nsi, "IDENT REQUEST", &sgsn_peer[1], 0x1002, - random_sgsn_tlli2, 0, NULL, 0, - GPRS_SAPI_GMM, sgsn_nu++, - dtap_identity_req, sizeof(dtap_identity_req)); - - dump_peers(stdout, 0, 0, &gbcfg); - - send_llc_ul_ui(nsi, "IDENT RESPONSE", &bss_peer[0], 0x1002, - foreign_bss_tlli2, &rai_bss, cell_id, - GPRS_SAPI_GMM, bss_nu++, - dtap_identity2_resp, sizeof(dtap_identity2_resp)); - - dump_peers(stdout, 0, 0, &gbcfg); - - send_llc_dl_ui(nsi, "ATTACH ACCEPT", &sgsn_peer[1], 0x1002, - random_sgsn_tlli2, 1, imsi2, sizeof(imsi2), - GPRS_SAPI_GMM, sgsn_nu++, - dtap_attach_acc2, sizeof(dtap_attach_acc2)); - - dump_peers(stdout, 0, 0, &gbcfg); - - OSMO_ASSERT(!gbproxy_link_info_by_sgsn_tlli(peer, random_sgsn_tlli2, SGSN_NSEI)); - link_info = gbproxy_link_info_by_sgsn_tlli(peer, random_sgsn_tlli2, SGSN2_NSEI); - OSMO_ASSERT(link_info); - OSMO_ASSERT(link_info->tlli.assigned == local_bss_tlli2); - OSMO_ASSERT(link_info->tlli.current == foreign_bss_tlli2); - OSMO_ASSERT(!link_info->tlli.bss_validated); - OSMO_ASSERT(!link_info->tlli.net_validated); - OSMO_ASSERT(link_info->tlli.ptmsi == bss_ptmsi2); - OSMO_ASSERT(link_info->sgsn_tlli.assigned == local_sgsn_tlli2); - OSMO_ASSERT(link_info->sgsn_tlli.current == random_sgsn_tlli2); - OSMO_ASSERT(!link_info->sgsn_tlli.bss_validated); - OSMO_ASSERT(!link_info->sgsn_tlli.net_validated); - OSMO_ASSERT(link_info->sgsn_tlli.ptmsi == sgsn_ptmsi2); - - send_llc_ul_ui(nsi, "ATTACH COMPLETE", &bss_peer[0], 0x1002, - local_bss_tlli2, &rai_bss, cell_id, - GPRS_SAPI_GMM, bss_nu++, - dtap_attach_complete, sizeof(dtap_attach_complete)); - - dump_peers(stdout, 0, 0, &gbcfg); - - OSMO_ASSERT(!gbproxy_link_info_by_sgsn_tlli(peer, local_sgsn_tlli2, SGSN_NSEI)); - link_info = gbproxy_link_info_by_sgsn_tlli(peer, local_sgsn_tlli2, SGSN2_NSEI); - OSMO_ASSERT(link_info); - OSMO_ASSERT(link_info->tlli.assigned == local_bss_tlli2); - OSMO_ASSERT(link_info->tlli.current == foreign_bss_tlli2); - OSMO_ASSERT(link_info->tlli.bss_validated); - OSMO_ASSERT(!link_info->tlli.net_validated); - OSMO_ASSERT(link_info->sgsn_tlli.assigned == local_sgsn_tlli2); - OSMO_ASSERT(link_info->sgsn_tlli.current == random_sgsn_tlli2); - OSMO_ASSERT(link_info->sgsn_tlli.bss_validated); - OSMO_ASSERT(!link_info->sgsn_tlli.net_validated); - - send_llc_dl_ui(nsi, "GMM INFO", &sgsn_peer[1], 0x1002, - local_sgsn_tlli2, 1, imsi2, sizeof(imsi2), - GPRS_SAPI_GMM, sgsn_nu++, - dtap_gmm_information, sizeof(dtap_gmm_information)); - - dump_peers(stdout, 0, 0, &gbcfg); - - OSMO_ASSERT(!gbproxy_link_info_by_sgsn_tlli(peer, local_sgsn_tlli2, SGSN_NSEI)); - link_info = gbproxy_link_info_by_sgsn_tlli(peer, local_sgsn_tlli2, SGSN2_NSEI); - OSMO_ASSERT(link_info); - OSMO_ASSERT(link_info->tlli.current == local_bss_tlli2); - OSMO_ASSERT(link_info->tlli.assigned == 0); - OSMO_ASSERT(link_info->sgsn_tlli.current == local_sgsn_tlli2); - OSMO_ASSERT(link_info->sgsn_tlli.assigned == 0); - - /* Non-DTAP */ - send_bssgp_ul_unitdata(nsi, "XID (UL)", &bss_peer[0], 0x1002, - local_bss_tlli2, &rai_bss, cell_id, - llc_u_xid_ul, sizeof(llc_u_xid_ul)); - - send_bssgp_dl_unitdata(nsi, "XID (DL)", &sgsn_peer[1], 0x1002, - local_sgsn_tlli2, 1, imsi2, sizeof(imsi2), - llc_u_xid_dl, sizeof(llc_u_xid_dl)); - - send_bssgp_ul_unitdata(nsi, "LL11 DNS QUERY (UL)", &bss_peer[0], 0x1002, - local_bss_tlli2, &rai_bss, cell_id, - llc_ui_ll11_dns_query_ul, - sizeof(llc_ui_ll11_dns_query_ul)); - - send_bssgp_dl_unitdata(nsi, "LL11 DNS RESP (DL)", &sgsn_peer[1], 0x1002, - local_sgsn_tlli2, 1, imsi2, sizeof(imsi2), - llc_ui_ll11_dns_resp_dl, - sizeof(llc_ui_ll11_dns_resp_dl)); - - dump_peers(stdout, 0, 0, &gbcfg); - - /* Other messages */ - send_bssgp_llc_discarded(nsi, &bss_peer[0], 0x1002, - local_bss_tlli2, 1, 12); - - dump_peers(stdout, 0, 0, &gbcfg); - - send_bssgp_llc_discarded(nsi, &sgsn_peer[1], 0x1002, - local_sgsn_tlli2, 1, 12); - - dump_peers(stdout, 0, 0, &gbcfg); - - send_bssgp_suspend(nsi, &bss_peer[0], local_bss_tlli2, &rai_bss); - - dump_peers(stdout, 0, 0, &gbcfg); - - send_bssgp_suspend_ack(nsi, &sgsn_peer[1], local_sgsn_tlli2, &rai_sgsn); - - dump_peers(stdout, 0, 0, &gbcfg); - - printf("--- Establish GPRS connection (SGSN 2, P-TMSI collision) ---\n\n"); - - send_llc_ul_ui(nsi, "ATTACH REQUEST", &bss_peer[0], 0x1002, - foreign_bss_tlli3, &rai_unknown, cell_id, - GPRS_SAPI_GMM, bss_nu++, - dtap_attach_req, sizeof(dtap_attach_req)); - - dump_peers(stdout, 0, 0, &gbcfg); - - send_llc_ul_ui(nsi, "IDENT RESPONSE", &bss_peer[0], 0x1002, - foreign_bss_tlli3, &rai_bss, cell_id, - GPRS_SAPI_GMM, bss_nu++, - dtap_identity3_resp, sizeof(dtap_identity3_resp)); - - dump_peers(stdout, 0, 0, &gbcfg); - - send_llc_dl_ui(nsi, "IDENT REQUEST", &sgsn_peer[1], 0x1002, - random_sgsn_tlli3, 0, NULL, 0, - GPRS_SAPI_GMM, sgsn_nu++, - dtap_identity_req, sizeof(dtap_identity_req)); - - dump_peers(stdout, 0, 0, &gbcfg); - - send_llc_ul_ui(nsi, "IDENT RESPONSE", &bss_peer[0], 0x1002, - foreign_bss_tlli3, &rai_bss, cell_id, - GPRS_SAPI_GMM, bss_nu++, - dtap_identity3_resp, sizeof(dtap_identity3_resp)); - - dump_peers(stdout, 0, 0, &gbcfg); - - send_llc_dl_ui(nsi, "ATTACH ACCEPT (P-TMSI 1)", &sgsn_peer[1], 0x1002, - random_sgsn_tlli3, 1, imsi3, sizeof(imsi3), - GPRS_SAPI_GMM, sgsn_nu++, - dtap_attach_acc, sizeof(dtap_attach_acc)); - - dump_peers(stdout, 0, 0, &gbcfg); - - OSMO_ASSERT(!gbproxy_link_info_by_sgsn_tlli(peer, random_sgsn_tlli3, SGSN_NSEI)); - link_info = gbproxy_link_info_by_sgsn_tlli(peer, random_sgsn_tlli3, SGSN2_NSEI); - OSMO_ASSERT(link_info); - OSMO_ASSERT(link_info->tlli.assigned == local_bss_tlli3); - OSMO_ASSERT(link_info->tlli.current == foreign_bss_tlli3); - OSMO_ASSERT(!link_info->tlli.bss_validated); - OSMO_ASSERT(!link_info->tlli.net_validated); - OSMO_ASSERT(link_info->tlli.ptmsi == bss_ptmsi3); - OSMO_ASSERT(link_info->sgsn_tlli.assigned == local_sgsn_tlli); - OSMO_ASSERT(link_info->sgsn_tlli.current == random_sgsn_tlli3); - OSMO_ASSERT(!link_info->sgsn_tlli.bss_validated); - OSMO_ASSERT(!link_info->sgsn_tlli.net_validated); - OSMO_ASSERT(link_info->sgsn_tlli.ptmsi == sgsn_ptmsi); - - send_llc_ul_ui(nsi, "ATTACH COMPLETE", &bss_peer[0], 0x1002, - local_bss_tlli3, &rai_bss, cell_id, - GPRS_SAPI_GMM, bss_nu++, - dtap_attach_complete, sizeof(dtap_attach_complete)); - - dump_peers(stdout, 0, 0, &gbcfg); - - other_info = gbproxy_link_info_by_sgsn_tlli(peer, local_sgsn_tlli, SGSN_NSEI); - OSMO_ASSERT(other_info); - link_info = gbproxy_link_info_by_sgsn_tlli(peer, local_sgsn_tlli, SGSN2_NSEI); - OSMO_ASSERT(link_info); - OSMO_ASSERT(link_info != other_info); - OSMO_ASSERT(link_info->tlli.assigned == local_bss_tlli3); - OSMO_ASSERT(link_info->tlli.current == foreign_bss_tlli3); - OSMO_ASSERT(link_info->tlli.bss_validated); - OSMO_ASSERT(!link_info->tlli.net_validated); - OSMO_ASSERT(link_info->sgsn_tlli.assigned == local_sgsn_tlli); - OSMO_ASSERT(link_info->sgsn_tlli.current == random_sgsn_tlli3); - OSMO_ASSERT(link_info->sgsn_tlli.bss_validated); - OSMO_ASSERT(!link_info->sgsn_tlli.net_validated); - - send_llc_dl_ui(nsi, "GMM INFO", &sgsn_peer[1], 0x1002, - local_sgsn_tlli, 1, imsi3, sizeof(imsi3), - GPRS_SAPI_GMM, sgsn_nu++, - dtap_gmm_information, sizeof(dtap_gmm_information)); - - dump_peers(stdout, 0, 0, &gbcfg); - - other_info = gbproxy_link_info_by_sgsn_tlli(peer, local_sgsn_tlli, SGSN_NSEI); - OSMO_ASSERT(other_info); - link_info = gbproxy_link_info_by_sgsn_tlli(peer, local_sgsn_tlli, SGSN2_NSEI); - OSMO_ASSERT(link_info); - OSMO_ASSERT(link_info != other_info); - OSMO_ASSERT(link_info->tlli.current == local_bss_tlli3); - OSMO_ASSERT(link_info->tlli.assigned == 0); - OSMO_ASSERT(link_info->sgsn_tlli.current == local_sgsn_tlli); - OSMO_ASSERT(link_info->sgsn_tlli.assigned == 0); - - - printf("--- Shutdown GPRS connection (SGSN 1) ---\n\n"); - - /* Detach */ - send_llc_ul_ui(nsi, "DETACH REQ", &bss_peer[0], 0x1002, - local_bss_tlli, &rai_bss, cell_id, - GPRS_SAPI_GMM, bss_nu++, - dtap_detach_req, sizeof(dtap_detach_req)); - - dump_peers(stdout, 0, 0, &gbcfg); - - send_llc_dl_ui(nsi, "DETACH ACC", &sgsn_peer[0], 0x1002, - local_sgsn_tlli, 1, imsi1, sizeof(imsi1), - GPRS_SAPI_GMM, sgsn_nu++, - dtap_detach_acc, sizeof(dtap_detach_acc)); - - dump_peers(stdout, 0, 0, &gbcfg); - - printf("--- Shutdown GPRS connection (SGSN 2) ---\n\n"); - - send_llc_ul_ui(nsi, "DETACH REQ", &bss_peer[0], 0x1002, - local_bss_tlli2, &rai_bss, cell_id, - GPRS_SAPI_GMM, bss_nu++, - dtap_detach_req, sizeof(dtap_detach_req)); - - dump_peers(stdout, 0, 0, &gbcfg); - - send_llc_dl_ui(nsi, "DETACH ACC", &sgsn_peer[1], 0x1002, - local_sgsn_tlli2, 1, imsi2, sizeof(imsi2), - GPRS_SAPI_GMM, sgsn_nu++, - dtap_detach_acc, sizeof(dtap_detach_acc)); - - dump_peers(stdout, 0, 0, &gbcfg); - - printf("--- Shutdown GPRS connection (SGSN 2, P-TMSI 1) ---\n\n"); - - send_llc_ul_ui(nsi, "DETACH REQ", &bss_peer[0], 0x1002, - local_bss_tlli3, &rai_bss, cell_id, - GPRS_SAPI_GMM, bss_nu++, - dtap_detach_req, sizeof(dtap_detach_req)); - - dump_peers(stdout, 0, 0, &gbcfg); - - send_llc_dl_ui(nsi, "DETACH ACC", &sgsn_peer[1], 0x1002, - local_sgsn_tlli, 1, imsi3, sizeof(imsi3), - GPRS_SAPI_GMM, sgsn_nu++, - dtap_detach_acc, sizeof(dtap_detach_acc)); - - dump_peers(stdout, 0, 0, &gbcfg); - - dump_global(stdout, 0); - - talloc_free(gbcfg.core_apn); - gbcfg.core_apn = NULL; - - gbproxy_clear_patch_filter(&gbcfg.matches[GBPROX_MATCH_ROUTING]); - gbprox_reset(&gbcfg); - gprs_ns_destroy(nsi); - nsi = NULL; - - cleanup_test(); -} - -static void test_gbproxy_keep_info() -{ - struct gprs_ns_inst *nsi = gprs_ns_instantiate(gprs_ns_callback, tall_sgsn_ctx); - struct sockaddr_in bss_peer[1] = {{0},}; - struct sockaddr_in sgsn_peer= {0}; - struct gprs_ra_id rai_bss = - {.mcc = 112, .mnc = 332, .lac = 16464, .rac = 96}; - uint16_t cell_id = 0x1234; - - const uint32_t ptmsi = 0xefe2b700; - const uint32_t local_tlli = 0xefe2b700; - const uint32_t foreign_tlli = 0xafe2b700; - - const uint8_t imsi[] = {0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0xf8}; - struct gbproxy_link_info *link_info, *link_info2; - struct gbproxy_peer *peer; - unsigned bss_nu = 0; - unsigned sgsn_nu = 0; - - LLIST_HEAD(rcv_list); - - OSMO_ASSERT(local_tlli == gprs_tmsi2tlli(ptmsi, TLLI_LOCAL)); - - bssgp_nsi = nsi; - gbcfg.nsi = bssgp_nsi; - gbcfg.nsip_sgsn_nsei = SGSN_NSEI; - gbcfg.patch_ptmsi = 0; - gbcfg.acquire_imsi = 1; - gbcfg.core_plmn = (struct osmo_plmn_id){}; - gbcfg.core_apn = NULL; - gbcfg.core_apn_size = 0; - gbcfg.route_to_sgsn2 = 0; - gbcfg.nsip_sgsn2_nsei = 0xffff; - gbcfg.keep_link_infos = GBPROX_KEEP_ALWAYS; - - configure_sgsn_peer(&sgsn_peer); - configure_bss_peers(bss_peer, ARRAY_SIZE(bss_peer)); - - printf("=== %s ===\n", __func__); - printf("--- Initialise SGSN ---\n\n"); - - connect_sgsn(nsi, &sgsn_peer, SGSN_NSEI); - - printf("--- Initialise BSS 1 ---\n\n"); - - setup_ns(nsi, &bss_peer[0], 0x1001, 0x1000); - setup_bssgp(nsi, &bss_peer[0], 0x1002); - - peer = gbproxy_peer_by_nsei(&gbcfg, 0x1000); - OSMO_ASSERT(peer != NULL); - - send_bssgp_reset_ack(nsi, &sgsn_peer, 0x1002); - - gprs_dump_nsi(nsi); - dump_global(stdout, 0); - dump_peers(stdout, 0, 0, &gbcfg); - - printf("--- Send message from BSS 1 to SGSN, BVCI 0x1002 ---\n\n"); - - received_messages = &rcv_list; - - send_llc_ul_ui(nsi, "ATTACH REQUEST", &bss_peer[0], 0x1002, - foreign_tlli, &rai_bss, cell_id, - GPRS_SAPI_GMM, bss_nu++, - dtap_attach_req, sizeof(dtap_attach_req)); - - OSMO_ASSERT(expect_gmm_msg(0x1000, 0x1002, GSM48_MT_GMM_ID_REQ)); - - dump_peers(stdout, 0, 0, &gbcfg); - - link_info = gbproxy_link_info_by_tlli(peer, foreign_tlli); - OSMO_ASSERT(link_info); - OSMO_ASSERT(link_info->imsi_len == 0); - OSMO_ASSERT(!link_info->is_deregistered); - OSMO_ASSERT(link_info->imsi_acq_pending); - - send_llc_ul_ui(nsi, "IDENT RESPONSE", &bss_peer[0], 0x1002, - foreign_tlli, &rai_bss, cell_id, - GPRS_SAPI_GMM, bss_nu++, - dtap_identity_resp, sizeof(dtap_identity_resp)); - - OSMO_ASSERT(expect_gmm_msg(SGSN_NSEI, 0x1002, GSM48_MT_GMM_ATTACH_REQ)); - - dump_peers(stdout, 0, 0, &gbcfg); - - link_info = gbproxy_link_info_by_tlli(peer, foreign_tlli); - OSMO_ASSERT(link_info); - OSMO_ASSERT(link_info->imsi_len > 0); - OSMO_ASSERT(!link_info->imsi_acq_pending); - OSMO_ASSERT(gprs_tlli_type(link_info->sgsn_tlli.current) == TLLI_FOREIGN); - - send_llc_dl_ui(nsi, "IDENT REQUEST", &sgsn_peer, 0x1002, - foreign_tlli, 0, NULL, 0, - GPRS_SAPI_GMM, sgsn_nu++, - dtap_identity_req, sizeof(dtap_identity_req)); - - OSMO_ASSERT(expect_gmm_msg(0x1000, 0x1002, GSM48_MT_GMM_ID_REQ)); - - dump_peers(stdout, 0, 0, &gbcfg); - - send_llc_ul_ui(nsi, "IDENT RESPONSE", &bss_peer[0], 0x1002, - foreign_tlli, &rai_bss, cell_id, - GPRS_SAPI_GMM, bss_nu++, - dtap_identity_resp, sizeof(dtap_identity_resp)); - - OSMO_ASSERT(expect_gmm_msg(SGSN_NSEI, 0x1002, GSM48_MT_GMM_ID_RESP)); - - dump_peers(stdout, 0, 0, &gbcfg); - - link_info = gbproxy_link_info_by_tlli(peer, foreign_tlli); - OSMO_ASSERT(link_info); - OSMO_ASSERT(link_info->imsi_len > 0); - OSMO_ASSERT(gbproxy_link_info_by_imsi(peer, imsi, sizeof(imsi))); - - send_llc_dl_ui(nsi, "ATTACH ACCEPT", &sgsn_peer, 0x1002, - foreign_tlli, 1, imsi, sizeof(imsi), - GPRS_SAPI_GMM, sgsn_nu++, - dtap_attach_acc, sizeof(dtap_attach_acc)); - - OSMO_ASSERT(expect_gmm_msg(0x1000, 0x1002, GSM48_MT_GMM_ATTACH_ACK)); - - dump_peers(stdout, 0, 0, &gbcfg); - - send_llc_ul_ui(nsi, "ATTACH COMPLETE", &bss_peer[0], 0x1002, - local_tlli, &rai_bss, cell_id, - GPRS_SAPI_GMM, bss_nu++, - dtap_attach_complete, sizeof(dtap_attach_complete)); - - OSMO_ASSERT(expect_gmm_msg(SGSN_NSEI, 0x1002, GSM48_MT_GMM_ATTACH_COMPL)); - - dump_peers(stdout, 0, 0, &gbcfg); - - send_llc_dl_ui(nsi, "GMM INFO", &sgsn_peer, 0x1002, - local_tlli, 1, imsi, sizeof(imsi), - GPRS_SAPI_GMM, sgsn_nu++, - dtap_gmm_information, sizeof(dtap_gmm_information)); - - OSMO_ASSERT(expect_gmm_msg(0x1000, 0x1002, GSM48_MT_GMM_INFO)); - - dump_peers(stdout, 0, 0, &gbcfg); - - link_info = gbproxy_link_info_by_tlli(peer, local_tlli); - OSMO_ASSERT(link_info); - - /* Detach (MO) */ - send_llc_ul_ui(nsi, "DETACH REQ", &bss_peer[0], 0x1002, - local_tlli, &rai_bss, cell_id, - GPRS_SAPI_GMM, bss_nu++, - dtap_detach_req, sizeof(dtap_detach_req)); - - OSMO_ASSERT(expect_gmm_msg(SGSN_NSEI, 0x1002, GSM48_MT_GMM_DETACH_REQ)); - - link_info = gbproxy_link_info_by_tlli(peer, local_tlli); - OSMO_ASSERT(link_info); - - dump_peers(stdout, 0, 0, &gbcfg); - - send_llc_dl_ui(nsi, "DETACH ACC", &sgsn_peer, 0x1002, - local_tlli, 1, imsi, sizeof(imsi), - GPRS_SAPI_GMM, sgsn_nu++, - dtap_detach_acc, sizeof(dtap_detach_acc)); - - OSMO_ASSERT(expect_gmm_msg(0x1000, 0x1002, GSM48_MT_GMM_DETACH_ACK)); - - dump_peers(stdout, 0, 0, &gbcfg); - - OSMO_ASSERT(!gbproxy_link_info_by_tlli(peer, local_tlli)); - link_info = gbproxy_link_info_by_imsi(peer, imsi, sizeof(imsi)); - OSMO_ASSERT(link_info); - OSMO_ASSERT(link_info->is_deregistered); - - OSMO_ASSERT(!expect_msg()); - - /* Re-Attach */ - send_llc_ul_ui(nsi, "ATTACH REQUEST", &bss_peer[0], 0x1002, - foreign_tlli, &rai_bss, cell_id, - GPRS_SAPI_GMM, bss_nu++, - dtap_attach_req3, sizeof(dtap_attach_req3)); - - OSMO_ASSERT(expect_gmm_msg(SGSN_NSEI, 0x1002, GSM48_MT_GMM_ATTACH_REQ)); - - dump_peers(stdout, 0, 0, &gbcfg); - - link_info2 = gbproxy_link_info_by_imsi(peer, imsi, sizeof(imsi)); - link_info = gbproxy_link_info_by_tlli(peer, foreign_tlli); - OSMO_ASSERT(link_info); - OSMO_ASSERT(link_info == link_info2); - OSMO_ASSERT(link_info->imsi_len != 0); - OSMO_ASSERT(!link_info->is_deregistered); - OSMO_ASSERT(!link_info->imsi_acq_pending); - OSMO_ASSERT(gprs_tlli_type(link_info->sgsn_tlli.current) == TLLI_FOREIGN); - - send_llc_dl_ui(nsi, "ATTACH ACCEPT", &sgsn_peer, 0x1002, - foreign_tlli, 1, imsi, sizeof(imsi), - GPRS_SAPI_GMM, sgsn_nu++, - dtap_attach_acc, sizeof(dtap_attach_acc)); - - OSMO_ASSERT(expect_gmm_msg(0x1000, 0x1002, GSM48_MT_GMM_ATTACH_ACK)); - - dump_peers(stdout, 0, 0, &gbcfg); - - send_llc_ul_ui(nsi, "ATTACH COMPLETE", &bss_peer[0], 0x1002, - local_tlli, &rai_bss, cell_id, - GPRS_SAPI_GMM, bss_nu++, - dtap_attach_complete, sizeof(dtap_attach_complete)); - - OSMO_ASSERT(expect_gmm_msg(SGSN_NSEI, 0x1002, GSM48_MT_GMM_ATTACH_COMPL)); - - dump_peers(stdout, 0, 0, &gbcfg); - - /* Detach (MT) */ - send_llc_dl_ui(nsi, "DETACH REQ (re-attach)", &sgsn_peer, 0x1002, - local_tlli, 1, imsi, sizeof(imsi), - GPRS_SAPI_GMM, sgsn_nu++, - dtap_mt_detach_rea_req, sizeof(dtap_mt_detach_rea_req)); - - OSMO_ASSERT(expect_gmm_msg(0x1000, 0x1002, GSM48_MT_GMM_DETACH_REQ)); - - dump_peers(stdout, 0, 0, &gbcfg); - - link_info = gbproxy_link_info_by_tlli(peer, local_tlli); - OSMO_ASSERT(link_info); - - send_llc_ul_ui(nsi, "DETACH ACC", &bss_peer[0], 0x1002, - local_tlli, &rai_bss, cell_id, - GPRS_SAPI_GMM, bss_nu++, - dtap_mt_detach_acc, sizeof(dtap_mt_detach_acc)); - - OSMO_ASSERT(expect_gmm_msg(SGSN_NSEI, 0x1002, GSM48_MT_GMM_DETACH_ACK)); - OSMO_ASSERT(!expect_msg()); - - dump_peers(stdout, 0, 0, &gbcfg); - - OSMO_ASSERT(!gbproxy_link_info_by_tlli(peer, local_tlli)); - link_info = gbproxy_link_info_by_imsi(peer, imsi, sizeof(imsi)); - OSMO_ASSERT(link_info); - OSMO_ASSERT(link_info->is_deregistered); - - /* Re-Attach */ - send_llc_ul_ui(nsi, "ATTACH REQUEST", &bss_peer[0], 0x1002, - foreign_tlli, &rai_bss, cell_id, - GPRS_SAPI_GMM, bss_nu++, - dtap_attach_req3, sizeof(dtap_attach_req3)); - - OSMO_ASSERT(expect_gmm_msg(SGSN_NSEI, 0x1002, GSM48_MT_GMM_ATTACH_REQ)); - - dump_peers(stdout, 0, 0, &gbcfg); - - link_info2 = gbproxy_link_info_by_imsi(peer, imsi, sizeof(imsi)); - link_info = gbproxy_link_info_by_tlli(peer, foreign_tlli); - OSMO_ASSERT(link_info); - OSMO_ASSERT(link_info == link_info2); - OSMO_ASSERT(link_info->imsi_len != 0); - OSMO_ASSERT(!link_info->is_deregistered); - OSMO_ASSERT(!link_info->imsi_acq_pending); - - send_llc_dl_ui(nsi, "ATTACH ACCEPT", &sgsn_peer, 0x1002, - foreign_tlli, 1, imsi, sizeof(imsi), - GPRS_SAPI_GMM, sgsn_nu++, - dtap_attach_acc, sizeof(dtap_attach_acc)); - - OSMO_ASSERT(expect_gmm_msg(0x1000, 0x1002, GSM48_MT_GMM_ATTACH_ACK)); - - dump_peers(stdout, 0, 0, &gbcfg); - - send_llc_ul_ui(nsi, "ATTACH COMPLETE", &bss_peer[0], 0x1002, - local_tlli, &rai_bss, cell_id, - GPRS_SAPI_GMM, bss_nu++, - dtap_attach_complete, sizeof(dtap_attach_complete)); - - OSMO_ASSERT(expect_gmm_msg(SGSN_NSEI, 0x1002, GSM48_MT_GMM_ATTACH_COMPL)); - - dump_peers(stdout, 0, 0, &gbcfg); - - /* Detach (MT) */ - send_llc_dl_ui(nsi, "DETACH REQ", &sgsn_peer, 0x1002, - local_tlli, 1, imsi, sizeof(imsi), - GPRS_SAPI_GMM, sgsn_nu++, - dtap_mt_detach_req, sizeof(dtap_mt_detach_req)); - - OSMO_ASSERT(expect_gmm_msg(0x1000, 0x1002, GSM48_MT_GMM_DETACH_REQ)); - - dump_peers(stdout, 0, 0, &gbcfg); - - link_info = gbproxy_link_info_by_tlli(peer, local_tlli); - OSMO_ASSERT(link_info); - - send_llc_ul_ui(nsi, "DETACH ACC", &bss_peer[0], 0x1002, - local_tlli, &rai_bss, cell_id, - GPRS_SAPI_GMM, bss_nu++, - dtap_mt_detach_acc, sizeof(dtap_mt_detach_acc)); - - OSMO_ASSERT(expect_gmm_msg(SGSN_NSEI, 0x1002, GSM48_MT_GMM_DETACH_ACK)); - OSMO_ASSERT(!expect_msg()); - - dump_peers(stdout, 0, 0, &gbcfg); - - OSMO_ASSERT(!gbproxy_link_info_by_tlli(peer, local_tlli)); - link_info = gbproxy_link_info_by_imsi(peer, imsi, sizeof(imsi)); - OSMO_ASSERT(link_info); - OSMO_ASSERT(link_info->is_deregistered); - - /* Re-Attach with IMSI */ - send_llc_ul_ui(nsi, "ATTACH REQUEST (IMSI)", &bss_peer[0], 0x1002, - foreign_tlli, &rai_bss, cell_id, - GPRS_SAPI_GMM, bss_nu++, - dtap_attach_req4, sizeof(dtap_attach_req4)); - - OSMO_ASSERT(expect_gmm_msg(SGSN_NSEI, 0x1002, GSM48_MT_GMM_ATTACH_REQ)); - - dump_peers(stdout, 0, 0, &gbcfg); - - link_info2 = gbproxy_link_info_by_imsi(peer, imsi, sizeof(imsi)); - link_info = gbproxy_link_info_by_tlli(peer, foreign_tlli); - OSMO_ASSERT(link_info); - OSMO_ASSERT(link_info == link_info2); - OSMO_ASSERT(link_info->imsi_len != 0); - OSMO_ASSERT(!link_info->is_deregistered); - OSMO_ASSERT(!link_info->imsi_acq_pending); - OSMO_ASSERT(link_info->sgsn_tlli.current == foreign_tlli); - - send_llc_dl_ui(nsi, "ATTACH ACCEPT", &sgsn_peer, 0x1002, - foreign_tlli, 1, imsi, sizeof(imsi), - GPRS_SAPI_GMM, sgsn_nu++, - dtap_attach_acc, sizeof(dtap_attach_acc)); - - OSMO_ASSERT(expect_gmm_msg(0x1000, 0x1002, GSM48_MT_GMM_ATTACH_ACK)); - - dump_peers(stdout, 0, 0, &gbcfg); - - send_llc_ul_ui(nsi, "ATTACH COMPLETE", &bss_peer[0], 0x1002, - local_tlli, &rai_bss, cell_id, - GPRS_SAPI_GMM, bss_nu++, - dtap_attach_complete, sizeof(dtap_attach_complete)); - - OSMO_ASSERT(expect_gmm_msg(SGSN_NSEI, 0x1002, GSM48_MT_GMM_ATTACH_COMPL)); - - dump_peers(stdout, 0, 0, &gbcfg); - - /* Detach (MT) */ - send_llc_dl_ui(nsi, "DETACH REQ", &sgsn_peer, 0x1002, - local_tlli, 1, imsi, sizeof(imsi), - GPRS_SAPI_GMM, sgsn_nu++, - dtap_mt_detach_req, sizeof(dtap_mt_detach_req)); - - OSMO_ASSERT(expect_gmm_msg(0x1000, 0x1002, GSM48_MT_GMM_DETACH_REQ)); - - dump_peers(stdout, 0, 0, &gbcfg); - - link_info = gbproxy_link_info_by_tlli(peer, local_tlli); - OSMO_ASSERT(link_info); - - send_llc_ul_ui(nsi, "DETACH ACC", &bss_peer[0], 0x1002, - local_tlli, &rai_bss, cell_id, - GPRS_SAPI_GMM, bss_nu++, - dtap_mt_detach_acc, sizeof(dtap_mt_detach_acc)); - - OSMO_ASSERT(expect_gmm_msg(SGSN_NSEI, 0x1002, GSM48_MT_GMM_DETACH_ACK)); - OSMO_ASSERT(!expect_msg()); - - dump_peers(stdout, 0, 0, &gbcfg); - - OSMO_ASSERT(!gbproxy_link_info_by_tlli(peer, local_tlli)); - link_info = gbproxy_link_info_by_imsi(peer, imsi, sizeof(imsi)); - OSMO_ASSERT(link_info); - OSMO_ASSERT(link_info->is_deregistered); - - /* Re-Attach */ - send_llc_ul_ui(nsi, "ATTACH REQUEST", &bss_peer[0], 0x1002, - foreign_tlli, &rai_bss, cell_id, - GPRS_SAPI_GMM, bss_nu++, - dtap_attach_req3, sizeof(dtap_attach_req3)); - - OSMO_ASSERT(expect_gmm_msg(SGSN_NSEI, 0x1002, GSM48_MT_GMM_ATTACH_REQ)); - - dump_peers(stdout, 0, 0, &gbcfg); - - link_info2 = gbproxy_link_info_by_imsi(peer, imsi, sizeof(imsi)); - link_info = gbproxy_link_info_by_tlli(peer, foreign_tlli); - OSMO_ASSERT(link_info); - OSMO_ASSERT(link_info == link_info2); - OSMO_ASSERT(link_info->imsi_len != 0); - OSMO_ASSERT(!link_info->is_deregistered); - OSMO_ASSERT(!link_info->imsi_acq_pending); - - send_llc_dl_ui(nsi, "ATTACH ACCEPT", &sgsn_peer, 0x1002, - foreign_tlli, 1, imsi, sizeof(imsi), - GPRS_SAPI_GMM, sgsn_nu++, - dtap_attach_acc, sizeof(dtap_attach_acc)); - - OSMO_ASSERT(expect_gmm_msg(0x1000, 0x1002, GSM48_MT_GMM_ATTACH_ACK)); - - dump_peers(stdout, 0, 0, &gbcfg); - - send_llc_ul_ui(nsi, "ATTACH COMPLETE", &bss_peer[0], 0x1002, - local_tlli, &rai_bss, cell_id, - GPRS_SAPI_GMM, bss_nu++, - dtap_attach_complete, sizeof(dtap_attach_complete)); - - OSMO_ASSERT(expect_gmm_msg(SGSN_NSEI, 0x1002, GSM48_MT_GMM_ATTACH_COMPL)); - - dump_peers(stdout, 0, 0, &gbcfg); - - /* RA update procedure (reject -> Detach) */ - send_llc_ul_ui(nsi, "RA UPD REQ", &bss_peer[0], 0x1002, - local_tlli, &rai_bss, 0x7080, - GPRS_SAPI_GMM, bss_nu++, - dtap_ra_upd_req, sizeof(dtap_ra_upd_req)); - - OSMO_ASSERT(expect_gmm_msg(SGSN_NSEI, 0x1002, GSM48_MT_GMM_RA_UPD_REQ)); - - send_llc_dl_ui(nsi, "RA UDP REJ", &sgsn_peer, 0x1002, - local_tlli, 1, imsi, sizeof(imsi), - GPRS_SAPI_GMM, sgsn_nu++, - dtap_ra_upd_rej, sizeof(dtap_ra_upd_rej)); - - OSMO_ASSERT(expect_gmm_msg(0x1000, 0x1002, GSM48_MT_GMM_RA_UPD_REJ)); - OSMO_ASSERT(!expect_msg()); - - dump_peers(stdout, 0, 0, &gbcfg); - - OSMO_ASSERT(!gbproxy_link_info_by_tlli(peer, local_tlli)); - link_info = gbproxy_link_info_by_imsi(peer, imsi, sizeof(imsi)); - OSMO_ASSERT(link_info); - OSMO_ASSERT(link_info->is_deregistered); - - /* Bad case: Re-Attach with wrong (initial) P-TMSI */ - send_llc_ul_ui(nsi, "ATTACH REQUEST", &bss_peer[0], 0x1002, - foreign_tlli, &rai_bss, cell_id, - GPRS_SAPI_GMM, bss_nu++, - dtap_attach_req, sizeof(dtap_attach_req)); - - OSMO_ASSERT(expect_gmm_msg(0x1000, 0x1002, GSM48_MT_GMM_ID_REQ)); - - dump_peers(stdout, 0, 0, &gbcfg); - - link_info2 = gbproxy_link_info_by_imsi(peer, imsi, sizeof(imsi)); - link_info = gbproxy_link_info_by_tlli(peer, foreign_tlli); - OSMO_ASSERT(link_info); - OSMO_ASSERT(link_info != link_info2); - OSMO_ASSERT(link_info->imsi_len == 0); - OSMO_ASSERT(!link_info->is_deregistered); - OSMO_ASSERT(link_info->imsi_acq_pending); - - send_llc_ul_ui(nsi, "IDENT RESPONSE", &bss_peer[0], 0x1002, - foreign_tlli, &rai_bss, cell_id, - GPRS_SAPI_GMM, bss_nu++, - dtap_identity_resp, sizeof(dtap_identity_resp)); - - OSMO_ASSERT(expect_gmm_msg(SGSN_NSEI, 0x1002, GSM48_MT_GMM_ATTACH_REQ)); - - dump_peers(stdout, 0, 0, &gbcfg); - - link_info2 = gbproxy_link_info_by_imsi(peer, imsi, sizeof(imsi)); - link_info = gbproxy_link_info_by_tlli(peer, foreign_tlli); - OSMO_ASSERT(link_info); - OSMO_ASSERT(link_info == link_info2); - OSMO_ASSERT(link_info->imsi_len != 0); - OSMO_ASSERT(!link_info->is_deregistered); - OSMO_ASSERT(!link_info->imsi_acq_pending); - - send_llc_dl_ui(nsi, "ATTACH ACCEPT", &sgsn_peer, 0x1002, - foreign_tlli, 1, imsi, sizeof(imsi), - GPRS_SAPI_GMM, sgsn_nu++, - dtap_attach_acc, sizeof(dtap_attach_acc)); - - OSMO_ASSERT(expect_gmm_msg(0x1000, 0x1002, GSM48_MT_GMM_ATTACH_ACK)); - - dump_peers(stdout, 0, 0, &gbcfg); - - link_info2 = gbproxy_link_info_by_imsi(peer, imsi, sizeof(imsi)); - link_info = gbproxy_link_info_by_tlli(peer, foreign_tlli); - OSMO_ASSERT(link_info); - OSMO_ASSERT(link_info == link_info2); - OSMO_ASSERT(link_info->imsi_len > 0); - - send_llc_ul_ui(nsi, "ATTACH COMPLETE", &bss_peer[0], 0x1002, - local_tlli, &rai_bss, cell_id, - GPRS_SAPI_GMM, bss_nu++, - dtap_attach_complete, sizeof(dtap_attach_complete)); - - OSMO_ASSERT(expect_gmm_msg(SGSN_NSEI, 0x1002, GSM48_MT_GMM_ATTACH_COMPL)); - - dump_peers(stdout, 0, 0, &gbcfg); - - /* Detach (MT) */ - send_llc_dl_ui(nsi, "DETACH REQ", &sgsn_peer, 0x1002, - local_tlli, 1, imsi, sizeof(imsi), - GPRS_SAPI_GMM, sgsn_nu++, - dtap_mt_detach_req, sizeof(dtap_mt_detach_req)); - - OSMO_ASSERT(expect_gmm_msg(0x1000, 0x1002, GSM48_MT_GMM_DETACH_REQ)); - - dump_peers(stdout, 0, 0, &gbcfg); - - link_info = gbproxy_link_info_by_tlli(peer, local_tlli); - OSMO_ASSERT(link_info); - - send_llc_ul_ui(nsi, "DETACH ACC", &bss_peer[0], 0x1002, - local_tlli, &rai_bss, cell_id, - GPRS_SAPI_GMM, bss_nu++, - dtap_mt_detach_acc, sizeof(dtap_mt_detach_acc)); - - OSMO_ASSERT(expect_gmm_msg(SGSN_NSEI, 0x1002, GSM48_MT_GMM_DETACH_ACK)); - - dump_peers(stdout, 0, 0, &gbcfg); - - OSMO_ASSERT(!gbproxy_link_info_by_tlli(peer, local_tlli)); - link_info = gbproxy_link_info_by_imsi(peer, imsi, sizeof(imsi)); - OSMO_ASSERT(link_info); - OSMO_ASSERT(link_info->is_deregistered); - - OSMO_ASSERT(!expect_msg()); - - /* Bad case: Re-Attach with local TLLI */ - send_llc_ul_ui(nsi, "ATTACH REQUEST (local TLLI)", &bss_peer[0], 0x1002, - local_tlli, &rai_bss, cell_id, - GPRS_SAPI_GMM, bss_nu++, - dtap_attach_req3, sizeof(dtap_attach_req3)); - - OSMO_ASSERT(expect_gmm_msg(SGSN_NSEI, 0x1002, GSM48_MT_GMM_ATTACH_REQ)); - - dump_peers(stdout, 0, 0, &gbcfg); - - link_info2 = gbproxy_link_info_by_imsi(peer, imsi, sizeof(imsi)); - link_info = gbproxy_link_info_by_tlli(peer, local_tlli); - OSMO_ASSERT(link_info); - OSMO_ASSERT(link_info == link_info2); - OSMO_ASSERT(link_info->imsi_len != 0); - OSMO_ASSERT(!link_info->is_deregistered); - OSMO_ASSERT(!link_info->imsi_acq_pending); - OSMO_ASSERT(link_info->sgsn_tlli.current == local_tlli); - - send_llc_dl_ui(nsi, "ATTACH ACCEPT", &sgsn_peer, 0x1002, - local_tlli, 1, imsi, sizeof(imsi), - GPRS_SAPI_GMM, sgsn_nu++, - dtap_attach_acc, sizeof(dtap_attach_acc)); - - OSMO_ASSERT(expect_gmm_msg(0x1000, 0x1002, GSM48_MT_GMM_ATTACH_ACK)); - - dump_peers(stdout, 0, 0, &gbcfg); - - send_llc_ul_ui(nsi, "ATTACH COMPLETE", &bss_peer[0], 0x1002, - local_tlli, &rai_bss, cell_id, - GPRS_SAPI_GMM, bss_nu++, - dtap_attach_complete, sizeof(dtap_attach_complete)); - - OSMO_ASSERT(expect_gmm_msg(SGSN_NSEI, 0x1002, GSM48_MT_GMM_ATTACH_COMPL)); - - dump_peers(stdout, 0, 0, &gbcfg); - - /* Detach (MT) */ - send_llc_dl_ui(nsi, "DETACH REQ (re-attach)", &sgsn_peer, 0x1002, - local_tlli, 1, imsi, sizeof(imsi), - GPRS_SAPI_GMM, sgsn_nu++, - dtap_mt_detach_rea_req, sizeof(dtap_mt_detach_rea_req)); - - OSMO_ASSERT(expect_gmm_msg(0x1000, 0x1002, GSM48_MT_GMM_DETACH_REQ)); - - dump_peers(stdout, 0, 0, &gbcfg); - - link_info = gbproxy_link_info_by_tlli(peer, local_tlli); - OSMO_ASSERT(link_info); - - send_llc_ul_ui(nsi, "DETACH ACC", &bss_peer[0], 0x1002, - local_tlli, &rai_bss, cell_id, - GPRS_SAPI_GMM, bss_nu++, - dtap_mt_detach_acc, sizeof(dtap_mt_detach_acc)); - - OSMO_ASSERT(expect_gmm_msg(SGSN_NSEI, 0x1002, GSM48_MT_GMM_DETACH_ACK)); - OSMO_ASSERT(!expect_msg()); - - dump_peers(stdout, 0, 0, &gbcfg); - - OSMO_ASSERT(!gbproxy_link_info_by_tlli(peer, local_tlli)); - link_info = gbproxy_link_info_by_imsi(peer, imsi, sizeof(imsi)); - OSMO_ASSERT(link_info); - OSMO_ASSERT(link_info->is_deregistered); - - /* Bad case: Unexpected Re-Attach with IMSI after completed attachment - * procedure */ - send_llc_ul_ui(nsi, "ATTACH REQUEST", &bss_peer[0], 0x1002, - foreign_tlli, &rai_bss, cell_id, - GPRS_SAPI_GMM, bss_nu++, - dtap_attach_req3, sizeof(dtap_attach_req3)); - - OSMO_ASSERT(expect_gmm_msg(SGSN_NSEI, 0x1002, GSM48_MT_GMM_ATTACH_REQ)); - - dump_peers(stdout, 0, 0, &gbcfg); - - link_info2 = gbproxy_link_info_by_imsi(peer, imsi, sizeof(imsi)); - link_info = gbproxy_link_info_by_tlli(peer, foreign_tlli); - OSMO_ASSERT(link_info); - OSMO_ASSERT(link_info == link_info2); - OSMO_ASSERT(link_info->imsi_len != 0); - OSMO_ASSERT(!link_info->is_deregistered); - OSMO_ASSERT(!link_info->imsi_acq_pending); - - send_llc_dl_ui(nsi, "ATTACH ACCEPT", &sgsn_peer, 0x1002, - foreign_tlli, 1, imsi, sizeof(imsi), - GPRS_SAPI_GMM, sgsn_nu++, - dtap_attach_acc, sizeof(dtap_attach_acc)); - - OSMO_ASSERT(expect_gmm_msg(0x1000, 0x1002, GSM48_MT_GMM_ATTACH_ACK)); - - dump_peers(stdout, 0, 0, &gbcfg); - - send_llc_ul_ui(nsi, "ATTACH COMPLETE", &bss_peer[0], 0x1002, - local_tlli, &rai_bss, cell_id, - GPRS_SAPI_GMM, bss_nu++, - dtap_attach_complete, sizeof(dtap_attach_complete)); - - OSMO_ASSERT(expect_gmm_msg(SGSN_NSEI, 0x1002, GSM48_MT_GMM_ATTACH_COMPL)); - - dump_peers(stdout, 0, 0, &gbcfg); - - send_llc_dl_ui(nsi, "GMM INFO", &sgsn_peer, 0x1002, - local_tlli, 1, imsi, sizeof(imsi), - GPRS_SAPI_GMM, sgsn_nu++, - dtap_gmm_information, sizeof(dtap_gmm_information)); - - OSMO_ASSERT(expect_gmm_msg(0x1000, 0x1002, GSM48_MT_GMM_INFO)); - - dump_peers(stdout, 0, 0, &gbcfg); - - send_llc_ul_ui(nsi, "ATTACH REQUEST (unexpected, IMSI)", - &bss_peer[0], 0x1002, - foreign_tlli, &rai_bss, cell_id, - GPRS_SAPI_GMM, bss_nu++, - dtap_attach_req4, sizeof(dtap_attach_req4)); - - OSMO_ASSERT(expect_gmm_msg(SGSN_NSEI, 0x1002, GSM48_MT_GMM_ATTACH_REQ)); - - dump_peers(stdout, 0, 0, &gbcfg); - - link_info2 = gbproxy_link_info_by_imsi(peer, imsi, sizeof(imsi)); - link_info = gbproxy_link_info_by_tlli(peer, foreign_tlli); - OSMO_ASSERT(link_info); - OSMO_ASSERT(link_info == link_info2); - OSMO_ASSERT(link_info->imsi_len != 0); - OSMO_ASSERT(!link_info->is_deregistered); - OSMO_ASSERT(!link_info->imsi_acq_pending); - OSMO_ASSERT(link_info->sgsn_tlli.current == foreign_tlli); - OSMO_ASSERT(link_info->sgsn_tlli.assigned == 0); - - send_llc_dl_ui(nsi, "ATTACH ACCEPT", &sgsn_peer, 0x1002, - foreign_tlli, 1, imsi, sizeof(imsi), - GPRS_SAPI_GMM, sgsn_nu++, - dtap_attach_acc, sizeof(dtap_attach_acc)); - - OSMO_ASSERT(expect_gmm_msg(0x1000, 0x1002, GSM48_MT_GMM_ATTACH_ACK)); - - dump_peers(stdout, 0, 0, &gbcfg); - - send_llc_ul_ui(nsi, "ATTACH COMPLETE", &bss_peer[0], 0x1002, - local_tlli, &rai_bss, cell_id, - GPRS_SAPI_GMM, bss_nu++, - dtap_attach_complete, sizeof(dtap_attach_complete)); - - OSMO_ASSERT(expect_gmm_msg(SGSN_NSEI, 0x1002, GSM48_MT_GMM_ATTACH_COMPL)); - - dump_peers(stdout, 0, 0, &gbcfg); - - /* Detach (MT) */ - send_llc_dl_ui(nsi, "DETACH REQ", &sgsn_peer, 0x1002, - local_tlli, 1, imsi, sizeof(imsi), - GPRS_SAPI_GMM, sgsn_nu++, - dtap_mt_detach_req, sizeof(dtap_mt_detach_req)); - - OSMO_ASSERT(expect_gmm_msg(0x1000, 0x1002, GSM48_MT_GMM_DETACH_REQ)); - - dump_peers(stdout, 0, 0, &gbcfg); - - link_info = gbproxy_link_info_by_tlli(peer, local_tlli); - OSMO_ASSERT(link_info); - - send_llc_ul_ui(nsi, "DETACH ACC", &bss_peer[0], 0x1002, - local_tlli, &rai_bss, cell_id, - GPRS_SAPI_GMM, bss_nu++, - dtap_mt_detach_acc, sizeof(dtap_mt_detach_acc)); - - OSMO_ASSERT(expect_gmm_msg(SGSN_NSEI, 0x1002, GSM48_MT_GMM_DETACH_ACK)); - OSMO_ASSERT(!expect_msg()); - - dump_peers(stdout, 0, 0, &gbcfg); - - OSMO_ASSERT(!gbproxy_link_info_by_tlli(peer, local_tlli)); - link_info = gbproxy_link_info_by_imsi(peer, imsi, sizeof(imsi)); - OSMO_ASSERT(link_info); - OSMO_ASSERT(link_info->is_deregistered); - - /* Bad case: Unexpected Re-Attach with P-TMSI after completed attachment - * procedure */ - send_llc_ul_ui(nsi, "ATTACH REQUEST", &bss_peer[0], 0x1002, - foreign_tlli, &rai_bss, cell_id, - GPRS_SAPI_GMM, bss_nu++, - dtap_attach_req3, sizeof(dtap_attach_req3)); - - OSMO_ASSERT(expect_gmm_msg(SGSN_NSEI, 0x1002, GSM48_MT_GMM_ATTACH_REQ)); - - dump_peers(stdout, 0, 0, &gbcfg); - - link_info2 = gbproxy_link_info_by_imsi(peer, imsi, sizeof(imsi)); - link_info = gbproxy_link_info_by_tlli(peer, foreign_tlli); - OSMO_ASSERT(link_info); - OSMO_ASSERT(link_info == link_info2); - OSMO_ASSERT(link_info->imsi_len != 0); - OSMO_ASSERT(!link_info->is_deregistered); - OSMO_ASSERT(!link_info->imsi_acq_pending); - - send_llc_dl_ui(nsi, "ATTACH ACCEPT", &sgsn_peer, 0x1002, - foreign_tlli, 1, imsi, sizeof(imsi), - GPRS_SAPI_GMM, sgsn_nu++, - dtap_attach_acc, sizeof(dtap_attach_acc)); - - OSMO_ASSERT(expect_gmm_msg(0x1000, 0x1002, GSM48_MT_GMM_ATTACH_ACK)); - - dump_peers(stdout, 0, 0, &gbcfg); - - send_llc_ul_ui(nsi, "ATTACH COMPLETE", &bss_peer[0], 0x1002, - local_tlli, &rai_bss, cell_id, - GPRS_SAPI_GMM, bss_nu++, - dtap_attach_complete, sizeof(dtap_attach_complete)); - - OSMO_ASSERT(expect_gmm_msg(SGSN_NSEI, 0x1002, GSM48_MT_GMM_ATTACH_COMPL)); - - dump_peers(stdout, 0, 0, &gbcfg); - - send_llc_dl_ui(nsi, "GMM INFO", &sgsn_peer, 0x1002, - local_tlli, 1, imsi, sizeof(imsi), - GPRS_SAPI_GMM, sgsn_nu++, - dtap_gmm_information, sizeof(dtap_gmm_information)); - - OSMO_ASSERT(expect_gmm_msg(0x1000, 0x1002, GSM48_MT_GMM_INFO)); - - dump_peers(stdout, 0, 0, &gbcfg); - - send_llc_ul_ui(nsi, "ATTACH REQUEST (unexpected)", &bss_peer[0], 0x1002, - foreign_tlli, &rai_bss, cell_id, - GPRS_SAPI_GMM, bss_nu++, - dtap_attach_req3, sizeof(dtap_attach_req3)); - - OSMO_ASSERT(expect_gmm_msg(SGSN_NSEI, 0x1002, GSM48_MT_GMM_ATTACH_REQ)); - - dump_peers(stdout, 0, 0, &gbcfg); - - link_info2 = gbproxy_link_info_by_imsi(peer, imsi, sizeof(imsi)); - link_info = gbproxy_link_info_by_tlli(peer, foreign_tlli); - OSMO_ASSERT(link_info); - OSMO_ASSERT(link_info == link_info2); - OSMO_ASSERT(link_info->imsi_len != 0); - OSMO_ASSERT(!link_info->is_deregistered); - OSMO_ASSERT(!link_info->imsi_acq_pending); - OSMO_ASSERT(link_info->sgsn_tlli.current == foreign_tlli); - OSMO_ASSERT(link_info->sgsn_tlli.assigned == 0); - - send_llc_dl_ui(nsi, "ATTACH ACCEPT", &sgsn_peer, 0x1002, - foreign_tlli, 1, imsi, sizeof(imsi), - GPRS_SAPI_GMM, sgsn_nu++, - dtap_attach_acc, sizeof(dtap_attach_acc)); - - OSMO_ASSERT(expect_gmm_msg(0x1000, 0x1002, GSM48_MT_GMM_ATTACH_ACK)); - - dump_peers(stdout, 0, 0, &gbcfg); - - send_llc_ul_ui(nsi, "ATTACH COMPLETE", &bss_peer[0], 0x1002, - local_tlli, &rai_bss, cell_id, - GPRS_SAPI_GMM, bss_nu++, - dtap_attach_complete, sizeof(dtap_attach_complete)); - - OSMO_ASSERT(expect_gmm_msg(SGSN_NSEI, 0x1002, GSM48_MT_GMM_ATTACH_COMPL)); - - dump_peers(stdout, 0, 0, &gbcfg); - - /* Detach (MT) */ - send_llc_dl_ui(nsi, "DETACH REQ", &sgsn_peer, 0x1002, - local_tlli, 1, imsi, sizeof(imsi), - GPRS_SAPI_GMM, sgsn_nu++, - dtap_mt_detach_req, sizeof(dtap_mt_detach_req)); - - OSMO_ASSERT(expect_gmm_msg(0x1000, 0x1002, GSM48_MT_GMM_DETACH_REQ)); - - dump_peers(stdout, 0, 0, &gbcfg); - - link_info = gbproxy_link_info_by_tlli(peer, local_tlli); - OSMO_ASSERT(link_info); - - send_llc_ul_ui(nsi, "DETACH ACC", &bss_peer[0], 0x1002, - local_tlli, &rai_bss, cell_id, - GPRS_SAPI_GMM, bss_nu++, - dtap_mt_detach_acc, sizeof(dtap_mt_detach_acc)); - - OSMO_ASSERT(expect_gmm_msg(SGSN_NSEI, 0x1002, GSM48_MT_GMM_DETACH_ACK)); - OSMO_ASSERT(!expect_msg()); - - dump_peers(stdout, 0, 0, &gbcfg); - - OSMO_ASSERT(!gbproxy_link_info_by_tlli(peer, local_tlli)); - link_info = gbproxy_link_info_by_imsi(peer, imsi, sizeof(imsi)); - OSMO_ASSERT(link_info); - OSMO_ASSERT(link_info->is_deregistered); - - - /* Attach rejected */ - - gbproxy_delete_link_infos(peer); - - send_llc_ul_ui(nsi, "ATTACH REQUEST", &bss_peer[0], 0x1002, - foreign_tlli, &rai_bss, cell_id, - GPRS_SAPI_GMM, bss_nu++, - dtap_attach_req, sizeof(dtap_attach_req)); - - OSMO_ASSERT(expect_gmm_msg(0x1000, 0x1002, GSM48_MT_GMM_ID_REQ)); - - dump_peers(stdout, 0, 0, &gbcfg); - - link_info = gbproxy_link_info_by_tlli(peer, foreign_tlli); - OSMO_ASSERT(link_info); - OSMO_ASSERT(link_info->imsi_len == 0); - OSMO_ASSERT(!link_info->is_deregistered); - OSMO_ASSERT(link_info->imsi_acq_pending); - - send_llc_ul_ui(nsi, "IDENT RESPONSE", &bss_peer[0], 0x1002, - foreign_tlli, &rai_bss, cell_id, - GPRS_SAPI_GMM, bss_nu++, - dtap_identity_resp, sizeof(dtap_identity_resp)); - - OSMO_ASSERT(expect_gmm_msg(SGSN_NSEI, 0x1002, GSM48_MT_GMM_ATTACH_REQ)); - - dump_peers(stdout, 0, 0, &gbcfg); - - link_info2 = gbproxy_link_info_by_imsi(peer, imsi, sizeof(imsi)); - link_info = gbproxy_link_info_by_tlli(peer, foreign_tlli); - OSMO_ASSERT(link_info); - OSMO_ASSERT(link_info == link_info2); - OSMO_ASSERT(link_info->imsi_len != 0); - OSMO_ASSERT(!link_info->is_deregistered); - OSMO_ASSERT(!link_info->imsi_acq_pending); - - send_llc_dl_ui(nsi, "ATTACH REJECT", &sgsn_peer, 0x1002, - foreign_tlli, 1, imsi, sizeof(imsi), - GPRS_SAPI_GMM, sgsn_nu++, - dtap_attach_rej7, sizeof(dtap_attach_rej7)); - - OSMO_ASSERT(expect_gmm_msg(0x1000, 0x1002, GSM48_MT_GMM_ATTACH_REJ)); - - dump_peers(stdout, 0, 0, &gbcfg); - - OSMO_ASSERT(!gbproxy_link_info_by_tlli(peer, foreign_tlli)); - - OSMO_ASSERT(!expect_msg()); - - /* Attach (incomplete) and Detach (MO) */ - - gbproxy_delete_link_infos(peer); - - send_llc_ul_ui(nsi, "ATTACH REQUEST", &bss_peer[0], 0x1002, - foreign_tlli, &rai_bss, cell_id, - GPRS_SAPI_GMM, bss_nu++, - dtap_attach_req, sizeof(dtap_attach_req)); - - OSMO_ASSERT(expect_gmm_msg(0x1000, 0x1002, GSM48_MT_GMM_ID_REQ)); - - dump_peers(stdout, 0, 0, &gbcfg); - - link_info = gbproxy_link_info_by_tlli(peer, foreign_tlli); - OSMO_ASSERT(link_info); - OSMO_ASSERT(link_info->imsi_len == 0); - OSMO_ASSERT(!link_info->is_deregistered); - OSMO_ASSERT(link_info->imsi_acq_pending); - - send_llc_ul_ui(nsi, "DETACH REQ (MO)", &bss_peer[0], 0x1002, - foreign_tlli, &rai_bss, cell_id, - GPRS_SAPI_GMM, bss_nu++, - dtap_detach_req, sizeof(dtap_detach_req)); - - OSMO_ASSERT(expect_gmm_msg(0x1000, 0x1002, GSM48_MT_GMM_DETACH_ACK)); - - dump_peers(stdout, 0, 0, &gbcfg); - - OSMO_ASSERT(!expect_msg()); - - /* Attach (incomplete) and Detach (MT) */ - - gbproxy_delete_link_infos(peer); - - send_llc_ul_ui(nsi, "ATTACH REQUEST", &bss_peer[0], 0x1002, - foreign_tlli, &rai_bss, cell_id, - GPRS_SAPI_GMM, bss_nu++, - dtap_attach_req, sizeof(dtap_attach_req)); - - OSMO_ASSERT(expect_gmm_msg(0x1000, 0x1002, GSM48_MT_GMM_ID_REQ)); - - dump_peers(stdout, 0, 0, &gbcfg); - - link_info = gbproxy_link_info_by_tlli(peer, foreign_tlli); - OSMO_ASSERT(link_info); - OSMO_ASSERT(link_info->imsi_len == 0); - OSMO_ASSERT(!link_info->is_deregistered); - OSMO_ASSERT(link_info->imsi_acq_pending); - - send_llc_dl_ui(nsi, "DETACH REQ (MT)", &sgsn_peer, 0x1002, - foreign_tlli, 1, imsi, sizeof(imsi), - GPRS_SAPI_GMM, sgsn_nu++, - dtap_mt_detach_req, sizeof(dtap_mt_detach_req)); - - OSMO_ASSERT(expect_gmm_msg(0x1000, 0x1002, GSM48_MT_GMM_DETACH_REQ)); - - dump_peers(stdout, 0, 0, &gbcfg); - - link_info = gbproxy_link_info_by_tlli(peer, foreign_tlli); - OSMO_ASSERT(link_info); - - send_llc_ul_ui(nsi, "DETACH ACC", &bss_peer[0], 0x1002, - foreign_tlli, &rai_bss, cell_id, - GPRS_SAPI_GMM, bss_nu++, - dtap_mt_detach_acc, sizeof(dtap_mt_detach_acc)); - - /* TODO: The stored messaged should be cleaned when receiving a Detach - * Ack. Remove the first OSMO_ASSERT when this is fixed. */ - OSMO_ASSERT(expect_gmm_msg(SGSN_NSEI, 0x1002, GSM48_MT_GMM_ATTACH_REQ)); - OSMO_ASSERT(expect_gmm_msg(SGSN_NSEI, 0x1002, GSM48_MT_GMM_DETACH_ACK)); - - dump_peers(stdout, 0, 0, &gbcfg); - - OSMO_ASSERT(!gbproxy_link_info_by_tlli(peer, foreign_tlli)); - link_info = gbproxy_link_info_by_imsi(peer, imsi, sizeof(imsi)); - OSMO_ASSERT(link_info); - OSMO_ASSERT(link_info->is_deregistered); - - OSMO_ASSERT(!expect_msg()); - received_messages = NULL; - - dump_global(stdout, 0); - - talloc_free(gbcfg.core_apn); - gbcfg.core_apn = NULL; - - gbprox_reset(&gbcfg); - gprs_ns_destroy(nsi); - nsi = NULL; - - cleanup_test(); -} - -struct gbproxy_link_info *register_tlli( - struct gbproxy_peer *peer, uint32_t tlli, - const uint8_t *imsi, size_t imsi_len, time_t now) -{ - struct gbproxy_link_info *link_info; - int imsi_matches = -1; - int tlli_already_known = 0; - struct gbproxy_config *cfg = peer->cfg; - - /* Check, whether the IMSI matches */ - if (gprs_is_mi_imsi(imsi, imsi_len)) { - imsi_matches = gbproxy_check_imsi( - &cfg->matches[GBPROX_MATCH_PATCHING], imsi, imsi_len); - if (imsi_matches < 0) - return NULL; - } - - link_info = gbproxy_link_info_by_tlli(peer, tlli); - - if (!link_info) { - link_info = gbproxy_link_info_by_imsi(peer, imsi, imsi_len); - - if (link_info) { - /* TLLI has changed somehow, adjust it */ - LOGP(DGPRS, LOGL_INFO, - "The TLLI has changed from %08x to %08x\n", - link_info->tlli.current, tlli); - link_info->tlli.current = tlli; - } - } - - if (!link_info) { - link_info = gbproxy_link_info_alloc(peer); - link_info->tlli.current = tlli; - } else { - gbproxy_detach_link_info(peer, link_info); - tlli_already_known = 1; - } - - OSMO_ASSERT(link_info != NULL); - - if (!tlli_already_known) - LOGP(DGPRS, LOGL_INFO, "Adding TLLI %08x to list\n", tlli); - - gbproxy_attach_link_info(peer, now, link_info); - gbproxy_update_link_info(link_info, imsi, imsi_len); - - if (imsi_matches >= 0) - link_info->is_matching[GBPROX_MATCH_PATCHING] = imsi_matches; - - return link_info; -} - -static void test_gbproxy_tlli_expire(void) -{ - struct gbproxy_config cfg = {0}; - struct gbproxy_peer *peer; - const char *err_msg = NULL; - const uint8_t imsi1[] = { GSM_MI_TYPE_IMSI, 0x23, 0x24, 0x25, 0xf6 }; - const uint8_t imsi2[] = { GSM_MI_TYPE_IMSI, 0x26, 0x27, 0x28, 0xf9 }; - const uint8_t imsi3[] = { GSM_MI_TYPE_IMSI | 0x10, 0x32, 0x54, 0x76, 0xf8 }; - const uint32_t tlli1 = 1234 | 0xc0000000; - const uint32_t tlli2 = 5678 | 0xc0000000; - const uint32_t tlli3 = 3456 | 0xc0000000; - const char *filter_re = ".*"; - time_t now = 1407479214; - - printf("Test TLLI info expiry\n\n"); - - gbproxy_init_config(&cfg); - - if (gbproxy_set_patch_filter(&cfg.matches[GBPROX_MATCH_PATCHING], - filter_re, &err_msg) != 0) { - fprintf(stderr, "gbprox_set_patch_filter: got error: %s\n", - err_msg); - OSMO_ASSERT(err_msg == NULL); - } - - { - struct gbproxy_link_info *link_info; - - printf("Test TLLI replacement:\n"); - - cfg.tlli_max_len = 0; - cfg.tlli_max_age = 0; - peer = gbproxy_peer_alloc(&cfg, 20); - OSMO_ASSERT(peer->patch_state.logical_link_count == 0); - - printf(" Add TLLI 1, IMSI 1\n"); - link_info = register_tlli(peer, tlli1, - imsi1, ARRAY_SIZE(imsi1), now); - OSMO_ASSERT(link_info); - OSMO_ASSERT(link_info->tlli.current == tlli1); - OSMO_ASSERT(peer->patch_state.logical_link_count == 1); - - /* replace the old entry */ - printf(" Add TLLI 2, IMSI 1 (should replace TLLI 1)\n"); - link_info = register_tlli(peer, tlli2, - imsi1, ARRAY_SIZE(imsi1), now); - OSMO_ASSERT(link_info); - OSMO_ASSERT(link_info->tlli.current == tlli2); - OSMO_ASSERT(peer->patch_state.logical_link_count == 1); - - dump_peers(stdout, 2, now, &cfg); - - /* verify that 5678 has survived */ - link_info = gbproxy_link_info_by_imsi(peer, imsi1, ARRAY_SIZE(imsi1)); - OSMO_ASSERT(link_info); - OSMO_ASSERT(link_info->tlli.current == tlli2); - link_info = gbproxy_link_info_by_imsi(peer, imsi2, ARRAY_SIZE(imsi2)); - OSMO_ASSERT(!link_info); - - printf("\n"); - - gbproxy_peer_free(peer); - } - - { - struct gbproxy_link_info *link_info; - - printf("Test IMSI replacement:\n"); - - cfg.tlli_max_len = 0; - cfg.tlli_max_age = 0; - peer = gbproxy_peer_alloc(&cfg, 20); - OSMO_ASSERT(peer->patch_state.logical_link_count == 0); - - printf(" Add TLLI 1, IMSI 1\n"); - link_info = register_tlli(peer, tlli1, - imsi1, ARRAY_SIZE(imsi1), now); - OSMO_ASSERT(link_info); - OSMO_ASSERT(link_info->tlli.current == tlli1); - OSMO_ASSERT(peer->patch_state.logical_link_count == 1); - - /* try to replace the old entry */ - printf(" Add TLLI 1, IMSI 2 (should replace IMSI 1)\n"); - link_info = register_tlli(peer, tlli1, - imsi2, ARRAY_SIZE(imsi2), now); - OSMO_ASSERT(link_info); - OSMO_ASSERT(link_info->tlli.current == tlli1); - OSMO_ASSERT(peer->patch_state.logical_link_count == 1); - - dump_peers(stdout, 2, now, &cfg); - - /* verify that 5678 has survived */ - link_info = gbproxy_link_info_by_imsi(peer, imsi1, ARRAY_SIZE(imsi1)); - OSMO_ASSERT(!link_info); - link_info = gbproxy_link_info_by_imsi(peer, imsi2, ARRAY_SIZE(imsi2)); - OSMO_ASSERT(link_info); - OSMO_ASSERT(link_info->tlli.current == tlli1); - - printf("\n"); - - gbproxy_peer_free(peer); - } - - { - struct gbproxy_link_info *link_info; - int num_removed; - - printf("Test TLLI expiry, max_len == 1:\n"); - - cfg.tlli_max_len = 1; - cfg.tlli_max_age = 0; - peer = gbproxy_peer_alloc(&cfg, 20); - OSMO_ASSERT(peer->patch_state.logical_link_count == 0); - - printf(" Add TLLI 1, IMSI 1\n"); - register_tlli(peer, tlli1, imsi1, ARRAY_SIZE(imsi1), now); - OSMO_ASSERT(peer->patch_state.logical_link_count == 1); - - /* replace the old entry */ - printf(" Add TLLI 2, IMSI 2 (should replace IMSI 1)\n"); - register_tlli(peer, tlli2, imsi2, ARRAY_SIZE(imsi2), now); - OSMO_ASSERT(peer->patch_state.logical_link_count == 2); - - num_removed = gbproxy_remove_stale_link_infos(peer, now + 2); - OSMO_ASSERT(num_removed == 1); - OSMO_ASSERT(peer->patch_state.logical_link_count == 1); - - dump_peers(stdout, 2, now, &cfg); - - /* verify that 5678 has survived */ - link_info = gbproxy_link_info_by_imsi(peer, imsi1, ARRAY_SIZE(imsi1)); - OSMO_ASSERT(!link_info); - link_info = gbproxy_link_info_by_imsi(peer, imsi2, ARRAY_SIZE(imsi2)); - OSMO_ASSERT(link_info); - OSMO_ASSERT(link_info->tlli.current == tlli2); - - printf("\n"); - - gbproxy_peer_free(peer); - } - - { - struct gbproxy_link_info *link_info; - int num_removed; - - printf("Test TLLI expiry, max_age == 1:\n"); - - cfg.tlli_max_len = 0; - cfg.tlli_max_age = 1; - peer = gbproxy_peer_alloc(&cfg, 20); - OSMO_ASSERT(peer->patch_state.logical_link_count == 0); - - printf(" Add TLLI 1, IMSI 1 (should expire after timeout)\n"); - register_tlli(peer, tlli1, imsi1, ARRAY_SIZE(imsi1), now); - OSMO_ASSERT(peer->patch_state.logical_link_count == 1); - - printf(" Add TLLI 2, IMSI 2 (should not expire after timeout)\n"); - register_tlli(peer, tlli2, imsi2, ARRAY_SIZE(imsi2), - now + 1); - OSMO_ASSERT(peer->patch_state.logical_link_count == 2); - - num_removed = gbproxy_remove_stale_link_infos(peer, now + 2); - OSMO_ASSERT(num_removed == 1); - OSMO_ASSERT(peer->patch_state.logical_link_count == 1); - - dump_peers(stdout, 2, now + 2, &cfg); - - /* verify that 5678 has survived */ - link_info = gbproxy_link_info_by_imsi(peer, imsi1, ARRAY_SIZE(imsi1)); - OSMO_ASSERT(!link_info); - link_info = gbproxy_link_info_by_imsi(peer, imsi2, ARRAY_SIZE(imsi2)); - OSMO_ASSERT(link_info); - OSMO_ASSERT(link_info->tlli.current == tlli2); - - printf("\n"); - - gbproxy_peer_free(peer); - } - - { - struct gbproxy_link_info *link_info; - int num_removed; - - printf("Test TLLI expiry, max_len == 2, max_age == 1:\n"); - - cfg.tlli_max_len = 0; - cfg.tlli_max_age = 1; - peer = gbproxy_peer_alloc(&cfg, 20); - OSMO_ASSERT(peer->patch_state.logical_link_count == 0); - - printf(" Add TLLI 1, IMSI 1 (should expire)\n"); - register_tlli(peer, tlli1, imsi1, ARRAY_SIZE(imsi1), now); - OSMO_ASSERT(peer->patch_state.logical_link_count == 1); - - printf(" Add TLLI 2, IMSI 2 (should expire after timeout)\n"); - register_tlli(peer, tlli2, imsi2, ARRAY_SIZE(imsi2), - now + 1); - OSMO_ASSERT(peer->patch_state.logical_link_count == 2); - - printf(" Add TLLI 3, IMSI 3 (should not expire after timeout)\n"); - register_tlli(peer, tlli3, imsi3, ARRAY_SIZE(imsi3), - now + 2); - OSMO_ASSERT(peer->patch_state.logical_link_count == 3); - - dump_peers(stdout, 2, now + 2, &cfg); - - printf(" Remove stale TLLIs\n"); - num_removed = gbproxy_remove_stale_link_infos(peer, now + 3); - OSMO_ASSERT(num_removed == 2); - OSMO_ASSERT(peer->patch_state.logical_link_count == 1); - - dump_peers(stdout, 2, now + 2, &cfg); - - /* verify that tlli3 has survived */ - link_info = gbproxy_link_info_by_imsi(peer, imsi1, ARRAY_SIZE(imsi1)); - OSMO_ASSERT(!link_info); - link_info = gbproxy_link_info_by_imsi(peer, imsi2, ARRAY_SIZE(imsi2)); - OSMO_ASSERT(!link_info); - link_info = gbproxy_link_info_by_imsi(peer, imsi3, ARRAY_SIZE(imsi3)); - OSMO_ASSERT(link_info); - OSMO_ASSERT(link_info->tlli.current == tlli3); - - printf("\n"); - - gbproxy_peer_free(peer); - } - gbproxy_clear_patch_filter(&cfg.matches[GBPROX_MATCH_PATCHING]); - gbprox_reset(&cfg); - /* gbprox_reset() frees the rate_ctr, but re-allocates it again. */ - rate_ctr_group_free(cfg.ctrg); - - cleanup_test(); -} - -static void test_gbproxy_imsi_matching(void) -{ - const char *err_msg = NULL; - const uint8_t imsi1[] = { GSM_MI_TYPE_IMSI | 0x10, 0x32, 0x54, 0xf6 }; - const uint8_t imsi2[] = { GSM_MI_TYPE_IMSI | GSM_MI_ODD | 0x10, 0x32, 0x54, 0x76 }; - const uint8_t imsi3_bad[] = { GSM_MI_TYPE_IMSI | 0x10, 0xee, 0x54, 0xff }; - const uint8_t tmsi1[] = { GSM_MI_TYPE_TMSI | 0xf0, 0x11, 0x22, 0x33, 0x44 }; - const uint8_t tmsi2_bad[] = { GSM_MI_TYPE_TMSI | 0xf0, 0x11, 0x22 }; - const uint8_t imei1[] = { GSM_MI_TYPE_IMEI | 0x10, 0x32, 0x54, 0xf6 }; - const uint8_t imei2[] = { GSM_MI_TYPE_IMEI | GSM_MI_ODD | 0x10, 0x32, 0x54, 0x76 }; - const char *filter_re1 = ".*"; - const char *filter_re2 = "^1234"; - const char *filter_re3 = "^4321"; - const char *filter_re4_bad = "^12["; - struct gbproxy_match match = {0,}; - - printf("=== Test IMSI/TMSI matching ===\n\n"); - - OSMO_ASSERT(match.enable == 0); - - OSMO_ASSERT(gbproxy_set_patch_filter(&match, filter_re1, &err_msg) == 0); - OSMO_ASSERT(match.enable == 1); - - OSMO_ASSERT(gbproxy_set_patch_filter(&match, filter_re2, &err_msg) == 0); - OSMO_ASSERT(match.enable == 1); - - err_msg = NULL; - OSMO_ASSERT(gbproxy_set_patch_filter(&match, filter_re4_bad, &err_msg) == -1); - OSMO_ASSERT(err_msg != NULL); - OSMO_ASSERT(match.enable == 0); - - OSMO_ASSERT(gbproxy_set_patch_filter(&match, filter_re2, &err_msg) == 0); - OSMO_ASSERT(match.enable == 1); - - OSMO_ASSERT(gbproxy_set_patch_filter(&match, NULL, &err_msg) == 0); - OSMO_ASSERT(match.enable == 0); - - OSMO_ASSERT(gbproxy_set_patch_filter(&match, filter_re2, &err_msg) == 0); - OSMO_ASSERT(match.enable == 1); - - gbproxy_clear_patch_filter(&match); - OSMO_ASSERT(match.enable == 0); - - OSMO_ASSERT(gbproxy_set_patch_filter(&match, filter_re2, &err_msg) == 0); - OSMO_ASSERT(match.enable == 1); - - OSMO_ASSERT(gbproxy_check_imsi(&match, imsi1, ARRAY_SIZE(imsi1)) == 1); - OSMO_ASSERT(gbproxy_check_imsi(&match, imsi2, ARRAY_SIZE(imsi2)) == 1); - OSMO_ASSERT(gbproxy_check_imsi(&match, imsi3_bad, ARRAY_SIZE(imsi3_bad)) == -1); - OSMO_ASSERT(gbproxy_check_imsi(&match, tmsi1, ARRAY_SIZE(tmsi1)) == -1); - OSMO_ASSERT(gbproxy_check_imsi(&match, tmsi2_bad, ARRAY_SIZE(tmsi2_bad)) == -1); - OSMO_ASSERT(gbproxy_check_imsi(&match, imei1, ARRAY_SIZE(imei1)) == -1); - OSMO_ASSERT(gbproxy_check_imsi(&match, imei2, ARRAY_SIZE(imei2)) == -1); - - OSMO_ASSERT(gbproxy_set_patch_filter(&match, filter_re3, &err_msg) == 0); - OSMO_ASSERT(match.enable == 1); - - OSMO_ASSERT(gbproxy_check_imsi(&match, imsi1, ARRAY_SIZE(imsi1)) == 0); - OSMO_ASSERT(gbproxy_check_imsi(&match, imsi2, ARRAY_SIZE(imsi2)) == 0); - OSMO_ASSERT(gbproxy_check_imsi(&match, imsi3_bad, ARRAY_SIZE(imsi3_bad)) == -1); - OSMO_ASSERT(gbproxy_check_imsi(&match, tmsi1, ARRAY_SIZE(tmsi1)) == -1); - OSMO_ASSERT(gbproxy_check_imsi(&match, tmsi2_bad, ARRAY_SIZE(tmsi2_bad)) == -1); - OSMO_ASSERT(gbproxy_check_imsi(&match, imei1, ARRAY_SIZE(imei1)) == -1); - OSMO_ASSERT(gbproxy_check_imsi(&match, imei2, ARRAY_SIZE(imei2)) == -1); - - /* TODO: Check correct length but wrong type with is_mi_tmsi */ - - gbproxy_clear_patch_filter(&match); - OSMO_ASSERT(match.enable == 0); - - cleanup_test(); -} - -static void test_gbproxy_stored_messages() -{ - struct gprs_ns_inst *nsi = gprs_ns_instantiate(gprs_ns_callback, tall_sgsn_ctx); - struct sockaddr_in bss_peer[1] = {{0},}; - struct sockaddr_in sgsn_peer= {0}; - struct gprs_ra_id rai_bss = - {.mcc = 112, .mnc = 332, .lac = 16464, .rac = 96}; - struct gprs_ra_id rai_unknown = - {.mcc = 1, .mnc = 99, .lac = 99, .rac = 96}; - uint16_t cell_id = 0x1234; - - const uint32_t ptmsi = 0xefe2b700; - const uint32_t local_tlli = 0xefe2b700; - - const uint32_t foreign_tlli1 = 0x8000dead; - - struct gbproxy_peer *peer; - unsigned bss_nu = 0; - unsigned sgsn_nu = 0; - - OSMO_ASSERT(local_tlli == gprs_tmsi2tlli(ptmsi, TLLI_LOCAL)); - - bssgp_nsi = nsi; - gbcfg.nsi = bssgp_nsi; - gbcfg.nsip_sgsn_nsei = SGSN_NSEI; - gbcfg.core_plmn = (struct osmo_plmn_id){}; - gbcfg.core_apn = talloc_zero_size(tall_sgsn_ctx, 100); - gbcfg.core_apn_size = gprs_str_to_apn(gbcfg.core_apn, 100, "foo.bar"); - gbcfg.patch_ptmsi = 0; - gbcfg.acquire_imsi = 1; - gbcfg.keep_link_infos = 0; - - configure_sgsn_peer(&sgsn_peer); - configure_bss_peers(bss_peer, ARRAY_SIZE(bss_peer)); - - printf("=== %s ===\n", __func__); - printf("--- Initialise SGSN ---\n\n"); - - connect_sgsn(nsi, &sgsn_peer, SGSN_NSEI); - - printf("--- Initialise BSS 1 ---\n\n"); - - setup_ns(nsi, &bss_peer[0], 0x1001, 0x1000); - setup_bssgp(nsi, &bss_peer[0], 0x1002); - - peer = gbproxy_peer_by_nsei(&gbcfg, 0x1000); - OSMO_ASSERT(peer != NULL); - - send_bssgp_reset_ack(nsi, &sgsn_peer, 0x1002); - - gprs_dump_nsi(nsi); - dump_global(stdout, 0); - dump_peers(stdout, 0, 0, &gbcfg); - - printf("--- Establish first LLC connection ---\n\n"); - - send_llc_ul_ui(nsi, "ATTACH REQUEST", &bss_peer[0], 0x1002, - foreign_tlli1, &rai_unknown, cell_id, - GPRS_SAPI_GMM, bss_nu++, - dtap_attach_req, sizeof(dtap_attach_req)); - - dump_peers(stdout, 0, 0, &gbcfg); - - send_llc_dl_ui(nsi, "IDENT REQUEST", &sgsn_peer, 0x1002, - foreign_tlli1, 0, NULL, 0, - GPRS_SAPI_GMM, sgsn_nu++, - dtap_identity_req, sizeof(dtap_identity_req)); - - dump_peers(stdout, 0, 0, &gbcfg); - - send_llc_ul_ui(nsi, "DETACH ACCEPT", &bss_peer[0], 0x1002, - foreign_tlli1, &rai_bss, cell_id, - GPRS_SAPI_GMM, bss_nu++, - dtap_detach_acc, sizeof(dtap_detach_acc)); - - dump_peers(stdout, 0, 0, &gbcfg); - - send_llc_ul_ui(nsi, "IDENT RESPONSE", &bss_peer[0], 0x1002, - foreign_tlli1, &rai_bss, cell_id, - GPRS_SAPI_GMM, bss_nu++, - dtap_identity_resp, sizeof(dtap_identity_resp)); - - dump_peers(stdout, 0, 0, &gbcfg); - - dump_global(stdout, 0); - - talloc_free(gbcfg.core_apn); - gbcfg.core_apn = NULL; - - gbprox_reset(&gbcfg); - gprs_ns_destroy(nsi); - nsi = NULL; - - cleanup_test(); -} - -/* See OS#3178 "gbproxy: failed to parse invalid BSSGP-UNITDATA message" */ -static void test_gbproxy_parse_bssgp_unitdata() -{ - const char *hex = "0000239401e155cfea000004088872f4801018009c4000800e000601c0416c4338"; - struct msgb *msg = msgb_alloc(1034, "bssgp_unitdata"); - struct gprs_gb_parse_context parse_ctx; - int rc; - - memset(&parse_ctx, 0, sizeof(parse_ctx)); - - OSMO_ASSERT(msg); - msgb_bssgph(msg) = msg->head; - msgb_put(msg, osmo_hexparse(hex, msg->head, msgb_tailroom(msg))); - - parse_ctx.to_bss = 0; - parse_ctx.peer_nsei = msgb_nsei(msg); - - rc = gprs_gb_parse_bssgp(msg->data, msg->len, &parse_ctx); - if (!rc) - fprintf(stderr, "%s: Test passed; Failed to parse invalid message %s\n", __func__, msgb_hexdump(msg)); - else - fprintf(stderr, "%s: Test failed; invalid message was accepted by parser: %s\n", __func__, msgb_hexdump(msg)); - - OSMO_ASSERT(!rc); - - /* Manually decoded message according to: - ETSI TS 148 018 V10.6.0 (2012 07) 96 - 3GPP TS 48.018 version 10.6.0 Release 10 - Table 10.2.2: UL-UNITDATA PDU content - - 00 - PDU type UL-UNITDATA (ok) - - 11.3.35 Temporary logical link Identity (TLLI) - 00 - TLLI[0] - 23 - TLLI[1] - 94 - TLLI[2] - 01 - TLLI[3] - TLLI == "00239401" - - e1 - QOS[0] (bit rate MSB) - 55 - QOS[1] (bit rate LSB) - bit rate = "57685" (57685*100000 bit/s per PBRG) - cf - QOS[2] PBRG = 11 (bit rate is expressed in 100000 bit/s increments), - C/R 0 (contains LLC ACK/SACK), - T 0 (contains signalling), - A 1 (radio if uses MAC/UNITDATA, - Precedence 111 (reserved value) - - ea - CELL_ID[0] (TLV IEI: wrong, should be 0x08) - 00 - CELL_ID[1] (length 1) - 00 - CELL_ID[2] (length 2) - lenth == 0 - 04 -- CELL_ID[3] - 08 -- CELL_ID[4] - 88 -- CELL_ID[5] - 72 -- CELL_ID[6] - f4 -- CELL_ID[7] - 80 -- CELL_ID[8] - 10 -- CELL_DI[9] - - 18 -- QOSP[0] OoS Profile IEI - not allowed in BSSGP Userdata - 00 -- QOSP[1] - 9c -- QOSP[2] - 40 -- QOSP[3] - 00 -- QOSP[4] - - 80 -- IEI for "E-UTRAN Inter RAT Handover Info" - not allowed in BSSGP Userdata - 0e -- length (14 bytes -- only 8 bytes remain) - 00 06 01 c0 41 6c 43 38 */ - - msgb_free(msg); - - cleanup_test(); -} - -static struct log_info_cat gprs_categories[] = { - [DGPRS] = { - .name = "DGPRS", - .description = "GPRS Packet Service", - .enabled = 1, .loglevel = LOGL_DEBUG, - }, - [DNS] = { - .name = "DNS", - .description = "GPRS Network Service (NS)", - .enabled = 1, .loglevel = LOGL_INFO, - }, - [DBSSGP] = { - .name = "DBSSGP", - .description = "GPRS BSS Gateway Protocol (BSSGP)", - .enabled = 1, .loglevel = LOGL_DEBUG, - }, -}; - -static struct log_info info = { - .cat = gprs_categories, - .num_cat = ARRAY_SIZE(gprs_categories), -}; - -int main(int argc, char **argv) -{ - talloc_enable_leak_report(); - tall_sgsn_ctx = talloc_named_const(NULL, 0, "gbproxy_test"); - void *log_ctx = talloc_named_const(tall_sgsn_ctx, 0, "log"); - - msgb_talloc_ctx_init(tall_sgsn_ctx, 0); - - osmo_init_logging2(log_ctx, &info); - log_set_use_color(osmo_stderr_target, 0); - log_set_print_filename(osmo_stderr_target, 0); - osmo_signal_register_handler(SS_L_NS, &test_signal, &gbcfg); - - log_set_print_filename(osmo_stderr_target, 0); - log_set_log_level(osmo_stderr_target, LOGL_DEBUG); - log_set_all_filter(osmo_stderr_target, 1); - - rate_ctr_init(tall_sgsn_ctx); - - setlinebuf(stdout); - - printf("===== GbProxy test START\n"); - gbproxy_init_config(&gbcfg); - test_gbproxy(); - test_gbproxy_ident_changes(); - test_gbproxy_imsi_matching(); - test_gbproxy_ptmsi_assignment(); - test_gbproxy_ra_patching(); - test_gbproxy_ptmsi_patching(); - test_gbproxy_ptmsi_patching_bad_cases(); - test_gbproxy_imsi_acquisition(); - test_gbproxy_secondary_sgsn(); - test_gbproxy_keep_info(); - test_gbproxy_tlli_expire(); - test_gbproxy_stored_messages(); - test_gbproxy_parse_bssgp_unitdata(); - gbprox_reset(&gbcfg); - /* gbprox_reset() frees the rate_ctr, but re-allocates it again. */ - rate_ctr_group_free(gbcfg.ctrg); - printf("===== GbProxy test END\n\n"); - - talloc_free(log_ctx); - /* expecting root and msgb ctx, empty */ - OSMO_ASSERT(talloc_total_blocks(tall_sgsn_ctx) == 2); - talloc_free(tall_sgsn_ctx); - - return 0; -} diff --git a/tests/gbproxy/gbproxy_test.ok b/tests/gbproxy/gbproxy_test.ok deleted file mode 100644 index 03de12e4..00000000 --- a/tests/gbproxy/gbproxy_test.ok +++ /dev/null @@ -1,7492 +0,0 @@ -===== GbProxy test START -=== test_gbproxy === ---- 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) = 0 - -PROCESSING ALIVE_ACK from 0x05060708:32000 -0b - -MESSAGE to SGSN at 0x05060708:32000, msg length 1 -06 - -result (ALIVE_ACK) = 0 - -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) = 0 - -Current NS-VCIs: - VCI 0x0101, NSEI 0x0100, peer 0x05060708:32000 - Packets at NS Level ( In): 4 - Packets at NS Level (Out): 4 - Bytes at NS Level ( In): 12 - Bytes at NS Level (Out): 15 - NS-VC Block count : 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) = 0 - -PROCESSING ALIVE from 0x01020304:1111 -0a - -MESSAGE to BSS at 0x01020304:1111, msg length 1 -0b - -result (ALIVE) = 0 - -PROCESSING UNBLOCK from 0x01020304:1111 -06 - -MESSAGE to BSS at 0x01020304:1111, msg length 1 -07 - -==> got signal NS_UNBLOCK, NS-VC 0x1001/1.2.3.4:1111 - -result (UNBLOCK) = 0 - -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 11 22 33 40 50 60 10 00 - -result (BVC_RESET) = 0 - -Current NS-VCIs: - VCI 0x1001, NSEI 0x1000, peer 0x01020304:1111 - Packets at NS Level ( In): 5 - Packets at NS Level (Out): 4 - Bytes at NS Level ( In): 37 - Bytes at NS Level (Out): 12 - VCI 0x0101, NSEI 0x0100, peer 0x05060708:32000 - Packets at NS Level ( In): 4 - Packets at NS Level (Out): 5 - Bytes at NS Level ( In): 12 - Bytes at NS Level (Out): 37 - NS-VC Block count : 1 - -Peers: - NSEI 4096, BVCI 4098, not blocked, RAI 112-332-16464-96 - TLLI-Cache: 0 -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) = 0 - ---- Initialise BSS 2 --- - -Setup NS-VC: remote 0x01020304:2222, NSVCI 0x2001(8193), NSEI 0x2000(8192) - -PROCESSING RESET from 0x01020304:2222 -02 00 81 01 01 82 20 01 04 82 20 00 - -==> got signal NS_RESET, NS-VC 0x2001/1.2.3.4:2222 - -MESSAGE to BSS at 0x01020304:2222, msg length 9 -03 01 82 20 01 04 82 20 00 - -MESSAGE to BSS at 0x01020304:2222, msg length 1 -0a - -result (RESET) = 0 - -PROCESSING ALIVE from 0x01020304:2222 -0a - -MESSAGE to BSS at 0x01020304:2222, msg length 1 -0b - -result (ALIVE) = 0 - -PROCESSING UNBLOCK from 0x01020304:2222 -06 - -MESSAGE to BSS at 0x01020304:2222, msg length 1 -07 - -==> got signal NS_UNBLOCK, NS-VC 0x2001/1.2.3.4:2222 - -result (UNBLOCK) = 0 - -PROCESSING ALIVE_ACK from 0x01020304:2222 -0b - -result (ALIVE_ACK) = 0 - -Setup BSSGP: remote 0x01020304:2222, BVCI 0x2002(8194) - -PROCESSING BVC_RESET from 0x01020304:2222 -00 00 00 00 22 04 82 20 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 20 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 20 02 07 81 08 08 88 11 22 33 40 50 60 10 00 - -result (BVC_RESET) = 0 - -Current NS-VCIs: - VCI 0x2001, NSEI 0x2000, peer 0x01020304:2222 - Packets at NS Level ( In): 5 - Packets at NS Level (Out): 4 - Bytes at NS Level ( In): 37 - Bytes at NS Level (Out): 12 - VCI 0x1001, NSEI 0x1000, peer 0x01020304:1111 - Packets at NS Level ( In): 5 - Packets at NS Level (Out): 5 - Bytes at NS Level ( In): 37 - Bytes at NS Level (Out): 21 - VCI 0x0101, NSEI 0x0100, peer 0x05060708:32000 - Packets at NS Level ( In): 5 - Packets at NS Level (Out): 6 - Bytes at NS Level ( In): 21 - Bytes at NS Level (Out): 59 - NS-VC Block count : 1 - -Peers: - NSEI 8192, BVCI 8194, not blocked, RAI 112-332-16464-96 - TLLI-Cache: 0 - NSEI 4096, BVCI 4098, not blocked, RAI 112-332-16464-96 - TLLI-Cache: 0 -PROCESSING BVC_RESET_ACK from 0x05060708:32000 -00 00 00 00 23 04 82 20 02 - -CALLBACK, event 0, msg length 5, bvci 0x0000 -00 00 00 00 23 04 82 20 02 - -NS UNITDATA MESSAGE to BSS, BVCI 0x0000, msg length 5 (gprs_ns_sendmsg) -MESSAGE to BSS at 0x01020304:2222, msg length 9 -00 00 00 00 23 04 82 20 02 - -result (BVC_RESET_ACK) = 0 - ---- Move BSS 1 to new port --- - -Setup NS-VC: remote 0x01020304:3333, NSVCI 0x1001(4097), NSEI 0x1000(4096) - -PROCESSING RESET from 0x01020304:3333 -02 00 81 01 01 82 10 01 04 82 10 00 - -==> got signal NS_RESET, NS-VC 0x1001/1.2.3.4:3333 - -MESSAGE to BSS at 0x01020304:3333, msg length 9 -03 01 82 10 01 04 82 10 00 - -MESSAGE to BSS at 0x01020304:3333, msg length 1 -0a - -result (RESET) = 0 - -PROCESSING ALIVE from 0x01020304:3333 -0a - -MESSAGE to BSS at 0x01020304:3333, msg length 1 -0b - -result (ALIVE) = 0 - -PROCESSING UNBLOCK from 0x01020304:3333 -06 - -MESSAGE to BSS at 0x01020304:3333, msg length 1 -07 - -==> got signal NS_UNBLOCK, NS-VC 0x1001/1.2.3.4:3333 - -result (UNBLOCK) = 0 - -PROCESSING ALIVE_ACK from 0x01020304:3333 -0b - -result (ALIVE_ACK) = 0 - -Current NS-VCIs: - VCI 0x2001, NSEI 0x2000, peer 0x01020304:2222 - Packets at NS Level ( In): 5 - Packets at NS Level (Out): 5 - Bytes at NS Level ( In): 37 - Bytes at NS Level (Out): 21 - VCI 0x1001, NSEI 0x1000, peer 0x01020304:3333 - Packets at NS Level ( In): 9 - Packets at NS Level (Out): 9 - Bytes at NS Level ( In): 52 - Bytes at NS Level (Out): 33 - VCI 0x0101, NSEI 0x0100, peer 0x05060708:32000 - Packets at NS Level ( In): 6 - Packets at NS Level (Out): 6 - Bytes at NS Level ( In): 30 - Bytes at NS Level (Out): 59 - NS-VC Block count : 1 - -Peers: - NSEI 8192, BVCI 8194, not blocked, RAI 112-332-16464-96 - TLLI-Cache: 0 - NSEI 4096, BVCI 4098, not blocked, RAI 112-332-16464-96 - TLLI-Cache: 0 ---- Move BSS 2 to former BSS 1 port --- - -Setup NS-VC: remote 0x01020304:1111, NSVCI 0x2001(8193), NSEI 0x2000(8192) - -PROCESSING RESET from 0x01020304:1111 -02 00 81 01 01 82 20 01 04 82 20 00 - -==> got signal NS_RESET, NS-VC 0x2001/1.2.3.4:1111 - -MESSAGE to BSS at 0x01020304:1111, msg length 9 -03 01 82 20 01 04 82 20 00 - -MESSAGE to BSS at 0x01020304:1111, msg length 1 -0a - -result (RESET) = 0 - -PROCESSING ALIVE from 0x01020304:1111 -0a - -MESSAGE to BSS at 0x01020304:1111, msg length 1 -0b - -result (ALIVE) = 0 - -PROCESSING UNBLOCK from 0x01020304:1111 -06 - -MESSAGE to BSS at 0x01020304:1111, msg length 1 -07 - -==> got signal NS_UNBLOCK, NS-VC 0x2001/1.2.3.4:1111 - -result (UNBLOCK) = 0 - -PROCESSING ALIVE_ACK from 0x01020304:1111 -0b - -result (ALIVE_ACK) = 0 - -Current NS-VCIs: - VCI 0x2001, NSEI 0x2000, peer 0x01020304:1111 - Packets at NS Level ( In): 9 - Packets at NS Level (Out): 9 - Bytes at NS Level ( In): 52 - Bytes at NS Level (Out): 33 - VCI 0x1001, NSEI 0x1000, peer 0x01020304:3333 - Packets at NS Level ( In): 9 - Packets at NS Level (Out): 9 - Bytes at NS Level ( In): 52 - Bytes at NS Level (Out): 33 - VCI 0x0101, NSEI 0x0100, peer 0x05060708:32000 - Packets at NS Level ( In): 6 - Packets at NS Level (Out): 6 - Bytes at NS Level ( In): 30 - Bytes at NS Level (Out): 59 - NS-VC Block count : 1 - -Peers: - NSEI 8192, BVCI 8194, not blocked, RAI 112-332-16464-96 - TLLI-Cache: 0 - NSEI 4096, BVCI 4098, not blocked, RAI 112-332-16464-96 - TLLI-Cache: 0 ---- Move BSS 1 to current BSS 2 port --- - -Setup NS-VC: remote 0x01020304:1111, NSVCI 0x2001(8193), NSEI 0x2000(8192) - -PROCESSING RESET from 0x01020304:1111 -02 00 81 01 01 82 20 01 04 82 20 00 - -==> got signal NS_RESET, NS-VC 0x2001/1.2.3.4:1111 - -MESSAGE to BSS at 0x01020304:1111, msg length 9 -03 01 82 20 01 04 82 20 00 - -MESSAGE to BSS at 0x01020304:1111, msg length 1 -0a - -result (RESET) = 0 - -PROCESSING ALIVE from 0x01020304:1111 -0a - -MESSAGE to BSS at 0x01020304:1111, msg length 1 -0b - -result (ALIVE) = 0 - -PROCESSING UNBLOCK from 0x01020304:1111 -06 - -MESSAGE to BSS at 0x01020304:1111, msg length 1 -07 - -==> got signal NS_UNBLOCK, NS-VC 0x2001/1.2.3.4:1111 - -result (UNBLOCK) = 0 - -PROCESSING ALIVE_ACK from 0x01020304:1111 -0b - -result (ALIVE_ACK) = 0 - -Current NS-VCIs: - VCI 0x2001, NSEI 0x2000, peer 0x01020304:1111 - Packets at NS Level ( In): 13 - Packets at NS Level (Out): 13 - Bytes at NS Level ( In): 67 - Bytes at NS Level (Out): 45 - VCI 0x1001, NSEI 0x1000, peer 0x01020304:3333 - Packets at NS Level ( In): 9 - Packets at NS Level (Out): 9 - Bytes at NS Level ( In): 52 - Bytes at NS Level (Out): 33 - VCI 0x0101, NSEI 0x0100, peer 0x05060708:32000 - Packets at NS Level ( In): 6 - Packets at NS Level (Out): 6 - Bytes at NS Level ( In): 30 - Bytes at NS Level (Out): 59 - NS-VC Block count : 1 - -Peers: - NSEI 8192, BVCI 8194, not blocked, RAI 112-332-16464-96 - TLLI-Cache: 0 - NSEI 4096, BVCI 4098, not blocked, RAI 112-332-16464-96 - TLLI-Cache: 0 ---- Move BSS 2 to new port --- - -Setup NS-VC: remote 0x01020304:4444, NSVCI 0x2001(8193), NSEI 0x2000(8192) - -PROCESSING RESET from 0x01020304:4444 -02 00 81 01 01 82 20 01 04 82 20 00 - -==> got signal NS_RESET, NS-VC 0x2001/1.2.3.4:4444 - -MESSAGE to BSS at 0x01020304:4444, msg length 9 -03 01 82 20 01 04 82 20 00 - -MESSAGE to BSS at 0x01020304:4444, msg length 1 -0a - -result (RESET) = 0 - -PROCESSING ALIVE from 0x01020304:4444 -0a - -MESSAGE to BSS at 0x01020304:4444, msg length 1 -0b - -result (ALIVE) = 0 - -PROCESSING UNBLOCK from 0x01020304:4444 -06 - -MESSAGE to BSS at 0x01020304:4444, msg length 1 -07 - -==> got signal NS_UNBLOCK, NS-VC 0x2001/1.2.3.4:4444 - -result (UNBLOCK) = 0 - -PROCESSING ALIVE_ACK from 0x01020304:4444 -0b - -result (ALIVE_ACK) = 0 - -Current NS-VCIs: - VCI 0x2001, NSEI 0x2000, peer 0x01020304:4444 - Packets at NS Level ( In): 17 - Packets at NS Level (Out): 17 - Bytes at NS Level ( In): 82 - Bytes at NS Level (Out): 57 - VCI 0x1001, NSEI 0x1000, peer 0x01020304:3333 - Packets at NS Level ( In): 9 - Packets at NS Level (Out): 9 - Bytes at NS Level ( In): 52 - Bytes at NS Level (Out): 33 - VCI 0x0101, NSEI 0x0100, peer 0x05060708:32000 - Packets at NS Level ( In): 6 - Packets at NS Level (Out): 6 - Bytes at NS Level ( In): 30 - Bytes at NS Level (Out): 59 - NS-VC Block count : 1 - -Peers: - NSEI 8192, BVCI 8194, not blocked, RAI 112-332-16464-96 - TLLI-Cache: 0 - NSEI 4096, BVCI 4098, not blocked, RAI 112-332-16464-96 - TLLI-Cache: 0 ---- Move BSS 2 to former BSS 1 port --- - -Setup NS-VC: remote 0x01020304:3333, NSVCI 0x2001(8193), NSEI 0x2000(8192) - -PROCESSING RESET from 0x01020304:3333 -02 00 81 01 01 82 20 01 04 82 20 00 - -==> got signal NS_REPLACED: 0x2001/1.2.3.4:4444 -> 0x1001/1.2.3.4:3333 - -==> got signal NS_RESET, NS-VC 0x2001/1.2.3.4:3333 - -MESSAGE to BSS at 0x01020304:3333, msg length 9 -03 01 82 20 01 04 82 20 00 - -MESSAGE to BSS at 0x01020304:3333, msg length 1 -0a - -result (RESET) = 0 - -PROCESSING ALIVE from 0x01020304:3333 -0a - -MESSAGE to BSS at 0x01020304:3333, msg length 1 -0b - -result (ALIVE) = 0 - -PROCESSING UNBLOCK from 0x01020304:3333 -06 - -MESSAGE to BSS at 0x01020304:3333, msg length 1 -07 - -==> got signal NS_UNBLOCK, NS-VC 0x2001/1.2.3.4:3333 - -result (UNBLOCK) = 0 - -PROCESSING ALIVE_ACK from 0x01020304:3333 -0b - -result (ALIVE_ACK) = 0 - -Current NS-VCIs: - VCI 0x2001, NSEI 0x2000, peer 0x01020304:3333 - Packets at NS Level ( In): 20 - Packets at NS Level (Out): 21 - Bytes at NS Level ( In): 85 - Bytes at NS Level (Out): 69 - NS-VC replaced other count: 1 - VCI 0x1001, NSEI 0x1000, peer 0x00000000:0 - Packets at NS Level ( In): 10 - Packets at NS Level (Out): 9 - Bytes at NS Level ( In): 64 - Bytes at NS Level (Out): 33 - VCI 0x0101, NSEI 0x0100, peer 0x05060708:32000 - Packets at NS Level ( In): 6 - Packets at NS Level (Out): 6 - Bytes at NS Level ( In): 30 - Bytes at NS Level (Out): 59 - NS-VC Block count : 1 - -Peers: - NSEI 8192, BVCI 8194, not blocked, RAI 112-332-16464-96 - TLLI-Cache: 0 - NSEI 4096, BVCI 4098, not blocked, RAI 112-332-16464-96 - TLLI-Cache: 0 ---- Move BSS 1 to original BSS 1 port --- - -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) = 0 - -PROCESSING ALIVE from 0x01020304:1111 -0a - -MESSAGE to BSS at 0x01020304:1111, msg length 1 -0b - -result (ALIVE) = 0 - -PROCESSING UNBLOCK from 0x01020304:1111 -06 - -MESSAGE to BSS at 0x01020304:1111, msg length 1 -07 - -==> got signal NS_UNBLOCK, NS-VC 0x1001/1.2.3.4:1111 - -result (UNBLOCK) = 0 - -PROCESSING ALIVE_ACK from 0x01020304:1111 -0b - -result (ALIVE_ACK) = 0 - -Current NS-VCIs: - VCI 0x2001, NSEI 0x2000, peer 0x01020304:3333 - Packets at NS Level ( In): 20 - Packets at NS Level (Out): 21 - Bytes at NS Level ( In): 85 - Bytes at NS Level (Out): 69 - NS-VC replaced other count: 1 - VCI 0x1001, NSEI 0x1000, peer 0x01020304:1111 - Packets at NS Level ( In): 14 - Packets at NS Level (Out): 13 - Bytes at NS Level ( In): 79 - Bytes at NS Level (Out): 45 - VCI 0x0101, NSEI 0x0100, peer 0x05060708:32000 - Packets at NS Level ( In): 6 - Packets at NS Level (Out): 6 - Bytes at NS Level ( In): 30 - Bytes at NS Level (Out): 59 - NS-VC Block count : 1 - -Peers: - NSEI 8192, BVCI 8194, not blocked, RAI 112-332-16464-96 - TLLI-Cache: 0 - NSEI 4096, BVCI 4098, not blocked, RAI 112-332-16464-96 - TLLI-Cache: 0 ---- Reset BSS 1 with a new BVCI --- - -Setup BSSGP: remote 0x01020304:1111, BVCI 0x1012(4114) - -PROCESSING BVC_RESET from 0x01020304:1111 -00 00 00 00 22 04 82 10 12 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 12 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 12 07 81 08 08 88 11 22 33 40 50 60 10 00 - -result (BVC_RESET) = 0 - -Current NS-VCIs: - VCI 0x2001, NSEI 0x2000, peer 0x01020304:3333 - Packets at NS Level ( In): 20 - Packets at NS Level (Out): 21 - Bytes at NS Level ( In): 85 - Bytes at NS Level (Out): 69 - NS-VC replaced other count: 1 - VCI 0x1001, NSEI 0x1000, peer 0x01020304:1111 - Packets at NS Level ( In): 15 - Packets at NS Level (Out): 13 - Bytes at NS Level ( In): 101 - Bytes at NS Level (Out): 45 - VCI 0x0101, NSEI 0x0100, peer 0x05060708:32000 - Packets at NS Level ( In): 6 - Packets at NS Level (Out): 7 - Bytes at NS Level ( In): 30 - Bytes at NS Level (Out): 81 - NS-VC Block count : 1 - -Peers: - NSEI 4096, BVCI 4114, not blocked, RAI 112-332-16464-96 - TLLI-Cache: 0 - NSEI 8192, BVCI 8194, not blocked, RAI 112-332-16464-96 - TLLI-Cache: 0 - NSEI 4096, BVCI 4098, not blocked, RAI 112-332-16464-96 - TLLI-Cache: 0 -PROCESSING BVC_RESET_ACK from 0x05060708:32000 -00 00 00 00 23 04 82 10 12 - -CALLBACK, event 0, msg length 5, bvci 0x0000 -00 00 00 00 23 04 82 10 12 - -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 12 - -result (BVC_RESET_ACK) = 0 - ---- Reset BSS 1 with the old BVCI --- - -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 11 22 33 40 50 60 10 00 - -result (BVC_RESET) = 0 - -Current NS-VCIs: - VCI 0x2001, NSEI 0x2000, peer 0x01020304:3333 - Packets at NS Level ( In): 20 - Packets at NS Level (Out): 21 - Bytes at NS Level ( In): 85 - Bytes at NS Level (Out): 69 - NS-VC replaced other count: 1 - VCI 0x1001, NSEI 0x1000, peer 0x01020304:1111 - Packets at NS Level ( In): 16 - Packets at NS Level (Out): 14 - Bytes at NS Level ( In): 123 - Bytes at NS Level (Out): 54 - VCI 0x0101, NSEI 0x0100, peer 0x05060708:32000 - Packets at NS Level ( In): 7 - Packets at NS Level (Out): 8 - Bytes at NS Level ( In): 39 - Bytes at NS Level (Out): 103 - NS-VC Block count : 1 - -Peers: - NSEI 4096, BVCI 4114, not blocked, RAI 112-332-16464-96 - TLLI-Cache: 0 - NSEI 8192, BVCI 8194, not blocked, RAI 112-332-16464-96 - TLLI-Cache: 0 - NSEI 4096, BVCI 4098, not blocked, RAI 112-332-16464-96 - TLLI-Cache: 0 -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) = 0 - ---- Reset BSS 1 with the old BVCI again --- - -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 11 22 33 40 50 60 10 00 - -result (BVC_RESET) = 0 - -Current NS-VCIs: - VCI 0x2001, NSEI 0x2000, peer 0x01020304:3333 - Packets at NS Level ( In): 20 - Packets at NS Level (Out): 21 - Bytes at NS Level ( In): 85 - Bytes at NS Level (Out): 69 - NS-VC replaced other count: 1 - VCI 0x1001, NSEI 0x1000, peer 0x01020304:1111 - Packets at NS Level ( In): 17 - Packets at NS Level (Out): 15 - Bytes at NS Level ( In): 145 - Bytes at NS Level (Out): 63 - VCI 0x0101, NSEI 0x0100, peer 0x05060708:32000 - Packets at NS Level ( In): 8 - Packets at NS Level (Out): 9 - Bytes at NS Level ( In): 48 - Bytes at NS Level (Out): 125 - NS-VC Block count : 1 - -Peers: - NSEI 4096, BVCI 4114, not blocked, RAI 112-332-16464-96 - TLLI-Cache: 0 - NSEI 8192, BVCI 8194, not blocked, RAI 112-332-16464-96 - TLLI-Cache: 0 - NSEI 4096, BVCI 4098, not blocked, RAI 112-332-16464-96 - TLLI-Cache: 0 -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) = 0 - ---- Send message from BSS 1 to SGSN, BVCI 0x1012 --- - -PROCESSING UNITDATA from 0x01020304:1111 -00 00 10 12 - -CALLBACK, event 0, msg length 0, bvci 0x1012 -00 00 10 12 - -NS UNITDATA MESSAGE to SGSN, BVCI 0x1012, msg length 0 (gprs_ns_sendmsg) -MESSAGE to SGSN at 0x05060708:32000, msg length 4 -00 00 10 12 - -result (UNITDATA) = 0 - ---- Send message from SGSN to BSS 1, BVCI 0x1012 --- - -PROCESSING UNITDATA from 0x05060708:32000 -00 00 10 12 - -CALLBACK, event 0, msg length 0, bvci 0x1012 -00 00 10 12 - -NS UNITDATA MESSAGE to BSS, BVCI 0x1012, msg length 0 (gprs_ns_sendmsg) -MESSAGE to BSS at 0x01020304:1111, msg length 4 -00 00 10 12 - -result (UNITDATA) = 0 - ---- Send message from BSS 1 to SGSN, BVCI 0x1002 --- - -PROCESSING UNITDATA from 0x01020304:1111 -00 00 10 12 - -CALLBACK, event 0, msg length 0, bvci 0x1012 -00 00 10 12 - -NS UNITDATA MESSAGE to SGSN, BVCI 0x1012, msg length 0 (gprs_ns_sendmsg) -MESSAGE to SGSN at 0x05060708:32000, msg length 4 -00 00 10 12 - -result (UNITDATA) = 0 - ---- Send message from SGSN to BSS 1, BVCI 0x1002 --- - -PROCESSING UNITDATA from 0x05060708:32000 -00 00 10 12 - -CALLBACK, event 0, msg length 0, bvci 0x1012 -00 00 10 12 - -NS UNITDATA MESSAGE to BSS, BVCI 0x1012, msg length 0 (gprs_ns_sendmsg) -MESSAGE to BSS at 0x01020304:1111, msg length 4 -00 00 10 12 - -result (UNITDATA) = 0 - ---- Send message from BSS 2 to SGSN, BVCI 0x2002 --- - -PROCESSING UNITDATA from 0x01020304:1111 -00 00 20 02 - -CALLBACK, event 0, msg length 0, bvci 0x2002 -00 00 20 02 - -NS UNITDATA MESSAGE to SGSN, BVCI 0x2002, msg length 0 (gprs_ns_sendmsg) -MESSAGE to SGSN at 0x05060708:32000, msg length 4 -00 00 20 02 - -result (UNITDATA) = 0 - ---- Send message from SGSN to BSS 2, BVCI 0x2002 --- - -PROCESSING UNITDATA from 0x05060708:32000 -00 00 20 02 - -CALLBACK, event 0, msg length 0, bvci 0x2002 -00 00 20 02 - -NS UNITDATA MESSAGE to BSS, BVCI 0x2002, msg length 0 (gprs_ns_sendmsg) -MESSAGE to BSS at 0x01020304:3333, msg length 4 -00 00 20 02 - -result (UNITDATA) = 0 - ---- Reset BSS 1 with the old BVCI on BSS2's link --- - -Setup BSSGP: remote 0x01020304:3333, BVCI 0x1002(4098) - -PROCESSING BVC_RESET from 0x01020304:3333 -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 11 22 33 40 50 60 10 00 - -result (BVC_RESET) = 0 - -Current NS-VCIs: - VCI 0x2001, NSEI 0x2000, peer 0x01020304:3333 - Packets at NS Level ( In): 21 - Packets at NS Level (Out): 22 - Bytes at NS Level ( In): 107 - Bytes at NS Level (Out): 73 - NS-VC replaced other count: 1 - VCI 0x1001, NSEI 0x1000, peer 0x01020304:1111 - Packets at NS Level ( In): 20 - Packets at NS Level (Out): 18 - Bytes at NS Level ( In): 157 - Bytes at NS Level (Out): 80 - VCI 0x0101, NSEI 0x0100, peer 0x05060708:32000 - Packets at NS Level ( In): 12 - Packets at NS Level (Out): 13 - Bytes at NS Level ( In): 69 - Bytes at NS Level (Out): 159 - NS-VC Block count : 1 - -Peers: - NSEI 4096, BVCI 4114, not blocked, RAI 112-332-16464-96 - TLLI-Cache: 0 - NSEI 8192, BVCI 8194, not blocked, RAI 112-332-16464-96 - NSEI mismatch : 1 - TLLI-Cache: 0 - NSEI 8192, BVCI 4098, not blocked, RAI 112-332-16464-96 - NSEI mismatch : 1 - TLLI-Cache: 0 -Gbproxy global: -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:3333, msg length 9 -00 00 00 00 23 04 82 10 02 - -result (BVC_RESET_ACK) = 0 - ---- Send message from BSS 1 to SGSN, BVCI 0x1002 --- - -PROCESSING UNITDATA from 0x01020304:1111 -00 00 10 12 - -CALLBACK, event 0, msg length 0, bvci 0x1012 -00 00 10 12 - -NS UNITDATA MESSAGE to SGSN, BVCI 0x1012, msg length 0 (gprs_ns_sendmsg) -MESSAGE to SGSN at 0x05060708:32000, msg length 4 -00 00 10 12 - -result (UNITDATA) = 0 - ---- Send message from SGSN to BSS 1, BVCI 0x1002 --- - -PROCESSING UNITDATA from 0x05060708:32000 -00 00 10 12 - -CALLBACK, event 0, msg length 0, bvci 0x1012 -00 00 10 12 - -NS UNITDATA MESSAGE to BSS, BVCI 0x1012, msg length 0 (gprs_ns_sendmsg) -MESSAGE to BSS at 0x01020304:1111, msg length 4 -00 00 10 12 - -result (UNITDATA) = 0 - ---- Send message from SGSN to BSS 1, BVCI 0x10ff (invalid) --- - -PROCESSING UNITDATA from 0x05060708:32000 -00 00 10 ff - -CALLBACK, event 0, msg length 0, bvci 0x10ff -00 00 10 ff - -NS UNITDATA MESSAGE to SGSN, BVCI 0x0000, msg length 10 (gprs_ns_sendmsg) -MESSAGE to SGSN at 0x05060708:32000, msg length 14 -00 00 00 00 41 07 81 05 04 82 10 ff 15 80 - -result (UNITDATA) = 0 - -Peers: - NSEI 8192, BVCI 8194, not blocked, RAI 112-332-16464-96 - NSEI mismatch : 1 - TLLI-Cache: 0 - NSEI 8192, BVCI 4098, not blocked, RAI 112-332-16464-96 - NSEI mismatch : 1 - TLLI-Cache: 0 -Gbproxy global: - Invalid BVC Identifier : 1 -=== test_gbproxy_ident_changes === ---- 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) = 0 - -PROCESSING ALIVE_ACK from 0x05060708:32000 -0b - -MESSAGE to SGSN at 0x05060708:32000, msg length 1 -06 - -result (ALIVE_ACK) = 0 - -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) = 0 - -Current NS-VCIs: - VCI 0x0101, NSEI 0x0100, peer 0x05060708:32000 - Packets at NS Level ( In): 4 - Packets at NS Level (Out): 4 - Bytes at NS Level ( In): 12 - Bytes at NS Level (Out): 15 - NS-VC Block count : 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) = 0 - -PROCESSING ALIVE from 0x01020304:1111 -0a - -MESSAGE to BSS at 0x01020304:1111, msg length 1 -0b - -result (ALIVE) = 0 - -PROCESSING UNBLOCK from 0x01020304:1111 -06 - -MESSAGE to BSS at 0x01020304:1111, msg length 1 -07 - -==> got signal NS_UNBLOCK, NS-VC 0x1001/1.2.3.4:1111 - -result (UNBLOCK) = 0 - -PROCESSING ALIVE_ACK from 0x01020304:1111 -0b - -result (ALIVE_ACK) = 0 - -Current NS-VCIs: - VCI 0x1001, NSEI 0x1000, peer 0x01020304:1111 - Packets at NS Level ( In): 4 - Packets at NS Level (Out): 4 - Bytes at NS Level ( In): 15 - Bytes at NS Level (Out): 12 - VCI 0x0101, NSEI 0x0100, peer 0x05060708:32000 - Packets at NS Level ( In): 4 - Packets at NS Level (Out): 4 - Bytes at NS Level ( In): 12 - Bytes at NS Level (Out): 15 - NS-VC Block count : 1 - ---- Setup BVCI 1 --- - -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 11 22 33 40 50 60 10 00 - -result (BVC_RESET) = 0 - -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) = 0 - -Peers: - NSEI 4096, BVCI 4098, not blocked, RAI 112-332-16464-96 - TLLI-Cache: 0 ---- Setup BVCI 2 --- - -Setup BSSGP: remote 0x01020304:1111, BVCI 0x2002(8194) - -PROCESSING BVC_RESET from 0x01020304:1111 -00 00 00 00 22 04 82 20 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 20 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 20 02 07 81 08 08 88 11 22 33 40 50 60 10 00 - -result (BVC_RESET) = 0 - -PROCESSING BVC_RESET_ACK from 0x05060708:32000 -00 00 00 00 23 04 82 20 02 - -CALLBACK, event 0, msg length 5, bvci 0x0000 -00 00 00 00 23 04 82 20 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 20 02 - -result (BVC_RESET_ACK) = 0 - -Peers: - NSEI 4096, BVCI 8194, not blocked, RAI 112-332-16464-96 - TLLI-Cache: 0 - NSEI 4096, BVCI 4098, not blocked, RAI 112-332-16464-96 - TLLI-Cache: 0 ---- Send message from BSS 1 to SGSN and back, BVCI 1 --- - -PROCESSING UNITDATA from 0x01020304:1111 -00 00 10 02 - -CALLBACK, event 0, msg length 0, bvci 0x1002 -00 00 10 02 - -NS UNITDATA MESSAGE to SGSN, BVCI 0x1002, msg length 0 (gprs_ns_sendmsg) -MESSAGE to SGSN at 0x05060708:32000, msg length 4 -00 00 10 02 - -result (UNITDATA) = 0 - -PROCESSING UNITDATA from 0x05060708:32000 -00 00 10 02 - -CALLBACK, event 0, msg length 0, bvci 0x1002 -00 00 10 02 - -NS UNITDATA MESSAGE to BSS, BVCI 0x1002, msg length 0 (gprs_ns_sendmsg) -MESSAGE to BSS at 0x01020304:1111, msg length 4 -00 00 10 02 - -result (UNITDATA) = 0 - ---- Send message from BSS 1 to SGSN and back, BVCI 2 --- - -PROCESSING UNITDATA from 0x01020304:1111 -00 00 20 02 - -CALLBACK, event 0, msg length 0, bvci 0x2002 -00 00 20 02 - -NS UNITDATA MESSAGE to SGSN, BVCI 0x2002, msg length 0 (gprs_ns_sendmsg) -MESSAGE to SGSN at 0x05060708:32000, msg length 4 -00 00 20 02 - -result (UNITDATA) = 0 - -PROCESSING UNITDATA from 0x05060708:32000 -00 00 20 02 - -CALLBACK, event 0, msg length 0, bvci 0x2002 -00 00 20 02 - -NS UNITDATA MESSAGE to BSS, BVCI 0x2002, msg length 0 (gprs_ns_sendmsg) -MESSAGE to BSS at 0x01020304:1111, msg length 4 -00 00 20 02 - -result (UNITDATA) = 0 - ---- Change NSEI --- - -Setup NS-VC: remote 0x01020304:1111, NSVCI 0x1001(4097), NSEI 0x2000(8192) - -PROCESSING RESET from 0x01020304:1111 -02 00 81 01 01 82 10 01 04 82 20 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 20 00 - -MESSAGE to BSS at 0x01020304:1111, msg length 1 -0a - -result (RESET) = 0 - -PROCESSING ALIVE from 0x01020304:1111 -0a - -MESSAGE to BSS at 0x01020304:1111, msg length 1 -0b - -result (ALIVE) = 0 - -PROCESSING UNBLOCK from 0x01020304:1111 -06 - -MESSAGE to BSS at 0x01020304:1111, msg length 1 -07 - -==> got signal NS_UNBLOCK, NS-VC 0x1001/1.2.3.4:1111 - -result (UNBLOCK) = 0 - -PROCESSING ALIVE_ACK from 0x01020304:1111 -0b - -result (ALIVE_ACK) = 0 - -Current NS-VCIs: - VCI 0x1001, NSEI 0x2000, peer 0x01020304:1111 - Packets at NS Level ( In): 12 - Packets at NS Level (Out): 12 - Bytes at NS Level ( In): 82 - Bytes at NS Level (Out): 50 - NS-VC changed NSEI count : 1 - VCI 0x0101, NSEI 0x0100, peer 0x05060708:32000 - Packets at NS Level ( In): 8 - Packets at NS Level (Out): 8 - Bytes at NS Level ( In): 38 - Bytes at NS Level (Out): 67 - NS-VC Block count : 1 - ---- Setup BVCI 1 --- - -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 11 22 33 40 50 60 10 00 - -result (BVC_RESET) = 0 - -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) = 0 - -Peers: - NSEI 4096, BVCI 8194, not blocked, RAI 112-332-16464-96 - TLLI-Cache: 0 - NSEI 8192, BVCI 4098, not blocked, RAI 112-332-16464-96 - NSEI mismatch : 1 - TLLI-Cache: 0 ---- Setup BVCI 3 --- - -Setup BSSGP: remote 0x01020304:1111, BVCI 0x3002(12290) - -PROCESSING BVC_RESET from 0x01020304:1111 -00 00 00 00 22 04 82 30 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 30 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 30 02 07 81 08 08 88 11 22 33 40 50 60 10 00 - -result (BVC_RESET) = 0 - -PROCESSING BVC_RESET_ACK from 0x05060708:32000 -00 00 00 00 23 04 82 30 02 - -CALLBACK, event 0, msg length 5, bvci 0x0000 -00 00 00 00 23 04 82 30 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 30 02 - -result (BVC_RESET_ACK) = 0 - -Peers: - NSEI 8192, BVCI 12290, not blocked, RAI 112-332-16464-96 - TLLI-Cache: 0 - NSEI 4096, BVCI 8194, not blocked, RAI 112-332-16464-96 - TLLI-Cache: 0 - NSEI 8192, BVCI 4098, not blocked, RAI 112-332-16464-96 - NSEI mismatch : 1 - TLLI-Cache: 0 ---- Send message from BSS 1 to SGSN and back, BVCI 1 --- - -PROCESSING UNITDATA from 0x01020304:1111 -00 00 10 02 - -CALLBACK, event 0, msg length 0, bvci 0x1002 -00 00 10 02 - -NS UNITDATA MESSAGE to SGSN, BVCI 0x1002, msg length 0 (gprs_ns_sendmsg) -MESSAGE to SGSN at 0x05060708:32000, msg length 4 -00 00 10 02 - -result (UNITDATA) = 0 - -PROCESSING UNITDATA from 0x05060708:32000 -00 00 10 02 - -CALLBACK, event 0, msg length 0, bvci 0x1002 -00 00 10 02 - -NS UNITDATA MESSAGE to BSS, BVCI 0x1002, msg length 0 (gprs_ns_sendmsg) -MESSAGE to BSS at 0x01020304:1111, msg length 4 -00 00 10 02 - -result (UNITDATA) = 0 - ---- Send message from BSS 1 to SGSN and back, BVCI 2 (should fail) --- - -PROCESSING UNITDATA from 0x01020304:1111 -00 00 20 02 - -CALLBACK, event 0, msg length 0, bvci 0x2002 -00 00 20 02 - -NS UNITDATA MESSAGE to SGSN, BVCI 0x2002, msg length 0 (gprs_ns_sendmsg) -MESSAGE to SGSN at 0x05060708:32000, msg length 4 -00 00 20 02 - -result (UNITDATA) = 0 - -Peers: - NSEI 8192, BVCI 12290, not blocked, RAI 112-332-16464-96 - TLLI-Cache: 0 - NSEI 4096, BVCI 8194, not blocked, RAI 112-332-16464-96 - NSEI mismatch : 1 - TLLI-Cache: 0 - NSEI 8192, BVCI 4098, not blocked, RAI 112-332-16464-96 - NSEI mismatch : 1 - TLLI-Cache: 0 -PROCESSING UNITDATA from 0x05060708:32000 -00 00 20 02 - -CALLBACK, event 0, msg length 0, bvci 0x2002 -00 00 20 02 - -NS UNITDATA MESSAGE to BSS, BVCI 0x2002, msg length 0 (gprs_ns_sendmsg) -result (UNITDATA) = -22 - -Peers: - NSEI 8192, BVCI 12290, not blocked, RAI 112-332-16464-96 - TLLI-Cache: 0 - NSEI 4096, BVCI 8194, not blocked, RAI 112-332-16464-96 - NSEI mismatch : 1 - NS Transmission error : 1 - TLLI-Cache: 0 - NSEI 8192, BVCI 4098, not blocked, RAI 112-332-16464-96 - NSEI mismatch : 1 - TLLI-Cache: 0 ---- Send message from BSS 1 to SGSN and back, BVCI 3 --- - -PROCESSING UNITDATA from 0x01020304:1111 -00 00 30 02 - -CALLBACK, event 0, msg length 0, bvci 0x3002 -00 00 30 02 - -NS UNITDATA MESSAGE to SGSN, BVCI 0x3002, msg length 0 (gprs_ns_sendmsg) -MESSAGE to SGSN at 0x05060708:32000, msg length 4 -00 00 30 02 - -result (UNITDATA) = 0 - -PROCESSING UNITDATA from 0x05060708:32000 -00 00 30 02 - -CALLBACK, event 0, msg length 0, bvci 0x3002 -00 00 30 02 - -NS UNITDATA MESSAGE to BSS, BVCI 0x3002, msg length 0 (gprs_ns_sendmsg) -MESSAGE to BSS at 0x01020304:1111, msg length 4 -00 00 30 02 - -result (UNITDATA) = 0 - ---- Change NSVCI --- - -Setup NS-VC: remote 0x01020304:1111, NSVCI 0x2001(8193), NSEI 0x2000(8192) - -PROCESSING RESET from 0x01020304:1111 -02 00 81 01 01 82 20 01 04 82 20 00 - -==> got signal NS_REPLACED: 0x2001/0.0.0.0:0 -> 0x1001/1.2.3.4:1111 - -==> got signal NS_RESET, NS-VC 0x2001/1.2.3.4:1111 - -MESSAGE to BSS at 0x01020304:1111, msg length 9 -03 01 82 20 01 04 82 20 00 - -MESSAGE to BSS at 0x01020304:1111, msg length 1 -0a - -result (RESET) = 0 - -PROCESSING ALIVE from 0x01020304:1111 -0a - -MESSAGE to BSS at 0x01020304:1111, msg length 1 -0b - -result (ALIVE) = 0 - -PROCESSING UNBLOCK from 0x01020304:1111 -06 - -MESSAGE to BSS at 0x01020304:1111, msg length 1 -07 - -==> got signal NS_UNBLOCK, NS-VC 0x2001/1.2.3.4:1111 - -result (UNBLOCK) = 0 - -PROCESSING ALIVE_ACK from 0x01020304:1111 -0b - -result (ALIVE_ACK) = 0 - -Current NS-VCIs: - VCI 0x2001, NSEI 0x2000, peer 0x01020304:1111 - Packets at NS Level ( In): 3 - Packets at NS Level (Out): 4 - Bytes at NS Level ( In): 3 - Bytes at NS Level (Out): 12 - NS-VC replaced other count: 1 - VCI 0x1001, NSEI 0x2000, peer 0x00000000:0 - Packets at NS Level ( In): 18 - Packets at NS Level (Out): 16 - Bytes at NS Level ( In): 150 - Bytes at NS Level (Out): 76 - NS-VC changed NSEI count : 1 - VCI 0x0101, NSEI 0x0100, peer 0x05060708:32000 - Packets at NS Level ( In): 13 - Packets at NS Level (Out): 13 - Bytes at NS Level ( In): 68 - Bytes at NS Level (Out): 123 - NS-VC Block count : 1 - ---- Setup BVCI 1 --- - -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 11 22 33 40 50 60 10 00 - -result (BVC_RESET) = 0 - -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) = 0 - -Peers: - NSEI 8192, BVCI 12290, not blocked, RAI 112-332-16464-96 - TLLI-Cache: 0 - NSEI 4096, BVCI 8194, not blocked, RAI 112-332-16464-96 - NSEI mismatch : 1 - NS Transmission error : 1 - TLLI-Cache: 0 - NSEI 8192, BVCI 4098, not blocked, RAI 112-332-16464-96 - NSEI mismatch : 1 - TLLI-Cache: 0 ---- Setup BVCI 4 --- - -Setup BSSGP: remote 0x01020304:1111, BVCI 0x4002(16386) - -PROCESSING BVC_RESET from 0x01020304:1111 -00 00 00 00 22 04 82 40 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 40 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 40 02 07 81 08 08 88 11 22 33 40 50 60 10 00 - -result (BVC_RESET) = 0 - -PROCESSING BVC_RESET_ACK from 0x05060708:32000 -00 00 00 00 23 04 82 40 02 - -CALLBACK, event 0, msg length 5, bvci 0x0000 -00 00 00 00 23 04 82 40 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 40 02 - -result (BVC_RESET_ACK) = 0 - -Peers: - NSEI 8192, BVCI 16386, not blocked, RAI 112-332-16464-96 - TLLI-Cache: 0 - NSEI 8192, BVCI 12290, not blocked, RAI 112-332-16464-96 - TLLI-Cache: 0 - NSEI 4096, BVCI 8194, not blocked, RAI 112-332-16464-96 - NSEI mismatch : 1 - NS Transmission error : 1 - TLLI-Cache: 0 - NSEI 8192, BVCI 4098, not blocked, RAI 112-332-16464-96 - NSEI mismatch : 1 - TLLI-Cache: 0 ---- Send message from BSS 1 to SGSN and back, BVCI 1 --- - -PROCESSING UNITDATA from 0x01020304:1111 -00 00 10 02 - -CALLBACK, event 0, msg length 0, bvci 0x1002 -00 00 10 02 - -NS UNITDATA MESSAGE to SGSN, BVCI 0x1002, msg length 0 (gprs_ns_sendmsg) -MESSAGE to SGSN at 0x05060708:32000, msg length 4 -00 00 10 02 - -result (UNITDATA) = 0 - -PROCESSING UNITDATA from 0x05060708:32000 -00 00 10 02 - -CALLBACK, event 0, msg length 0, bvci 0x1002 -00 00 10 02 - -NS UNITDATA MESSAGE to BSS, BVCI 0x1002, msg length 0 (gprs_ns_sendmsg) -MESSAGE to BSS at 0x01020304:1111, msg length 4 -00 00 10 02 - -result (UNITDATA) = 0 - ---- Send message from BSS 1 to SGSN and back, BVCI 2 (should fail) --- - -PROCESSING UNITDATA from 0x01020304:1111 -00 00 20 02 - -CALLBACK, event 0, msg length 0, bvci 0x2002 -00 00 20 02 - -NS UNITDATA MESSAGE to SGSN, BVCI 0x2002, msg length 0 (gprs_ns_sendmsg) -MESSAGE to SGSN at 0x05060708:32000, msg length 4 -00 00 20 02 - -result (UNITDATA) = 0 - -Peers: - NSEI 8192, BVCI 16386, not blocked, RAI 112-332-16464-96 - TLLI-Cache: 0 - NSEI 8192, BVCI 12290, not blocked, RAI 112-332-16464-96 - TLLI-Cache: 0 - NSEI 4096, BVCI 8194, not blocked, RAI 112-332-16464-96 - NSEI mismatch : 2 - NS Transmission error : 1 - TLLI-Cache: 0 - NSEI 8192, BVCI 4098, not blocked, RAI 112-332-16464-96 - NSEI mismatch : 1 - TLLI-Cache: 0 -PROCESSING UNITDATA from 0x05060708:32000 -00 00 20 02 - -CALLBACK, event 0, msg length 0, bvci 0x2002 -00 00 20 02 - -NS UNITDATA MESSAGE to BSS, BVCI 0x2002, msg length 0 (gprs_ns_sendmsg) -result (UNITDATA) = -22 - -Peers: - NSEI 8192, BVCI 16386, not blocked, RAI 112-332-16464-96 - TLLI-Cache: 0 - NSEI 8192, BVCI 12290, not blocked, RAI 112-332-16464-96 - TLLI-Cache: 0 - NSEI 4096, BVCI 8194, not blocked, RAI 112-332-16464-96 - NSEI mismatch : 2 - NS Transmission error : 2 - TLLI-Cache: 0 - NSEI 8192, BVCI 4098, not blocked, RAI 112-332-16464-96 - NSEI mismatch : 1 - TLLI-Cache: 0 ---- Send message from BSS 1 to SGSN and back, BVCI 3 --- - -PROCESSING UNITDATA from 0x01020304:1111 -00 00 30 02 - -CALLBACK, event 0, msg length 0, bvci 0x3002 -00 00 30 02 - -NS UNITDATA MESSAGE to SGSN, BVCI 0x3002, msg length 0 (gprs_ns_sendmsg) -MESSAGE to SGSN at 0x05060708:32000, msg length 4 -00 00 30 02 - -result (UNITDATA) = 0 - -PROCESSING UNITDATA from 0x05060708:32000 -00 00 30 02 - -CALLBACK, event 0, msg length 0, bvci 0x3002 -00 00 30 02 - -NS UNITDATA MESSAGE to BSS, BVCI 0x3002, msg length 0 (gprs_ns_sendmsg) -MESSAGE to BSS at 0x01020304:1111, msg length 4 -00 00 30 02 - -result (UNITDATA) = 0 - ---- Send message from BSS 1 to SGSN and back, BVCI 4 --- - -PROCESSING UNITDATA from 0x01020304:1111 -00 00 40 02 - -CALLBACK, event 0, msg length 0, bvci 0x4002 -00 00 40 02 - -NS UNITDATA MESSAGE to SGSN, BVCI 0x4002, msg length 0 (gprs_ns_sendmsg) -MESSAGE to SGSN at 0x05060708:32000, msg length 4 -00 00 40 02 - -result (UNITDATA) = 0 - -PROCESSING UNITDATA from 0x05060708:32000 -00 00 40 02 - -CALLBACK, event 0, msg length 0, bvci 0x4002 -00 00 40 02 - -NS UNITDATA MESSAGE to BSS, BVCI 0x4002, msg length 0 (gprs_ns_sendmsg) -MESSAGE to BSS at 0x01020304:1111, msg length 4 -00 00 40 02 - -result (UNITDATA) = 0 - -Gbproxy global: -Peers: - NSEI 8192, BVCI 16386, not blocked, RAI 112-332-16464-96 - TLLI-Cache: 0 - NSEI 8192, BVCI 12290, not blocked, RAI 112-332-16464-96 - TLLI-Cache: 0 - NSEI 4096, BVCI 8194, not blocked, RAI 112-332-16464-96 - NSEI mismatch : 2 - NS Transmission error : 2 - TLLI-Cache: 0 - NSEI 8192, BVCI 4098, not blocked, RAI 112-332-16464-96 - NSEI mismatch : 1 - TLLI-Cache: 0 -=== Test IMSI/TMSI matching === - -=== test_gbproxy_ptmsi_assignment === ---- 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) = 0 - -PROCESSING ALIVE_ACK from 0x05060708:32000 -0b - -MESSAGE to SGSN at 0x05060708:32000, msg length 1 -06 - -result (ALIVE_ACK) = 0 - -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) = 0 - ---- 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) = 0 - -PROCESSING ALIVE from 0x01020304:1111 -0a - -MESSAGE to BSS at 0x01020304:1111, msg length 1 -0b - -result (ALIVE) = 0 - -PROCESSING UNBLOCK from 0x01020304:1111 -06 - -MESSAGE to BSS at 0x01020304:1111, msg length 1 -07 - -==> got signal NS_UNBLOCK, NS-VC 0x1001/1.2.3.4:1111 - -result (UNBLOCK) = 0 - -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 11 22 33 40 50 60 10 00 - -result (BVC_RESET) = 0 - -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) = 0 - -Current NS-VCIs: - VCI 0x1001, NSEI 0x1000, peer 0x01020304:1111 - Packets at NS Level ( In): 5 - Packets at NS Level (Out): 5 - Bytes at NS Level ( In): 37 - Bytes at NS Level (Out): 21 - VCI 0x0101, NSEI 0x0100, peer 0x05060708:32000 - Packets at NS Level ( In): 5 - Packets at NS Level (Out): 5 - Bytes at NS Level ( In): 21 - Bytes at NS Level (Out): 37 - NS-VC Block count : 1 - -Gbproxy global: -Peers: - NSEI 4096, BVCI 4098, not blocked, RAI 112-332-16464-96 - TLLI-Cache: 0 ---- Establish first LLC connection --- - -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 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 - -result (ATTACH REQUEST) = 0 - -Peers: - NSEI 4096, BVCI 4098, not blocked, RAI 112-332-16464-96 - Attach Request count : 1 - TLLI cache size : 1 - TLLI-Cache: 1 - TLLI 8000dead -> 8000dead, IMSI (none), AGE 0 -PROCESSING IDENT REQUEST from 0x05060708:32000 -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 - -CALLBACK, event 0, msg length 23, bvci 0x1002 -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 - -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) = 0 - -Peers: - NSEI 4096, BVCI 4098, not blocked, RAI 112-332-16464-96 - Attach Request count : 1 - TLLI cache size : 1 - TLLI-Cache: 1 - TLLI 8000dead -> 8000dead, 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 f8 07 e1 ae - -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 f8 07 e1 ae - -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 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 f8 07 e1 ae - -result (IDENT RESPONSE) = 0 - -Peers: - NSEI 4096, BVCI 4098, not blocked, RAI 112-332-16464-96 - Attach Request count : 1 - TLLI cache size : 1 - TLLI-Cache: 1 - TLLI 8000dead -> 8000dead, IMSI 12131415161718, AGE 0 -PROCESSING ATTACH ACCEPT from 0x05060708:32000 -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 f8 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 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 f8 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 f8 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 - -result (ATTACH ACCEPT) = 0 - -Peers: - NSEI 4096, BVCI 4098, not blocked, RAI 112-332-16464-96 - Attach Request count : 1 - Attach Accept count : 1 - TLLI cache size : 1 - TLLI-Cache: 1 - TLLI 8000dead/efe2b700 -> 8000dead/efe2b700, IMSI 12131415161718, AGE 0 -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 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 ef e2 b7 00 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 11 22 33 40 50 60 12 34 00 80 0e 00 08 01 c0 09 08 03 39 d7 bc - -result (ATTACH COMPLETE) = 0 - -Peers: - NSEI 4096, BVCI 4098, not blocked, RAI 112-332-16464-96 - Attach Request count : 1 - Attach Accept count : 1 - Attach Completed count : 1 - TLLI cache size : 1 - TLLI-Cache: 1 - TLLI 8000dead/efe2b700 -> 8000dead/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 f8 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 f8 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 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 f8 00 81 00 0e 88 41 c0 09 08 21 04 ba 3d - -result (GMM INFO) = 0 - -Peers: - NSEI 4096, BVCI 4098, not blocked, RAI 112-332-16464-96 - Attach Request count : 1 - Attach Accept count : 1 - Attach Completed count : 1 - TLLI cache size : 1 - TLLI-Cache: 1 - TLLI efe2b700 -> efe2b700, IMSI 12131415161718, AGE 0 ---- Establish second LLC connection with the same P-TMSI --- - -PROCESSING ATTACH REQUEST from 0x01020304:1111 -00 00 10 02 01 80 00 be ef 00 00 04 08 88 00 f1 99 00 63 60 12 34 00 80 0e 00 34 01 c0 0d 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 46 42 6e - -CALLBACK, event 0, msg length 75, bvci 0x1002 -00 00 10 02 01 80 00 be ef 00 00 04 08 88 00 f1 99 00 63 60 12 34 00 80 0e 00 34 01 c0 0d 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 46 42 6e - -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 80 00 be ef 00 00 04 08 88 00 f1 99 00 63 60 12 34 00 80 0e 00 34 01 c0 0d 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 46 42 6e - -result (ATTACH REQUEST) = 0 - -Peers: - NSEI 4096, BVCI 4098, not blocked, RAI 112-332-16464-96 - Attach Request count : 2 - Attach Accept count : 1 - Attach Completed count : 1 - TLLI cache size : 2 - TLLI-Cache: 2 - TLLI 8000beef -> 8000beef, IMSI (none), AGE 0 - TLLI efe2b700 -> efe2b700, IMSI 12131415161718, AGE 0 -PROCESSING IDENT REQUEST from 0x05060708:32000 -00 00 10 02 00 80 00 be ef 00 50 20 16 82 02 58 0e 89 41 c0 0d 08 15 01 0c a6 18 - -CALLBACK, event 0, msg length 23, bvci 0x1002 -00 00 10 02 00 80 00 be ef 00 50 20 16 82 02 58 0e 89 41 c0 0d 08 15 01 0c a6 18 - -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 be ef 00 50 20 16 82 02 58 0e 89 41 c0 0d 08 15 01 0c a6 18 - -result (IDENT REQUEST) = 0 - -Peers: - NSEI 4096, BVCI 4098, not blocked, RAI 112-332-16464-96 - Attach Request count : 2 - Attach Accept count : 1 - Attach Completed count : 1 - TLLI cache size : 2 - TLLI-Cache: 2 - TLLI 8000beef -> 8000beef, IMSI (none), AGE 0 - TLLI efe2b700 -> efe2b700, IMSI 12131415161718, AGE 0 -PROCESSING IDENT RESPONSE from 0x01020304:1111 -00 00 10 02 01 80 00 be ef 00 00 04 08 88 11 22 33 40 50 60 12 34 00 80 0e 00 11 01 c0 11 08 16 08 11 12 99 99 99 16 17 f8 15 36 87 - -CALLBACK, event 0, msg length 40, bvci 0x1002 -00 00 10 02 01 80 00 be ef 00 00 04 08 88 11 22 33 40 50 60 12 34 00 80 0e 00 11 01 c0 11 08 16 08 11 12 99 99 99 16 17 f8 15 36 87 - -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 80 00 be ef 00 00 04 08 88 11 22 33 40 50 60 12 34 00 80 0e 00 11 01 c0 11 08 16 08 11 12 99 99 99 16 17 f8 15 36 87 - -result (IDENT RESPONSE) = 0 - -Peers: - NSEI 4096, BVCI 4098, not blocked, RAI 112-332-16464-96 - Attach Request count : 2 - Attach Accept count : 1 - Attach Completed count : 1 - TLLI cache size : 2 - TLLI-Cache: 2 - TLLI 8000beef -> 8000beef, IMSI 12199999961718, AGE 0 - TLLI efe2b700 -> efe2b700, IMSI 12131415161718, AGE 0 -PROCESSING ATTACH ACCEPT from 0x05060708:32000 -00 00 10 02 00 80 00 be ef 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 99 99 99 16 17 f8 00 81 00 0e 9e 41 c0 11 08 02 01 49 04 21 63 54 40 50 60 19 cd d7 08 17 16 18 05 f4 ef e2 b7 00 3a 6d d4 - -CALLBACK, event 0, msg length 88, bvci 0x1002 -00 00 10 02 00 80 00 be ef 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 99 99 99 16 17 f8 00 81 00 0e 9e 41 c0 11 08 02 01 49 04 21 63 54 40 50 60 19 cd d7 08 17 16 18 05 f4 ef e2 b7 00 3a 6d d4 - -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 be ef 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 99 99 99 16 17 f8 00 81 00 0e 9e 41 c0 11 08 02 01 49 04 21 63 54 40 50 60 19 cd d7 08 17 16 18 05 f4 ef e2 b7 00 3a 6d d4 - -result (ATTACH ACCEPT) = 0 - -Peers: - NSEI 4096, BVCI 4098, not blocked, RAI 112-332-16464-96 - Attach Request count : 2 - Attach Accept count : 2 - Attach Completed count : 1 - TLLI cache size : 1 - TLLI-Cache: 1 - TLLI 8000beef/efe2b700 -> 8000beef/efe2b700, IMSI 12199999961718, AGE 0 -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 12 34 00 80 0e 00 08 01 c0 15 08 03 86 ac 47 - -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 12 34 00 80 0e 00 08 01 c0 15 08 03 86 ac 47 - -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 11 22 33 40 50 60 12 34 00 80 0e 00 08 01 c0 15 08 03 86 ac 47 - -result (ATTACH COMPLETE) = 0 - -Peers: - NSEI 4096, BVCI 4098, not blocked, RAI 112-332-16464-96 - Attach Request count : 2 - Attach Accept count : 2 - Attach Completed count : 2 - TLLI cache size : 1 - TLLI-Cache: 1 - TLLI 8000beef/efe2b700 -> 8000beef/efe2b700, IMSI 12199999961718, 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 99 99 99 16 17 f8 00 81 00 0e 88 41 c0 15 08 21 bb c1 c6 - -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 99 99 99 16 17 f8 00 81 00 0e 88 41 c0 15 08 21 bb c1 c6 - -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 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 99 99 99 16 17 f8 00 81 00 0e 88 41 c0 15 08 21 bb c1 c6 - -result (GMM INFO) = 0 - -Peers: - NSEI 4096, BVCI 4098, not blocked, RAI 112-332-16464-96 - Attach Request count : 2 - Attach Accept count : 2 - Attach Completed count : 2 - TLLI cache size : 1 - TLLI-Cache: 1 - TLLI efe2b700 -> efe2b700, IMSI 12199999961718, AGE 0 -Gbproxy global: -=== test_gbproxy_ra_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) = 0 - -PROCESSING ALIVE_ACK from 0x05060708:32000 -0b - -MESSAGE to SGSN at 0x05060708:32000, msg length 1 -06 - -result (ALIVE_ACK) = 0 - -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) = 0 - -Current NS-VCIs: - VCI 0x0101, NSEI 0x0100, peer 0x05060708:32000 - Packets at NS Level ( In): 4 - Packets at NS Level (Out): 4 - Bytes at NS Level ( In): 12 - Bytes at NS Level (Out): 15 - NS-VC Block count : 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) = 0 - -PROCESSING ALIVE from 0x01020304:1111 -0a - -MESSAGE to BSS at 0x01020304:1111, msg length 1 -0b - -result (ALIVE) = 0 - -PROCESSING UNBLOCK from 0x01020304:1111 -06 - -MESSAGE to BSS at 0x01020304:1111, msg length 1 -07 - -==> got signal NS_UNBLOCK, NS-VC 0x1001/1.2.3.4:1111 - -result (UNBLOCK) = 0 - -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) = 0 - -Current NS-VCIs: - VCI 0x1001, NSEI 0x1000, peer 0x01020304:1111 - Packets at NS Level ( In): 5 - Packets at NS Level (Out): 4 - Bytes at NS Level ( In): 37 - Bytes at NS Level (Out): 12 - VCI 0x0101, NSEI 0x0100, peer 0x05060708:32000 - Packets at NS Level ( In): 4 - Packets at NS Level (Out): 5 - Bytes at NS Level ( In): 12 - Bytes at NS Level (Out): 37 - NS-VC Block count : 1 - -Peers: - NSEI 4096, BVCI 4098, not blocked, RAI 112-332-16464-96 - RAID patched (BSS ): 1 - TLLI-Cache: 0 -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) = 0 - -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) = 0 - -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) = 0 - -Gbproxy global: -Peers: - NSEI 4096, BVCI 4098, not blocked, RAI 112-332-16464-96 - RAID patched (BSS ): 2 - RAID patched (SGSN): 1 - TLLI from SGSN unknown : 1 - TLLI-Cache: 0 ---- Send message from BSS 1 to SGSN, BVCI 0x1002 --- - -PROCESSING ATTACH REQUEST from 0x01020304:1111 -00 00 10 02 01 bb c5 46 79 00 00 04 08 88 11 22 33 40 50 60 75 30 00 80 0e 00 34 01 c0 01 08 01 02 f5 e0 21 08 02 05 f4 fb c5 46 79 11 22 33 40 50 60 19 18 b3 43 2b 25 96 62 00 60 80 9a c2 c6 62 00 60 80 ba c8 c6 62 00 60 80 00 16 6d 01 - -CALLBACK, event 0, msg length 75, bvci 0x1002 -00 00 10 02 01 bb c5 46 79 00 00 04 08 88 11 22 33 40 50 60 75 30 00 80 0e 00 34 01 c0 01 08 01 02 f5 e0 21 08 02 05 f4 fb c5 46 79 11 22 33 40 50 60 19 18 b3 43 2b 25 96 62 00 60 80 9a c2 c6 62 00 60 80 ba c8 c6 62 00 60 80 00 16 6d 01 - -NS UNITDATA MESSAGE to SGSN, BVCI 0x1002, msg length 75 (gprs_ns_sendmsg) -MESSAGE to SGSN at 0x05060708:32000, msg length 79 -00 00 10 02 01 bb c5 46 79 00 00 04 08 88 21 63 54 40 50 60 75 30 00 80 0e 00 34 01 c0 01 08 01 02 f5 e0 21 08 02 05 f4 fb c5 46 79 21 63 54 40 50 60 19 18 b3 43 2b 25 96 62 00 60 80 9a c2 c6 62 00 60 80 ba c8 c6 62 00 60 80 00 8e cd 32 - -result (ATTACH REQUEST) = 0 - -PROCESSING IDENT REQUEST from 0x05060708:32000 -00 00 10 02 00 bb c5 46 79 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 bb c5 46 79 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 bb c5 46 79 00 50 20 16 82 02 58 0e 89 41 c0 01 08 15 01 ff 6c ba - -result (IDENT REQUEST) = 0 - -PROCESSING IDENT RESPONSE from 0x01020304:1111 -00 00 10 02 01 bb c5 46 79 00 00 04 08 88 11 22 33 40 50 60 75 30 00 80 0e 00 11 01 c0 0d 08 16 08 11 12 13 14 15 16 17 f8 1d ff 1c - -CALLBACK, event 0, msg length 40, bvci 0x1002 -00 00 10 02 01 bb c5 46 79 00 00 04 08 88 11 22 33 40 50 60 75 30 00 80 0e 00 11 01 c0 0d 08 16 08 11 12 13 14 15 16 17 f8 1d ff 1c - -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 bb c5 46 79 00 00 04 08 88 21 63 54 40 50 60 75 30 00 80 0e 00 11 01 c0 0d 08 16 08 11 12 13 14 15 16 17 f8 1d ff 1c - -result (IDENT RESPONSE) = 0 - -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 f8 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 f8 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 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 f8 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 ef e2 b7 00 be 38 c0 - -result (ATTACH ACCEPT) = 0 - -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) = 0 - -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 - -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 81 (gprs_ns_sendmsg) -MESSAGE to SGSN at 0x05060708:32000, msg length 85 -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 3a 01 c0 0d 0a 41 05 03 0c 00 00 1f 10 00 00 00 00 00 00 00 00 02 01 21 28 08 03 66 6f 6f 03 62 61 72 27 14 80 80 21 10 01 00 00 10 81 06 00 00 00 00 83 06 00 00 00 00 24 9d 75 - -result (ACT PDP CTX REQ (REPLACE APN)) = 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 f8 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 f8 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 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 f8 00 81 00 0e 88 41 c0 09 08 21 04 ba 3d - -result (GMM INFO) = 0 - -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 - -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 81 (gprs_ns_sendmsg) -MESSAGE to SGSN at 0x05060708:32000, msg length 85 -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 3a 01 c0 0d 0a 41 05 03 0c 00 00 1f 10 00 00 00 00 00 00 00 00 02 01 21 28 08 03 66 6f 6f 03 62 61 72 27 14 80 80 21 10 01 00 00 10 81 06 00 00 00 00 83 06 00 00 00 00 24 9d 75 - -result (ACT PDP CTX REQ (REPLACE APN)) = 0 - -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 - -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 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)) = 0 - -Peers: - NSEI 4096, BVCI 4098, not blocked, RAI 112-332-16464-96 - RAID patched (BSS ): 9 - RAID patched (SGSN): 2 - APN patched : 3 - Attach Request count : 1 - Attach Accept count : 1 - Attach Completed count : 1 - PDP Activation Request count : 3 - TLLI from SGSN unknown : 1 - TLLI cache size : 1 - TLLI-Cache: 1 - TLLI efe2b700 -> efe2b700, IMSI 12131415161718, AGE 0, IMSI matches -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) = 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 f8 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 f8 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 f8 00 81 00 0e 89 41 c0 15 08 06 00 f7 35 f0 - -result (DETACH ACC) = 0 - -Peers: - NSEI 4096, BVCI 4098, not blocked, RAI 112-332-16464-96 - RAID patched (BSS ): 10 - RAID patched (SGSN): 2 - APN patched : 3 - Attach Request count : 1 - Attach Accept count : 1 - Attach Completed count : 1 - Detach Request count : 1 - Detach Accept count : 1 - PDP Activation Request count : 3 - TLLI from SGSN unknown : 1 - TLLI-Cache: 0 ---- RA update --- - -PROCESSING RA UPD REQ from 0x01020304:1111 -00 00 10 02 01 bb c5 46 79 00 00 04 08 88 11 22 33 40 50 60 70 80 00 80 0e 00 3e 01 c0 15 08 08 10 11 22 33 40 50 60 1d 19 13 42 33 57 2b f7 c8 48 02 13 48 50 c8 48 02 14 48 50 c8 48 02 17 49 10 c8 48 02 00 19 8b b2 92 17 16 27 07 04 31 02 e5 e0 32 02 20 00 96 3e 97 - -CALLBACK, event 0, msg length 85, bvci 0x1002 -00 00 10 02 01 bb c5 46 79 00 00 04 08 88 11 22 33 40 50 60 70 80 00 80 0e 00 3e 01 c0 15 08 08 10 11 22 33 40 50 60 1d 19 13 42 33 57 2b f7 c8 48 02 13 48 50 c8 48 02 14 48 50 c8 48 02 17 49 10 c8 48 02 00 19 8b b2 92 17 16 27 07 04 31 02 e5 e0 32 02 20 00 96 3e 97 - -NS UNITDATA MESSAGE to SGSN, BVCI 0x1002, msg length 85 (gprs_ns_sendmsg) -MESSAGE to SGSN at 0x05060708:32000, msg length 89 -00 00 10 02 01 bb c5 46 79 00 00 04 08 88 21 63 54 40 50 60 70 80 00 80 0e 00 3e 01 c0 15 08 08 10 21 63 54 40 50 60 1d 19 13 42 33 57 2b f7 c8 48 02 13 48 50 c8 48 02 14 48 50 c8 48 02 17 49 10 c8 48 02 00 19 8b b2 92 17 16 27 07 04 31 02 e5 e0 32 02 20 00 1d f0 41 - -result (RA UPD REQ) = 0 - -PROCESSING RA UPD ACC 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 f8 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 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 f8 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 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 f8 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) = 0 - -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 - -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 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)) = 0 - -Peers: - NSEI 4096, BVCI 4098, not blocked, RAI 112-332-16464-96 - RAID patched (BSS ): 13 - RAID patched (SGSN): 3 - APN patched : 4 - Attach Request count : 1 - Attach Accept count : 1 - Attach Completed count : 1 - RoutingArea Update Request count: 1 - RoutingArea Update Accept count : 1 - Detach Request count : 1 - Detach Accept count : 1 - PDP Activation Request count : 4 - TLLI from SGSN unknown : 1 - TLLI cache size : 1 - TLLI-Cache: 1 - TLLI bbc54679/efe2b700 -> bbc54679/efe2b700, IMSI 12131415161718, AGE 0, IMSI matches -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)) = 0 - -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 - Attach Accept count : 1 - Attach Completed count : 1 - RoutingArea Update Request count: 1 - RoutingArea Update Accept count : 1 - Detach Request count : 2 - Detach Accept count : 1 - PDP Activation Request count : 4 - TLLI from SGSN unknown : 1 - TLLI-Cache: 0 ---- Bad cases --- - -PROCESSING ATTACH REQUEST (foreign RAI) from 0x01020304:1111 -00 00 10 02 01 bb 00 be ef 00 00 04 08 88 11 22 33 40 50 60 75 30 00 80 0e 00 34 01 c0 01 08 01 02 f5 e0 21 08 02 05 f4 fb 00 be ef 99 99 99 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 2d c7 df - -CALLBACK, event 0, msg length 75, bvci 0x1002 -00 00 10 02 01 bb 00 be ef 00 00 04 08 88 11 22 33 40 50 60 75 30 00 80 0e 00 34 01 c0 01 08 01 02 f5 e0 21 08 02 05 f4 fb 00 be ef 99 99 99 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 2d c7 df - -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 bb 00 be ef 00 00 04 08 88 21 63 54 40 50 60 75 30 00 80 0e 00 34 01 c0 01 08 01 02 f5 e0 21 08 02 05 f4 fb 00 be ef 99 99 99 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 2d c7 df - -result (ATTACH REQUEST (foreign RAI)) = 0 - -TLLI is already detached, shouldn't patch -PROCESSING ACT PDP CTX 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 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 - -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 - -result (ACT PDP CTX REQ) = 0 - -Invalid RAI, shouldn't patch -PROCESSING BVC_SUSPEND_ACK from 0x05060708:32000 -00 00 00 00 0c 1f 84 cc d1 75 8b 1b 86 00 f1 99 00 63 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 00 f1 99 00 63 60 1d 81 01 - -NS UNITDATA MESSAGE to SGSN, BVCI 0x0000, msg length 24 (gprs_ns_sendmsg) -MESSAGE to SGSN at 0x05060708:32000, msg length 28 -00 00 00 00 41 07 81 21 15 92 0c 1f 84 cc d1 75 8b 1b 86 00 f1 99 00 63 60 1d 81 01 - -result (BVC_SUSPEND_ACK) = 0 - -Gbproxy global: - Invalid Routing Area Identifier : 1 - Patch error: no peer : 1 -Peers: - NSEI 4096, BVCI 4098, not blocked, RAI 112-332-16464-96 - RAID patched (BSS ): 16 - RAID patched (SGSN): 3 - APN patched : 4 - Attach Request count : 2 - Attach Accept count : 1 - Attach Completed count : 1 - RoutingArea Update Request count: 1 - RoutingArea Update Accept count : 1 - Detach Request count : 2 - Detach Accept count : 1 - PDP Activation Request count : 5 - TLLI from SGSN unknown : 1 - TLLI cache size : 2 - TLLI-Cache: 2 - TLLI efe2b700 -> efe2b700, IMSI (none), AGE 0 - TLLI bb00beef -> bb00beef, 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) = 0 - -PROCESSING ALIVE_ACK from 0x05060708:32000 -0b - -MESSAGE to SGSN at 0x05060708:32000, msg length 1 -06 - -result (ALIVE_ACK) = 0 - -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) = 0 - ---- 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) = 0 - -PROCESSING ALIVE from 0x01020304:1111 -0a - -MESSAGE to BSS at 0x01020304:1111, msg length 1 -0b - -result (ALIVE) = 0 - -PROCESSING UNBLOCK from 0x01020304:1111 -06 - -MESSAGE to BSS at 0x01020304:1111, msg length 1 -07 - -==> got signal NS_UNBLOCK, NS-VC 0x1001/1.2.3.4:1111 - -result (UNBLOCK) = 0 - -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) = 0 - -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) = 0 - -Current NS-VCIs: - VCI 0x1001, NSEI 0x1000, peer 0x01020304:1111 - Packets at NS Level ( In): 5 - Packets at NS Level (Out): 5 - Bytes at NS Level ( In): 37 - Bytes at NS Level (Out): 21 - VCI 0x0101, NSEI 0x0100, peer 0x05060708:32000 - Packets at NS Level ( In): 5 - Packets at NS Level (Out): 5 - Bytes at NS Level ( In): 21 - Bytes at NS Level (Out): 37 - NS-VC Block count : 1 - -Gbproxy global: -Peers: - NSEI 4096, BVCI 4098, not blocked, RAI 112-332-16464-96 - RAID patched (BSS ): 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 78 de ad 00 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) = 0 - -Peers: - NSEI 4096, BVCI 4098, not blocked, RAI 112-332-16464-96 - RAID patched (BSS ): 2 - TLLI patched (BSS ): 1 - Attach Request count : 1 - TLLI cache size : 1 - TLLI-Cache: 1 - TLLI 8000dead -> 78dead00, IMSI (none), AGE 0 -PROCESSING IDENT REQUEST from 0x05060708:32000 -00 00 10 02 00 78 de ad 00 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 78 de ad 00 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) = 0 - -Peers: - NSEI 4096, BVCI 4098, not blocked, RAI 112-332-16464-96 - RAID patched (BSS ): 2 - TLLI patched (BSS ): 1 - TLLI patched (SGSN): 1 - Attach Request count : 1 - TLLI cache size : 1 - TLLI-Cache: 1 - TLLI 8000dead -> 78dead00, 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 f8 07 e1 ae - -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 f8 07 e1 ae - -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 78 de ad 00 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 f8 07 e1 ae - -result (IDENT RESPONSE) = 0 - -Peers: - NSEI 4096, BVCI 4098, not blocked, RAI 112-332-16464-96 - RAID patched (BSS ): 3 - TLLI patched (BSS ): 2 - TLLI patched (SGSN): 1 - Attach Request count : 1 - TLLI cache size : 1 - TLLI-Cache: 1 - TLLI 8000dead -> 78dead00, IMSI 12131415161718, AGE 0 -PROCESSING ATTACH ACCEPT from 0x05060708:32000 -00 00 10 02 00 78 de ad 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 f8 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 78 de ad 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 f8 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 f8 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 de ad 01 0c 0a 29 - -result (ATTACH ACCEPT) = 0 - -Peers: - NSEI 4096, BVCI 4098, not blocked, RAI 112-332-16464-96 - RAID patched (BSS ): 3 - RAID patched (SGSN): 1 - TLLI patched (BSS ): 2 - TLLI patched (SGSN): 2 - P-TMSI patched (SGSN): 1 - Attach Request count : 1 - Attach Accept count : 1 - TLLI cache size : 1 - TLLI-Cache: 1 - TLLI 8000dead/c0dead01 -> 78dead00/efe2b700, IMSI 12131415161718, AGE 0 -PROCESSING ATTACH COMPLETE from 0x01020304:1111 -00 00 10 02 01 c0 de ad 01 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 de ad 01 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) = 0 - -Peers: - NSEI 4096, BVCI 4098, not blocked, RAI 112-332-16464-96 - RAID patched (BSS ): 4 - RAID patched (SGSN): 1 - TLLI patched (BSS ): 3 - TLLI patched (SGSN): 2 - P-TMSI patched (SGSN): 1 - Attach Request count : 1 - Attach Accept count : 1 - Attach Completed count : 1 - TLLI cache size : 1 - TLLI-Cache: 1 - TLLI 8000dead/c0dead01 -> 78dead00/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 f8 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 f8 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 de ad 01 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 f8 00 81 00 0e 88 41 c0 09 08 21 04 ba 3d - -result (GMM INFO) = 0 - -Peers: - NSEI 4096, BVCI 4098, not blocked, RAI 112-332-16464-96 - RAID patched (BSS ): 4 - RAID patched (SGSN): 1 - TLLI patched (BSS ): 3 - TLLI patched (SGSN): 3 - P-TMSI patched (SGSN): 1 - Attach Request count : 1 - Attach Accept count : 1 - Attach Completed count : 1 - TLLI cache size : 1 - TLLI-Cache: 1 - TLLI c0dead01 -> efe2b700, IMSI 12131415161718, AGE 0 -PROCESSING ACT PDP CTX REQ (REPLACE APN) from 0x01020304:1111 -00 00 10 02 01 c0 de ad 01 00 00 04 08 88 11 22 33 40 50 60 12 34 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 - -CALLBACK, event 0, msg length 76, bvci 0x1002 -00 00 10 02 01 c0 de ad 01 00 00 04 08 88 11 22 33 40 50 60 12 34 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 81 (gprs_ns_sendmsg) -MESSAGE to SGSN at 0x05060708:32000, msg length 85 -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 3a 01 c0 0d 0a 41 05 03 0c 00 00 1f 10 00 00 00 00 00 00 00 00 02 01 21 28 08 03 66 6f 6f 03 62 61 72 27 14 80 80 21 10 01 00 00 10 81 06 00 00 00 00 83 06 00 00 00 00 24 9d 75 - -result (ACT PDP CTX REQ (REPLACE APN)) = 0 - -Peers: - NSEI 4096, BVCI 4098, not blocked, RAI 112-332-16464-96 - RAID patched (BSS ): 5 - RAID patched (SGSN): 1 - APN patched : 1 - TLLI patched (BSS ): 4 - TLLI patched (SGSN): 3 - P-TMSI patched (SGSN): 1 - Attach Request count : 1 - Attach Accept count : 1 - Attach Completed count : 1 - PDP Activation Request count : 1 - TLLI cache size : 1 - TLLI-Cache: 1 - TLLI c0dead01 -> efe2b700, IMSI 12131415161718, AGE 0 -PROCESSING XID (UL) from 0x01020304:1111 -00 00 10 02 01 c0 de ad 01 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 de ad 01 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)) = 0 - -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 f8 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 f8 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 de ad 01 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 f8 00 81 00 0e 8c 41 fb 30 84 10 61 b6 64 e4 a9 1a 9e - -result (XID (DL)) = 0 - -PROCESSING LL11 DNS QUERY (UL) from 0x01020304:1111 -00 00 10 02 01 c0 de ad 01 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 de ad 01 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)) = 0 - -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 f8 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 f8 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 de ad 01 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 f8 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)) = 0 - -Peers: - NSEI 4096, BVCI 4098, not blocked, RAI 112-332-16464-96 - RAID patched (BSS ): 7 - RAID patched (SGSN): 1 - APN patched : 1 - TLLI patched (BSS ): 6 - TLLI patched (SGSN): 5 - P-TMSI patched (SGSN): 1 - Attach Request count : 1 - Attach Accept count : 1 - Attach Completed count : 1 - PDP Activation Request count : 1 - TLLI cache size : 1 - TLLI-Cache: 1 - TLLI c0dead01 -> efe2b700, IMSI 12131415161718, AGE 0 -PROCESSING RA UPD REQ (P-TMSI 2) from 0x01020304:1111 -00 00 10 02 01 c0 de ad 01 00 00 04 08 88 11 22 33 40 50 60 70 80 00 80 0e 00 3e 01 c0 11 08 08 10 11 22 33 40 50 60 1d 19 13 42 33 57 2b f7 c8 48 02 13 48 50 c8 48 02 14 48 50 c8 48 02 17 49 10 c8 48 02 00 19 8b b2 92 17 16 27 07 04 31 02 e5 e0 32 02 20 00 e2 6d 78 - -CALLBACK, event 0, msg length 85, bvci 0x1002 -00 00 10 02 01 c0 de ad 01 00 00 04 08 88 11 22 33 40 50 60 70 80 00 80 0e 00 3e 01 c0 11 08 08 10 11 22 33 40 50 60 1d 19 13 42 33 57 2b f7 c8 48 02 13 48 50 c8 48 02 14 48 50 c8 48 02 17 49 10 c8 48 02 00 19 8b b2 92 17 16 27 07 04 31 02 e5 e0 32 02 20 00 e2 6d 78 - -NS UNITDATA MESSAGE to SGSN, BVCI 0x1002, msg length 85 (gprs_ns_sendmsg) -MESSAGE to SGSN at 0x05060708:32000, msg length 89 -00 00 10 02 01 ef e2 b7 00 00 00 04 08 88 21 63 54 40 50 60 70 80 00 80 0e 00 3e 01 c0 11 08 08 10 21 63 54 40 50 60 1d 19 13 42 33 57 2b f7 c8 48 02 13 48 50 c8 48 02 14 48 50 c8 48 02 17 49 10 c8 48 02 00 19 8b b2 92 17 16 27 07 04 31 02 e5 e0 32 02 20 00 69 a3 ae - -result (RA UPD REQ (P-TMSI 2)) = 0 - -PROCESSING RA UDP ACC (P-TMSI 2) 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 f8 00 81 00 0e 9d 41 c0 0d 08 09 00 49 21 63 54 40 50 60 19 54 ab b3 18 05 f4 e0 98 76 54 17 16 9f e8 ea - -CALLBACK, event 0, msg length 87, 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 f8 00 81 00 0e 9d 41 c0 0d 08 09 00 49 21 63 54 40 50 60 19 54 ab b3 18 05 f4 e0 98 76 54 17 16 9f e8 ea - -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 c0 de ad 01 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 f8 00 81 00 0e 9d 41 c0 0d 08 09 00 49 11 22 33 40 50 60 19 54 ab b3 18 05 f4 c0 de ad 02 17 16 bb 4d a0 - -result (RA UDP ACC (P-TMSI 2)) = 0 - -Peers: - NSEI 4096, BVCI 4098, not blocked, RAI 112-332-16464-96 - RAID patched (BSS ): 9 - RAID patched (SGSN): 2 - APN patched : 1 - TLLI patched (BSS ): 7 - TLLI patched (SGSN): 6 - P-TMSI patched (SGSN): 2 - Attach Request count : 1 - Attach Accept count : 1 - Attach Completed count : 1 - RoutingArea Update Request count: 1 - RoutingArea Update Accept count : 1 - PDP Activation Request count : 1 - TLLI cache size : 1 - TLLI-Cache: 1 - TLLI c0dead01/c0dead02 -> efe2b700/e0987654, IMSI 12131415161718, AGE 0 -PROCESSING RA UPD REQ (P-TMSI 3) from 0x01020304:1111 -00 00 10 02 01 c0 de ad 02 00 00 04 08 88 11 22 33 40 50 60 70 80 00 80 0e 00 3e 01 c0 15 08 08 10 11 22 33 40 50 60 1d 19 13 42 33 57 2b f7 c8 48 02 13 48 50 c8 48 02 14 48 50 c8 48 02 17 49 10 c8 48 02 00 19 8b b2 92 17 16 27 07 04 31 02 e5 e0 32 02 20 00 96 3e 97 - -CALLBACK, event 0, msg length 85, bvci 0x1002 -00 00 10 02 01 c0 de ad 02 00 00 04 08 88 11 22 33 40 50 60 70 80 00 80 0e 00 3e 01 c0 15 08 08 10 11 22 33 40 50 60 1d 19 13 42 33 57 2b f7 c8 48 02 13 48 50 c8 48 02 14 48 50 c8 48 02 17 49 10 c8 48 02 00 19 8b b2 92 17 16 27 07 04 31 02 e5 e0 32 02 20 00 96 3e 97 - -NS UNITDATA MESSAGE to SGSN, BVCI 0x1002, msg length 85 (gprs_ns_sendmsg) -MESSAGE to SGSN at 0x05060708:32000, msg length 89 -00 00 10 02 01 e0 98 76 54 00 00 04 08 88 21 63 54 40 50 60 70 80 00 80 0e 00 3e 01 c0 15 08 08 10 21 63 54 40 50 60 1d 19 13 42 33 57 2b f7 c8 48 02 13 48 50 c8 48 02 14 48 50 c8 48 02 17 49 10 c8 48 02 00 19 8b b2 92 17 16 27 07 04 31 02 e5 e0 32 02 20 00 1d f0 41 - -result (RA UPD REQ (P-TMSI 3)) = 0 - -PROCESSING RA UDP ACC (P-TMSI 3) from 0x05060708:32000 -00 00 10 02 00 e0 98 76 54 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 f8 00 81 00 0e 9d 41 c0 11 08 09 00 49 21 63 54 40 50 60 19 54 ab b3 18 05 f4 e0 54 32 10 17 16 1b a3 a8 - -CALLBACK, event 0, msg length 87, bvci 0x1002 -00 00 10 02 00 e0 98 76 54 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 f8 00 81 00 0e 9d 41 c0 11 08 09 00 49 21 63 54 40 50 60 19 54 ab b3 18 05 f4 e0 54 32 10 17 16 1b a3 a8 - -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 c0 de ad 02 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 f8 00 81 00 0e 9d 41 c0 11 08 09 00 49 11 22 33 40 50 60 19 54 ab b3 18 05 f4 c0 de ad 03 17 16 6e 58 26 - -result (RA UDP ACC (P-TMSI 3)) = 0 - -Peers: - NSEI 4096, BVCI 4098, not blocked, RAI 112-332-16464-96 - RAID patched (BSS ): 11 - RAID patched (SGSN): 3 - APN patched : 1 - TLLI patched (BSS ): 8 - TLLI patched (SGSN): 7 - P-TMSI patched (SGSN): 3 - Attach Request count : 1 - Attach Accept count : 1 - Attach Completed count : 1 - RoutingArea Update Request count: 2 - RoutingArea Update Accept count : 2 - PDP Activation Request count : 1 - TLLI cache size : 1 - TLLI-Cache: 1 - TLLI c0dead01/c0dead03 -> efe2b700/e0543210, IMSI 12131415161718, AGE 0 -PROCESSING RA UPD COMPLETE from 0x01020304:1111 -00 00 10 02 01 c0 de ad 03 00 00 04 08 88 11 22 33 40 50 60 70 80 00 80 0e 00 08 01 c0 19 08 0a d5 5f 5e - -CALLBACK, event 0, msg length 31, bvci 0x1002 -00 00 10 02 01 c0 de ad 03 00 00 04 08 88 11 22 33 40 50 60 70 80 00 80 0e 00 08 01 c0 19 08 0a d5 5f 5e - -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 e0 54 32 10 00 00 04 08 88 21 63 54 40 50 60 70 80 00 80 0e 00 08 01 c0 19 08 0a d5 5f 5e - -result (RA UPD COMPLETE) = 0 - -PROCESSING GMM INFO from 0x05060708:32000 -00 00 10 02 00 e0 54 32 10 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 f8 00 81 00 0e 88 41 c0 15 08 21 bb c1 c6 - -CALLBACK, event 0, msg length 66, bvci 0x1002 -00 00 10 02 00 e0 54 32 10 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 f8 00 81 00 0e 88 41 c0 15 08 21 bb c1 c6 - -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 de ad 03 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 f8 00 81 00 0e 88 41 c0 15 08 21 bb c1 c6 - -result (GMM INFO) = 0 - -Peers: - NSEI 4096, BVCI 4098, not blocked, RAI 112-332-16464-96 - RAID patched (BSS ): 12 - RAID patched (SGSN): 3 - APN patched : 1 - TLLI patched (BSS ): 9 - TLLI patched (SGSN): 8 - P-TMSI patched (SGSN): 3 - Attach Request count : 1 - Attach Accept count : 1 - Attach Completed count : 1 - RoutingArea Update Request count: 2 - RoutingArea Update Accept count : 2 - RoutingArea Update Compltd count: 1 - PDP Activation Request count : 1 - TLLI cache size : 1 - TLLI-Cache: 1 - TLLI c0dead03 -> e0543210, IMSI 12131415161718, AGE 0 -PROCESSING LLC_DISCARDED from 0x01020304:1111 -00 00 00 00 2c 1f 84 c0 de ad 03 0f 81 01 04 82 10 02 25 83 00 00 0c - -CALLBACK, event 0, msg length 19, bvci 0x0000 -00 00 00 00 2c 1f 84 c0 de ad 03 0f 81 01 04 82 10 02 25 83 00 00 0c - -NS UNITDATA MESSAGE to SGSN, BVCI 0x0000, msg length 19 (gprs_ns_sendmsg) -MESSAGE to SGSN at 0x05060708:32000, msg length 23 -00 00 00 00 2c 1f 84 e0 54 32 10 0f 81 01 04 82 10 02 25 83 00 00 0c - -result (LLC_DISCARDED) = 0 - -Peers: - NSEI 4096, BVCI 4098, not blocked, RAI 112-332-16464-96 - RAID patched (BSS ): 12 - RAID patched (SGSN): 3 - APN patched : 1 - TLLI patched (BSS ): 10 - TLLI patched (SGSN): 8 - P-TMSI patched (SGSN): 3 - Attach Request count : 1 - Attach Accept count : 1 - Attach Completed count : 1 - RoutingArea Update Request count: 2 - RoutingArea Update Accept count : 2 - RoutingArea Update Compltd count: 1 - PDP Activation Request count : 1 - TLLI cache size : 1 - TLLI-Cache: 1 - TLLI c0dead03 -> e0543210, IMSI 12131415161718, AGE 0 -PROCESSING BVC_SUSPEND from 0x01020304:1111 -00 00 00 00 0b 1f 84 c0 de ad 03 1b 86 11 22 33 40 50 60 - -CALLBACK, event 0, msg length 15, bvci 0x0000 -00 00 00 00 0b 1f 84 c0 de ad 03 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 e0 54 32 10 1b 86 21 63 54 40 50 60 - -result (BVC_SUSPEND) = 0 - -Peers: - NSEI 4096, BVCI 4098, not blocked, RAI 112-332-16464-96 - RAID patched (BSS ): 13 - RAID patched (SGSN): 3 - APN patched : 1 - TLLI patched (BSS ): 11 - TLLI patched (SGSN): 8 - P-TMSI patched (SGSN): 3 - Attach Request count : 1 - Attach Accept count : 1 - Attach Completed count : 1 - RoutingArea Update Request count: 2 - RoutingArea Update Accept count : 2 - RoutingArea Update Compltd count: 1 - PDP Activation Request count : 1 - TLLI cache size : 1 - TLLI-Cache: 1 - TLLI c0dead03 -> e0543210, IMSI 12131415161718, AGE 0 -PROCESSING BVC_SUSPEND_ACK from 0x05060708:32000 -00 00 00 00 0c 1f 84 e0 54 32 10 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 e0 54 32 10 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 c0 de ad 03 1b 86 11 22 33 40 50 60 1d 81 01 - -result (BVC_SUSPEND_ACK) = 0 - -Peers: - NSEI 4096, BVCI 4098, not blocked, RAI 112-332-16464-96 - RAID patched (BSS ): 13 - RAID patched (SGSN): 4 - APN patched : 1 - TLLI patched (BSS ): 11 - TLLI patched (SGSN): 9 - P-TMSI patched (SGSN): 3 - Attach Request count : 1 - Attach Accept count : 1 - Attach Completed count : 1 - RoutingArea Update Request count: 2 - RoutingArea Update Accept count : 2 - RoutingArea Update Compltd count: 1 - PDP Activation Request count : 1 - TLLI cache size : 1 - TLLI-Cache: 1 - TLLI c0dead03 -> e0543210, IMSI 12131415161718, AGE 0 -PROCESSING PAGING_PS from 0x05060708:32000 -00 00 00 00 06 0d 88 11 12 13 14 15 16 17 f8 0a 82 07 04 1b 86 11 22 33 40 50 60 18 83 00 00 00 20 84 e0 54 32 10 - -CALLBACK, event 0, msg length 34, bvci 0x0000 -00 00 00 00 06 0d 88 11 12 13 14 15 16 17 f8 0a 82 07 04 1b 86 11 22 33 40 50 60 18 83 00 00 00 20 84 e0 54 32 10 - -NS UNITDATA MESSAGE to BSS, BVCI 0x0000, msg length 34 (gprs_ns_sendmsg) -MESSAGE to BSS at 0x01020304:1111, msg length 38 -00 00 00 00 06 0d 88 11 12 13 14 15 16 17 f8 0a 82 07 04 1b 86 11 22 33 40 50 60 18 83 00 00 00 20 84 c0 de ad 03 - -result (PAGING_PS) = 0 - -Peers: - NSEI 4096, BVCI 4098, not blocked, RAI 112-332-16464-96 - RAID patched (BSS ): 13 - RAID patched (SGSN): 5 - APN patched : 1 - TLLI patched (BSS ): 11 - TLLI patched (SGSN): 9 - P-TMSI patched (SGSN): 4 - Attach Request count : 1 - Attach Accept count : 1 - Attach Completed count : 1 - RoutingArea Update Request count: 2 - RoutingArea Update Accept count : 2 - RoutingArea Update Compltd count: 1 - PDP Activation Request count : 1 - TLLI cache size : 1 - TLLI-Cache: 1 - TLLI c0dead03 -> e0543210, IMSI 12131415161718, AGE 0 -PROCESSING LLC_DISCARDED from 0x01020304:1111 -00 00 00 00 2c 1f 84 c0 de ad 03 0f 81 01 04 82 ee e1 25 83 00 00 0c - -CALLBACK, event 0, msg length 19, bvci 0x0000 -00 00 00 00 2c 1f 84 c0 de ad 03 0f 81 01 04 82 ee e1 25 83 00 00 0c - -NS UNITDATA MESSAGE to SGSN, BVCI 0x0000, msg length 19 (gprs_ns_sendmsg) -MESSAGE to SGSN at 0x05060708:32000, msg length 23 -00 00 00 00 2c 1f 84 e0 54 32 10 0f 81 01 04 82 ee e1 25 83 00 00 0c - -result (LLC_DISCARDED) = 0 - -Gbproxy global: -PROCESSING BVC_SUSPEND_ACK from 0x05060708:32000 -00 00 00 00 0c 1f 84 e0 54 32 10 1b 86 00 f1 99 00 63 60 1d 81 01 - -CALLBACK, event 0, msg length 18, bvci 0x0000 -00 00 00 00 0c 1f 84 e0 54 32 10 1b 86 00 f1 99 00 63 60 1d 81 01 - -NS UNITDATA MESSAGE to SGSN, BVCI 0x0000, msg length 24 (gprs_ns_sendmsg) -MESSAGE to SGSN at 0x05060708:32000, msg length 28 -00 00 00 00 41 07 81 21 15 92 0c 1f 84 e0 54 32 10 1b 86 00 f1 99 00 63 60 1d 81 01 - -result (BVC_SUSPEND_ACK) = 0 - -Gbproxy global: - Invalid Routing Area Identifier : 1 - Patch error: no peer : 1 -PROCESSING BVC_SUSPEND_ACK from 0x05060708:32000 -00 00 00 00 0c 1f 84 e0 54 32 10 1b 86 99 69 54 40 50 60 1d 81 01 - -CALLBACK, event 0, msg length 18, bvci 0x0000 -00 00 00 00 0c 1f 84 e0 54 32 10 1b 86 99 69 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 c0 de ad 03 1b 86 11 22 33 40 50 60 1d 81 01 - -result (BVC_SUSPEND_ACK) = 0 - -Gbproxy global: - Invalid Routing Area Identifier : 1 - Patch error: no peer : 1 -PROCESSING GMM INFO from 0x05060708:32000 -00 00 10 02 00 ee ba db 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 00 83 00 00 00 0e 88 41 c0 09 08 21 04 ba 3d - -CALLBACK, event 0, msg length 58, bvci 0x1002 -00 00 10 02 00 ee ba db 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 00 83 00 00 00 0e 88 41 c0 09 08 21 04 ba 3d - -NS UNITDATA MESSAGE to BSS, BVCI 0x1002, msg length 58 (gprs_ns_sendmsg) -MESSAGE to BSS at 0x01020304:1111, msg length 62 -00 00 10 02 00 ee ba db 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 00 83 00 00 00 0e 88 41 c0 09 08 21 04 ba 3d - -result (GMM INFO) = 0 - -PROCESSING GMM INFO from 0x05060708:32000 -00 00 10 02 00 ee ba db 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 f8 00 81 00 0e 88 41 c0 0d 08 21 68 71 6b - -CALLBACK, event 0, msg length 66, bvci 0x1002 -00 00 10 02 00 ee ba db 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 f8 00 81 00 0e 88 41 c0 0d 08 21 68 71 6b - -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 ee ba db 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 f8 00 81 00 0e 88 41 c0 0d 08 21 68 71 6b - -result (GMM INFO) = 0 - -PROCESSING DETACH REQ from 0x01020304:1111 -00 00 10 02 01 c0 de ad 03 00 00 04 08 88 11 22 33 40 50 60 12 34 00 80 0e 00 15 01 c0 1d 08 05 01 18 05 f4 ef e2 b7 00 19 03 b9 97 cb aa cc a3 - -CALLBACK, event 0, msg length 44, bvci 0x1002 -00 00 10 02 01 c0 de ad 03 00 00 04 08 88 11 22 33 40 50 60 12 34 00 80 0e 00 15 01 c0 1d 08 05 01 18 05 f4 ef e2 b7 00 19 03 b9 97 cb aa cc a3 - -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 e0 54 32 10 00 00 04 08 88 21 63 54 40 50 60 12 34 00 80 0e 00 15 01 c0 1d 08 05 01 18 05 f4 e0 54 32 10 19 03 b9 97 cb ea 6d af - -result (DETACH REQ) = 0 - -Peers: - NSEI 4096, BVCI 4098, not blocked, RAI 112-332-16464-96 - RAID patched (BSS ): 14 - RAID patched (SGSN): 6 - APN patched : 1 - TLLI patched (BSS ): 13 - TLLI patched (SGSN): 10 - P-TMSI patched (BSS ): 1 - P-TMSI patched (SGSN): 4 - Attach Request count : 1 - Attach Accept count : 1 - Attach Completed count : 1 - RoutingArea Update Request count: 2 - RoutingArea Update Accept count : 2 - RoutingArea Update Compltd count: 1 - Detach Request count : 1 - PDP Activation Request count : 1 - TLLI from SGSN unknown : 2 - TLLI cache size : 1 - TLLI-Cache: 1 - TLLI c0dead03 -> e0543210, IMSI 12131415161718, AGE 0 -PROCESSING DETACH ACC from 0x05060708:32000 -00 00 10 02 00 e0 54 32 10 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 f8 00 81 00 0e 89 41 c0 19 08 06 00 04 ff 52 - -CALLBACK, event 0, msg length 67, bvci 0x1002 -00 00 10 02 00 e0 54 32 10 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 f8 00 81 00 0e 89 41 c0 19 08 06 00 04 ff 52 - -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 de ad 03 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 f8 00 81 00 0e 89 41 c0 19 08 06 00 04 ff 52 - -result (DETACH ACC) = 0 - -Peers: - NSEI 4096, BVCI 4098, not blocked, RAI 112-332-16464-96 - RAID patched (BSS ): 14 - RAID patched (SGSN): 6 - APN patched : 1 - TLLI patched (BSS ): 13 - TLLI patched (SGSN): 11 - P-TMSI patched (BSS ): 1 - P-TMSI patched (SGSN): 4 - Attach Request count : 1 - Attach Accept count : 1 - Attach Completed count : 1 - RoutingArea Update Request count: 2 - RoutingArea Update Accept count : 2 - RoutingArea Update Compltd count: 1 - Detach Request count : 1 - Detach Accept count : 1 - PDP Activation Request count : 1 - TLLI from SGSN unknown : 2 - TLLI-Cache: 0 -Gbproxy global: - Invalid Routing Area Identifier : 1 - Patch error: no peer : 1 -=== test_gbproxy_ptmsi_patching_bad_cases === ---- 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) = 0 - -PROCESSING ALIVE_ACK from 0x05060708:32000 -0b - -MESSAGE to SGSN at 0x05060708:32000, msg length 1 -06 - -result (ALIVE_ACK) = 0 - -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) = 0 - ---- 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) = 0 - -PROCESSING ALIVE from 0x01020304:1111 -0a - -MESSAGE to BSS at 0x01020304:1111, msg length 1 -0b - -result (ALIVE) = 0 - -PROCESSING UNBLOCK from 0x01020304:1111 -06 - -MESSAGE to BSS at 0x01020304:1111, msg length 1 -07 - -==> got signal NS_UNBLOCK, NS-VC 0x1001/1.2.3.4:1111 - -result (UNBLOCK) = 0 - -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) = 0 - -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) = 0 - -Current NS-VCIs: - VCI 0x1001, NSEI 0x1000, peer 0x01020304:1111 - Packets at NS Level ( In): 5 - Packets at NS Level (Out): 5 - Bytes at NS Level ( In): 37 - Bytes at NS Level (Out): 21 - VCI 0x0101, NSEI 0x0100, peer 0x05060708:32000 - Packets at NS Level ( In): 5 - Packets at NS Level (Out): 5 - Bytes at NS Level ( In): 21 - Bytes at NS Level (Out): 37 - NS-VC Block count : 1 - -Gbproxy global: -Peers: - NSEI 4096, BVCI 4098, not blocked, RAI 112-332-16464-96 - RAID patched (BSS ): 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 78 de ad 00 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) = 0 - -Peers: - NSEI 4096, BVCI 4098, not blocked, RAI 112-332-16464-96 - RAID patched (BSS ): 2 - TLLI patched (BSS ): 1 - Attach Request count : 1 - TLLI cache size : 1 - TLLI-Cache: 1 - TLLI 8000dead -> 78dead00, IMSI (none), AGE 0 -PROCESSING IDENT REQUEST from 0x05060708:32000 -00 00 10 02 00 78 de ad 00 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 78 de ad 00 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) = 0 - -Peers: - NSEI 4096, BVCI 4098, not blocked, RAI 112-332-16464-96 - RAID patched (BSS ): 2 - TLLI patched (BSS ): 1 - TLLI patched (SGSN): 1 - Attach Request count : 1 - TLLI cache size : 1 - TLLI-Cache: 1 - TLLI 8000dead -> 78dead00, 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 f8 07 e1 ae - -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 f8 07 e1 ae - -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 78 de ad 00 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 f8 07 e1 ae - -result (IDENT RESPONSE) = 0 - -Peers: - NSEI 4096, BVCI 4098, not blocked, RAI 112-332-16464-96 - RAID patched (BSS ): 3 - TLLI patched (BSS ): 2 - TLLI patched (SGSN): 1 - Attach Request count : 1 - TLLI cache size : 1 - TLLI-Cache: 1 - TLLI 8000dead -> 78dead00, IMSI 12131415161718, AGE 0 -PROCESSING ATTACH ACCEPT from 0x05060708:32000 -00 00 10 02 00 78 de ad 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 f8 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 78 de ad 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 f8 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 f8 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 de ad 01 0c 0a 29 - -result (ATTACH ACCEPT) = 0 - -Peers: - NSEI 4096, BVCI 4098, not blocked, RAI 112-332-16464-96 - RAID patched (BSS ): 3 - RAID patched (SGSN): 1 - TLLI patched (BSS ): 2 - TLLI patched (SGSN): 2 - P-TMSI patched (SGSN): 1 - Attach Request count : 1 - Attach Accept count : 1 - TLLI cache size : 1 - TLLI-Cache: 1 - TLLI 8000dead/c0dead01 -> 78dead00/efe2b700, IMSI 12131415161718, AGE 0 -PROCESSING ATTACH ACCEPT (duplicated) from 0x05060708:32000 -00 00 10 02 00 78 de ad 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 f8 00 81 00 0e 9e 41 c0 09 08 02 01 49 04 21 63 54 40 50 60 19 cd d7 08 17 16 18 05 f4 ef e2 b7 00 1d 9e 24 - -CALLBACK, event 0, msg length 88, bvci 0x1002 -00 00 10 02 00 78 de ad 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 f8 00 81 00 0e 9e 41 c0 09 08 02 01 49 04 21 63 54 40 50 60 19 cd d7 08 17 16 18 05 f4 ef e2 b7 00 1d 9e 24 - -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 f8 00 81 00 0e 9e 41 c0 09 08 02 01 49 04 11 22 33 40 50 60 19 cd d7 08 17 16 18 05 f4 c0 de ad 01 42 f6 fc - -result (ATTACH ACCEPT (duplicated)) = 0 - -Peers: - NSEI 4096, BVCI 4098, not blocked, RAI 112-332-16464-96 - RAID patched (BSS ): 3 - RAID patched (SGSN): 2 - TLLI patched (BSS ): 2 - TLLI patched (SGSN): 3 - P-TMSI patched (SGSN): 2 - Attach Request count : 1 - Attach Accept count : 2 - TLLI cache size : 1 - TLLI-Cache: 1 - TLLI 8000dead/c0dead01 -> 78dead00/efe2b700, IMSI 12131415161718, AGE 0 -PROCESSING ATTACH COMPLETE from 0x01020304:1111 -00 00 10 02 01 c0 de ad 01 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 de ad 01 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) = 0 - -Peers: - NSEI 4096, BVCI 4098, not blocked, RAI 112-332-16464-96 - RAID patched (BSS ): 4 - RAID patched (SGSN): 2 - TLLI patched (BSS ): 3 - TLLI patched (SGSN): 3 - P-TMSI patched (SGSN): 2 - Attach Request count : 1 - Attach Accept count : 2 - Attach Completed count : 1 - TLLI cache size : 1 - TLLI-Cache: 1 - TLLI 8000dead/c0dead01 -> 78dead00/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 f8 00 81 00 0e 88 41 c0 0d 08 21 68 71 6b - -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 f8 00 81 00 0e 88 41 c0 0d 08 21 68 71 6b - -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 de ad 01 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 f8 00 81 00 0e 88 41 c0 0d 08 21 68 71 6b - -result (GMM INFO) = 0 - -Peers: - NSEI 4096, BVCI 4098, not blocked, RAI 112-332-16464-96 - RAID patched (BSS ): 4 - RAID patched (SGSN): 2 - TLLI patched (BSS ): 3 - TLLI patched (SGSN): 4 - P-TMSI patched (SGSN): 2 - Attach Request count : 1 - Attach Accept count : 2 - Attach Completed count : 1 - TLLI cache size : 1 - TLLI-Cache: 1 - TLLI c0dead01 -> efe2b700, IMSI 12131415161718, AGE 0 -PROCESSING DETACH REQ from 0x01020304:1111 -00 00 10 02 01 c0 de ad 01 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 de ad 01 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) = 0 - -Peers: - NSEI 4096, BVCI 4098, not blocked, RAI 112-332-16464-96 - RAID patched (BSS ): 5 - RAID patched (SGSN): 2 - TLLI patched (BSS ): 4 - TLLI patched (SGSN): 4 - P-TMSI patched (SGSN): 2 - Attach Request count : 1 - Attach Accept count : 2 - Attach Completed count : 1 - Detach Request count : 1 - TLLI cache size : 1 - TLLI-Cache: 1 - TLLI c0dead01 -> 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 f8 00 81 00 0e 89 41 c0 11 08 06 00 cf 8a 58 - -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 f8 00 81 00 0e 89 41 c0 11 08 06 00 cf 8a 58 - -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 de ad 01 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 f8 00 81 00 0e 89 41 c0 11 08 06 00 cf 8a 58 - -result (DETACH ACC) = 0 - -Peers: - NSEI 4096, BVCI 4098, not blocked, RAI 112-332-16464-96 - RAID patched (BSS ): 5 - RAID patched (SGSN): 2 - TLLI patched (BSS ): 4 - TLLI patched (SGSN): 5 - P-TMSI patched (SGSN): 2 - Attach Request count : 1 - Attach Accept count : 2 - Attach Completed count : 1 - Detach Request count : 1 - Detach Accept count : 1 - TLLI-Cache: 0 -Gbproxy global: -=== test_gbproxy_imsi_acquisition === ---- 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) = 0 - -PROCESSING ALIVE_ACK from 0x05060708:32000 -0b - -MESSAGE to SGSN at 0x05060708:32000, msg length 1 -06 - -result (ALIVE_ACK) = 0 - -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) = 0 - ---- 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) = 0 - -PROCESSING ALIVE from 0x01020304:1111 -0a - -MESSAGE to BSS at 0x01020304:1111, msg length 1 -0b - -result (ALIVE) = 0 - -PROCESSING UNBLOCK from 0x01020304:1111 -06 - -MESSAGE to BSS at 0x01020304:1111, msg length 1 -07 - -==> got signal NS_UNBLOCK, NS-VC 0x1001/1.2.3.4:1111 - -result (UNBLOCK) = 0 - -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) = 0 - -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) = 0 - -Current NS-VCIs: - VCI 0x1001, NSEI 0x1000, peer 0x01020304:1111 - Packets at NS Level ( In): 5 - Packets at NS Level (Out): 5 - Bytes at NS Level ( In): 37 - Bytes at NS Level (Out): 21 - VCI 0x0101, NSEI 0x0100, peer 0x05060708:32000 - Packets at NS Level ( In): 5 - Packets at NS Level (Out): 5 - Bytes at NS Level ( In): 21 - Bytes at NS Level (Out): 37 - NS-VC Block count : 1 - -Gbproxy global: -Peers: - NSEI 4096, BVCI 4098, not blocked, RAI 112-332-16464-96 - RAID patched (BSS ): 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 11 22 33 40 50 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 11 22 33 40 50 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 BSS, BVCI 0x1002, msg length 24 (gprs_ns_sendmsg) -MESSAGE to BSS at 0x01020304:1111, msg length 28 -00 00 10 02 00 80 00 de ad 00 50 20 16 82 02 58 0e 00 09 41 c4 01 08 15 01 b7 f8 36 - -result (ATTACH REQUEST) = 0 - -Peers: - NSEI 4096, BVCI 4098, not blocked, RAI 112-332-16464-96 - RAID patched (BSS ): 1 - Attach Request count : 1 - TLLI cache size : 1 - TLLI-Cache: 1 - TLLI 8000dead -> 78dead00, IMSI (none), AGE 0, STORED 1, IMSI acquisition in progress -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 f8 07 e1 ae - -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 f8 07 e1 ae - -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 78 de ad 00 00 00 04 08 88 21 63 54 40 50 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 21 63 54 40 50 60 19 18 b3 43 2b 25 96 62 00 60 80 9a c2 c6 62 00 60 80 ba c8 c6 62 00 60 80 00 8e cd 32 - -result (IDENT RESPONSE) = 0 - -Peers: - NSEI 4096, BVCI 4098, not blocked, RAI 112-332-16464-96 - RAID patched (BSS ): 3 - TLLI patched (BSS ): 1 - Attach Request count : 1 - TLLI cache size : 1 - TLLI-Cache: 1 - TLLI 8000dead -> 78dead00, IMSI 12131415161718, AGE 0 -PROCESSING IDENT REQUEST from 0x05060708:32000 -00 00 10 02 00 78 de ad 00 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 78 de ad 00 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) = 0 - -Peers: - NSEI 4096, BVCI 4098, not blocked, RAI 112-332-16464-96 - RAID patched (BSS ): 3 - TLLI patched (BSS ): 1 - TLLI patched (SGSN): 1 - Attach Request count : 1 - TLLI cache size : 1 - TLLI-Cache: 1 - TLLI 8000dead -> 78dead00, IMSI 12131415161718, 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 09 08 16 08 11 12 13 14 15 16 17 f8 10 f0 45 - -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 09 08 16 08 11 12 13 14 15 16 17 f8 10 f0 45 - -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 78 de ad 00 00 00 04 08 88 21 63 54 40 50 60 12 34 00 80 0e 00 11 01 c0 09 08 16 08 11 12 13 14 15 16 17 f8 10 f0 45 - -result (IDENT RESPONSE) = 0 - -Peers: - NSEI 4096, BVCI 4098, not blocked, RAI 112-332-16464-96 - RAID patched (BSS ): 4 - TLLI patched (BSS ): 2 - TLLI patched (SGSN): 1 - Attach Request count : 1 - TLLI cache size : 1 - TLLI-Cache: 1 - TLLI 8000dead -> 78dead00, IMSI 12131415161718, AGE 0 -PROCESSING ATTACH ACCEPT from 0x05060708:32000 -00 00 10 02 00 78 de ad 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 f8 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 78 de ad 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 f8 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 f8 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 de ad 01 0c 0a 29 - -result (ATTACH ACCEPT) = 0 - -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): 2 - P-TMSI patched (SGSN): 1 - Attach Request count : 1 - Attach Accept count : 1 - TLLI cache size : 1 - TLLI-Cache: 1 - TLLI 8000dead/c0dead01 -> 78dead00/efe2b700, IMSI 12131415161718, AGE 0 -PROCESSING ATTACH COMPLETE from 0x01020304:1111 -00 00 10 02 01 c0 de ad 01 00 00 04 08 88 11 22 33 40 50 60 12 34 00 80 0e 00 08 01 c0 0d 08 03 55 1c ea - -CALLBACK, event 0, msg length 31, bvci 0x1002 -00 00 10 02 01 c0 de ad 01 00 00 04 08 88 11 22 33 40 50 60 12 34 00 80 0e 00 08 01 c0 0d 08 03 55 1c ea - -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 0d 08 03 55 1c ea - -result (ATTACH COMPLETE) = 0 - -Peers: - NSEI 4096, BVCI 4098, not blocked, RAI 112-332-16464-96 - RAID patched (BSS ): 5 - RAID patched (SGSN): 1 - TLLI patched (BSS ): 3 - TLLI patched (SGSN): 2 - P-TMSI patched (SGSN): 1 - Attach Request count : 1 - Attach Accept count : 1 - Attach Completed count : 1 - TLLI cache size : 1 - TLLI-Cache: 1 - TLLI 8000dead/c0dead01 -> 78dead00/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 f8 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 f8 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 de ad 01 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 f8 00 81 00 0e 88 41 c0 09 08 21 04 ba 3d - -result (GMM INFO) = 0 - -Peers: - NSEI 4096, BVCI 4098, not blocked, RAI 112-332-16464-96 - RAID patched (BSS ): 5 - RAID patched (SGSN): 1 - TLLI patched (BSS ): 3 - TLLI patched (SGSN): 3 - P-TMSI patched (SGSN): 1 - Attach Request count : 1 - Attach Accept count : 1 - Attach Completed count : 1 - TLLI cache size : 1 - TLLI-Cache: 1 - TLLI c0dead01 -> efe2b700, IMSI 12131415161718, AGE 0 -PROCESSING XID (UL) from 0x01020304:1111 -00 00 10 02 01 c0 de ad 01 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 de ad 01 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)) = 0 - -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 f8 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 f8 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 de ad 01 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 f8 00 81 00 0e 8c 41 fb 30 84 10 61 b6 64 e4 a9 1a 9e - -result (XID (DL)) = 0 - -PROCESSING LL11 DNS QUERY (UL) from 0x01020304:1111 -00 00 10 02 01 c0 de ad 01 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 de ad 01 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)) = 0 - -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 f8 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 f8 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 de ad 01 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 f8 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)) = 0 - -Peers: - NSEI 4096, BVCI 4098, not blocked, RAI 112-332-16464-96 - RAID patched (BSS ): 7 - RAID patched (SGSN): 1 - TLLI patched (BSS ): 5 - TLLI patched (SGSN): 5 - P-TMSI patched (SGSN): 1 - Attach Request count : 1 - Attach Accept count : 1 - Attach Completed count : 1 - TLLI cache size : 1 - TLLI-Cache: 1 - TLLI c0dead01 -> efe2b700, IMSI 12131415161718, AGE 0 -PROCESSING LLC_DISCARDED from 0x01020304:1111 -00 00 00 00 2c 1f 84 c0 de ad 01 0f 81 01 04 82 10 02 25 83 00 00 0c - -CALLBACK, event 0, msg length 19, bvci 0x0000 -00 00 00 00 2c 1f 84 c0 de ad 01 0f 81 01 04 82 10 02 25 83 00 00 0c - -NS UNITDATA MESSAGE to SGSN, BVCI 0x0000, msg length 19 (gprs_ns_sendmsg) -MESSAGE to SGSN at 0x05060708:32000, msg length 23 -00 00 00 00 2c 1f 84 ef e2 b7 00 0f 81 01 04 82 10 02 25 83 00 00 0c - -result (LLC_DISCARDED) = 0 - -Peers: - NSEI 4096, BVCI 4098, not blocked, RAI 112-332-16464-96 - RAID patched (BSS ): 7 - RAID patched (SGSN): 1 - TLLI patched (BSS ): 6 - TLLI patched (SGSN): 5 - P-TMSI patched (SGSN): 1 - Attach Request count : 1 - Attach Accept count : 1 - Attach Completed count : 1 - TLLI cache size : 1 - TLLI-Cache: 1 - TLLI c0dead01 -> efe2b700, IMSI 12131415161718, AGE 0 -PROCESSING LLC_DISCARDED from 0x05060708:32000 -00 00 00 00 2c 1f 84 ef e2 b7 00 0f 81 01 04 82 10 02 25 83 00 00 0c - -CALLBACK, event 0, msg length 19, bvci 0x0000 -00 00 00 00 2c 1f 84 ef e2 b7 00 0f 81 01 04 82 10 02 25 83 00 00 0c - -NS UNITDATA MESSAGE to SGSN, BVCI 0x0000, msg length 25 (gprs_ns_sendmsg) -MESSAGE to SGSN at 0x05060708:32000, msg length 29 -00 00 00 00 41 07 81 27 15 93 2c 1f 84 ef e2 b7 00 0f 81 01 04 82 10 02 25 83 00 00 0c - -result (LLC_DISCARDED) = 0 - -Peers: - NSEI 4096, BVCI 4098, not blocked, RAI 112-332-16464-96 - RAID patched (BSS ): 7 - RAID patched (SGSN): 1 - TLLI patched (BSS ): 6 - TLLI patched (SGSN): 6 - P-TMSI patched (SGSN): 1 - Attach Request count : 1 - Attach Accept count : 1 - Attach Completed count : 1 - TLLI cache size : 1 - TLLI-Cache: 1 - TLLI c0dead01 -> efe2b700, IMSI 12131415161718, AGE 0 -PROCESSING BVC_SUSPEND from 0x01020304:1111 -00 00 00 00 0b 1f 84 c0 de ad 01 1b 86 11 22 33 40 50 60 - -CALLBACK, event 0, msg length 15, bvci 0x0000 -00 00 00 00 0b 1f 84 c0 de ad 01 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 ef e2 b7 00 1b 86 21 63 54 40 50 60 - -result (BVC_SUSPEND) = 0 - -Peers: - NSEI 4096, BVCI 4098, not blocked, RAI 112-332-16464-96 - RAID patched (BSS ): 8 - RAID patched (SGSN): 1 - TLLI patched (BSS ): 7 - TLLI patched (SGSN): 6 - P-TMSI patched (SGSN): 1 - Attach Request count : 1 - Attach Accept count : 1 - Attach Completed count : 1 - TLLI cache size : 1 - TLLI-Cache: 1 - TLLI c0dead01 -> efe2b700, IMSI 12131415161718, AGE 0 -PROCESSING BVC_SUSPEND_ACK from 0x05060708:32000 -00 00 00 00 0c 1f 84 ef e2 b7 00 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 ef e2 b7 00 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 c0 de ad 01 1b 86 11 22 33 40 50 60 1d 81 01 - -result (BVC_SUSPEND_ACK) = 0 - -Peers: - NSEI 4096, BVCI 4098, not blocked, RAI 112-332-16464-96 - RAID patched (BSS ): 8 - RAID patched (SGSN): 2 - TLLI patched (BSS ): 7 - TLLI patched (SGSN): 7 - P-TMSI patched (SGSN): 1 - Attach Request count : 1 - Attach Accept count : 1 - Attach Completed count : 1 - TLLI cache size : 1 - TLLI-Cache: 1 - TLLI c0dead01 -> efe2b700, IMSI 12131415161718, AGE 0 -PROCESSING LLC_DISCARDED from 0x01020304:1111 -00 00 00 00 2c 1f 84 c0 de ad 01 0f 81 01 04 82 ee e1 25 83 00 00 0c - -CALLBACK, event 0, msg length 19, bvci 0x0000 -00 00 00 00 2c 1f 84 c0 de ad 01 0f 81 01 04 82 ee e1 25 83 00 00 0c - -NS UNITDATA MESSAGE to SGSN, BVCI 0x0000, msg length 19 (gprs_ns_sendmsg) -MESSAGE to SGSN at 0x05060708:32000, msg length 23 -00 00 00 00 2c 1f 84 ef e2 b7 00 0f 81 01 04 82 ee e1 25 83 00 00 0c - -result (LLC_DISCARDED) = 0 - -Gbproxy global: - BSSGP protocol error (SGSN): 1 -PROCESSING BVC_SUSPEND_ACK from 0x05060708:32000 -00 00 00 00 0c 1f 84 ef e2 b7 00 1b 86 00 f1 99 00 63 60 1d 81 01 - -CALLBACK, event 0, msg length 18, bvci 0x0000 -00 00 00 00 0c 1f 84 ef e2 b7 00 1b 86 00 f1 99 00 63 60 1d 81 01 - -NS UNITDATA MESSAGE to SGSN, BVCI 0x0000, msg length 24 (gprs_ns_sendmsg) -MESSAGE to SGSN at 0x05060708:32000, msg length 28 -00 00 00 00 41 07 81 21 15 92 0c 1f 84 ef e2 b7 00 1b 86 00 f1 99 00 63 60 1d 81 01 - -result (BVC_SUSPEND_ACK) = 0 - -Gbproxy global: - Invalid Routing Area Identifier : 1 - BSSGP protocol error (SGSN): 1 - Patch error: no peer : 1 -PROCESSING BVC_SUSPEND_ACK from 0x05060708:32000 -00 00 00 00 0c 1f 84 ef e2 b7 00 1b 86 99 69 54 40 50 60 1d 81 01 - -CALLBACK, event 0, msg length 18, bvci 0x0000 -00 00 00 00 0c 1f 84 ef e2 b7 00 1b 86 99 69 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 c0 de ad 01 1b 86 11 22 33 40 50 60 1d 81 01 - -result (BVC_SUSPEND_ACK) = 0 - -Gbproxy global: - Invalid Routing Area Identifier : 1 - BSSGP protocol error (SGSN): 1 - Patch error: no peer : 1 -PROCESSING DETACH REQ from 0x01020304:1111 -00 00 10 02 01 c0 de ad 01 00 00 04 08 88 11 22 33 40 50 60 12 34 00 80 0e 00 15 01 c0 11 08 05 01 18 05 f4 ef e2 b7 00 19 03 b9 97 cb 6d b1 de - -CALLBACK, event 0, msg length 44, bvci 0x1002 -00 00 10 02 01 c0 de ad 01 00 00 04 08 88 11 22 33 40 50 60 12 34 00 80 0e 00 15 01 c0 11 08 05 01 18 05 f4 ef e2 b7 00 19 03 b9 97 cb 6d b1 de - -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 11 08 05 01 18 05 f4 ef e2 b7 00 19 03 b9 97 cb 6d b1 de - -result (DETACH REQ) = 0 - -Peers: - NSEI 4096, BVCI 4098, not blocked, RAI 112-332-16464-96 - RAID patched (BSS ): 9 - RAID patched (SGSN): 3 - TLLI patched (BSS ): 9 - TLLI patched (SGSN): 8 - P-TMSI patched (SGSN): 1 - Attach Request count : 1 - Attach Accept count : 1 - Attach Completed count : 1 - Detach Request count : 1 - TLLI cache size : 1 - TLLI-Cache: 1 - TLLI c0dead01 -> 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 f8 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 f8 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 de ad 01 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 f8 00 81 00 0e 89 41 c0 0d 08 06 00 aa ab ee - -result (DETACH ACC) = 0 - -Peers: - NSEI 4096, BVCI 4098, not blocked, RAI 112-332-16464-96 - RAID patched (BSS ): 9 - RAID patched (SGSN): 3 - TLLI patched (BSS ): 9 - TLLI patched (SGSN): 9 - P-TMSI patched (SGSN): 1 - Attach Request count : 1 - Attach Accept count : 1 - Attach Completed count : 1 - Detach Request count : 1 - Detach Accept count : 1 - TLLI-Cache: 0 -PROCESSING RA UPD REQ from 0x01020304:1111 -00 00 10 02 01 80 00 de ad 00 00 04 08 88 00 f1 99 00 63 60 70 80 00 80 0e 00 3e 01 c0 15 08 08 10 11 22 33 40 50 60 1d 19 13 42 33 57 2b f7 c8 48 02 13 48 50 c8 48 02 14 48 50 c8 48 02 17 49 10 c8 48 02 00 19 8b b2 92 17 16 27 07 04 31 02 e5 e0 32 02 20 00 96 3e 97 - -CALLBACK, event 0, msg length 85, bvci 0x1002 -00 00 10 02 01 80 00 de ad 00 00 04 08 88 00 f1 99 00 63 60 70 80 00 80 0e 00 3e 01 c0 15 08 08 10 11 22 33 40 50 60 1d 19 13 42 33 57 2b f7 c8 48 02 13 48 50 c8 48 02 14 48 50 c8 48 02 17 49 10 c8 48 02 00 19 8b b2 92 17 16 27 07 04 31 02 e5 e0 32 02 20 00 96 3e 97 - -NS UNITDATA MESSAGE to BSS, BVCI 0x1002, msg length 24 (gprs_ns_sendmsg) -MESSAGE to BSS at 0x01020304:1111, msg length 28 -00 00 10 02 00 80 00 de ad 00 50 20 16 82 02 58 0e 00 09 41 c4 01 08 15 01 b7 f8 36 - -result (RA UPD REQ) = 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 19 08 16 08 11 12 13 14 15 16 17 f8 9f c7 7a - -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 19 08 16 08 11 12 13 14 15 16 17 f8 9f c7 7a - -NS UNITDATA MESSAGE to SGSN, BVCI 0x1002, msg length 85 (gprs_ns_sendmsg) -MESSAGE to SGSN at 0x05060708:32000, msg length 89 -00 00 10 02 01 78 de ad 02 00 00 04 08 88 21 63 54 00 63 60 70 80 00 80 0e 00 3e 01 c0 15 08 08 10 11 22 33 40 50 60 1d 19 13 42 33 57 2b f7 c8 48 02 13 48 50 c8 48 02 14 48 50 c8 48 02 17 49 10 c8 48 02 00 19 8b b2 92 17 16 27 07 04 31 02 e5 e0 32 02 20 00 96 3e 97 - -result (IDENT RESPONSE) = 0 - -Peers: - NSEI 4096, BVCI 4098, not blocked, RAI 112-332-16464-96 - RAID patched (BSS ): 10 - RAID patched (SGSN): 3 - TLLI patched (BSS ): 10 - TLLI patched (SGSN): 9 - P-TMSI patched (SGSN): 1 - Attach Request count : 1 - Attach Accept count : 1 - Attach Completed count : 1 - RoutingArea Update Request count: 1 - Detach Request count : 1 - Detach Accept count : 1 - TLLI cache size : 1 - TLLI-Cache: 1 - TLLI 8000dead -> 78dead02, IMSI 12131415161718, AGE 0 -PROCESSING RA UDP ACC from 0x05060708:32000 -00 00 10 02 00 78 de ad 02 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 f8 00 81 00 0e 9d 41 c0 11 08 09 00 49 21 63 54 40 50 60 19 54 ab b3 18 05 f4 ef e2 b7 00 17 16 36 98 77 - -CALLBACK, event 0, msg length 87, bvci 0x1002 -00 00 10 02 00 78 de ad 02 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 f8 00 81 00 0e 9d 41 c0 11 08 09 00 49 21 63 54 40 50 60 19 54 ab b3 18 05 f4 ef e2 b7 00 17 16 36 98 77 - -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 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 f8 00 81 00 0e 9d 41 c0 11 08 09 00 49 11 22 33 40 50 60 19 54 ab b3 18 05 f4 c0 de ad 03 17 16 6e 58 26 - -result (RA UDP ACC) = 0 - -Peers: - NSEI 4096, BVCI 4098, not blocked, RAI 112-332-16464-96 - RAID patched (BSS ): 10 - RAID patched (SGSN): 4 - TLLI patched (BSS ): 10 - TLLI patched (SGSN): 10 - P-TMSI patched (SGSN): 2 - Attach Request count : 1 - Attach Accept count : 1 - Attach Completed count : 1 - RoutingArea Update Request count: 1 - RoutingArea Update Accept count : 1 - Detach Request count : 1 - Detach Accept count : 1 - TLLI cache size : 1 - TLLI-Cache: 1 - TLLI 8000dead/c0dead03 -> 78dead02/efe2b700, IMSI 12131415161718, AGE 0 -PROCESSING DETACH REQ from 0x01020304:1111 -00 00 10 02 01 c0 de ad 01 00 00 04 08 88 11 22 33 40 50 60 12 34 00 80 0e 00 15 01 c0 1d 08 05 01 18 05 f4 ef e2 b7 00 19 03 b9 97 cb aa cc a3 - -CALLBACK, event 0, msg length 44, bvci 0x1002 -00 00 10 02 01 c0 de ad 01 00 00 04 08 88 11 22 33 40 50 60 12 34 00 80 0e 00 15 01 c0 1d 08 05 01 18 05 f4 ef e2 b7 00 19 03 b9 97 cb aa cc a3 - -NS UNITDATA MESSAGE to BSS, BVCI 0x1002, msg length 24 (gprs_ns_sendmsg) -MESSAGE to BSS at 0x01020304:1111, msg length 28 -00 00 10 02 00 c0 de ad 01 00 50 20 16 82 02 58 0e 00 09 41 c4 01 08 06 00 11 f5 c0 - -result (DETACH REQ) = 0 - -Peers: - NSEI 4096, BVCI 4098, not blocked, RAI 112-332-16464-96 - RAID patched (BSS ): 10 - RAID patched (SGSN): 4 - TLLI patched (BSS ): 10 - TLLI patched (SGSN): 10 - P-TMSI patched (SGSN): 2 - Attach Request count : 1 - Attach Accept count : 1 - Attach Completed count : 1 - RoutingArea Update Request count: 1 - RoutingArea Update Accept count : 1 - Detach Request count : 2 - Detach Accept count : 1 - TLLI cache size : 1 - TLLI-Cache: 1 - TLLI 8000dead/c0dead03 -> 78dead02/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 f8 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 f8 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 c0 de ad 03 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 f8 00 81 00 0e 89 41 c0 15 08 06 00 f7 35 f0 - -result (DETACH ACC) = 0 - -Peers: - NSEI 4096, BVCI 4098, not blocked, RAI 112-332-16464-96 - RAID patched (BSS ): 10 - RAID patched (SGSN): 4 - TLLI patched (BSS ): 10 - TLLI patched (SGSN): 11 - P-TMSI patched (SGSN): 2 - Attach Request count : 1 - Attach Accept count : 1 - Attach Completed count : 1 - RoutingArea Update Request count: 1 - RoutingArea Update Accept count : 1 - Detach Request count : 2 - Detach Accept count : 2 - TLLI-Cache: 0 -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 21 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 44 b6 bb - -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 21 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 44 b6 bb - -NS UNITDATA MESSAGE to BSS, BVCI 0x1002, msg length 24 (gprs_ns_sendmsg) -MESSAGE to BSS at 0x01020304:1111, msg length 28 -00 00 10 02 00 80 00 de ad 00 50 20 16 82 02 58 0e 00 09 41 c4 01 08 15 01 b7 f8 36 - -result (ATTACH REQUEST) = 0 - -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 25 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 1d aa 57 - -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 25 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 1d aa 57 - -NS UNITDATA MESSAGE to BSS, BVCI 0x1002, msg length 24 (gprs_ns_sendmsg) -MESSAGE to BSS at 0x01020304:1111, msg length 28 -00 00 10 02 00 80 00 de ad 00 50 20 16 82 02 58 0e 00 09 41 c4 05 08 15 01 8f 47 9e - -result (ATTACH REQUEST) = 0 - -PROCESSING DETACH REQ 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 15 01 c0 29 08 05 01 18 05 f4 ef e2 b7 00 19 03 b9 97 cb d9 1d ef - -CALLBACK, event 0, msg length 44, 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 15 01 c0 29 08 05 01 18 05 f4 ef e2 b7 00 19 03 b9 97 cb d9 1d ef - -NS UNITDATA MESSAGE to BSS, BVCI 0x1002, msg length 24 (gprs_ns_sendmsg) -MESSAGE to BSS at 0x01020304:1111, msg length 28 -00 00 10 02 00 80 00 de ad 00 50 20 16 82 02 58 0e 00 09 41 c4 09 08 06 00 da 80 ca - -result (DETACH REQ) = 0 - -Peers: - NSEI 4096, BVCI 4098, not blocked, RAI 112-332-16464-96 - RAID patched (BSS ): 10 - RAID patched (SGSN): 4 - TLLI patched (BSS ): 10 - TLLI patched (SGSN): 11 - P-TMSI patched (SGSN): 2 - Attach Request count : 3 - Attach Accept count : 1 - Attach Completed count : 1 - RoutingArea Update Request count: 1 - RoutingArea Update Accept count : 1 - Detach Request count : 3 - Detach Accept count : 2 - TLLI-Cache: 0 -PROCESSING DETACH REQ (unknown TLLI) from 0x01020304:1111 -00 00 10 02 01 80 00 be ef 00 00 04 08 88 11 22 33 40 50 60 12 34 00 80 0e 00 15 01 c0 2d 08 05 01 18 05 f4 ef e2 b7 00 19 03 b9 97 cb 0d 30 0d - -CALLBACK, event 0, msg length 44, bvci 0x1002 -00 00 10 02 01 80 00 be ef 00 00 04 08 88 11 22 33 40 50 60 12 34 00 80 0e 00 15 01 c0 2d 08 05 01 18 05 f4 ef e2 b7 00 19 03 b9 97 cb 0d 30 0d - -NS UNITDATA MESSAGE to BSS, BVCI 0x1002, msg length 24 (gprs_ns_sendmsg) -MESSAGE to BSS at 0x01020304:1111, msg length 28 -00 00 10 02 00 80 00 be ef 00 50 20 16 82 02 58 0e 00 09 41 c4 01 08 06 00 11 f5 c0 - -result (DETACH REQ (unknown TLLI)) = 0 - -Peers: - NSEI 4096, BVCI 4098, not blocked, RAI 112-332-16464-96 - RAID patched (BSS ): 10 - RAID patched (SGSN): 4 - TLLI patched (BSS ): 10 - TLLI patched (SGSN): 11 - P-TMSI patched (SGSN): 2 - Attach Request count : 3 - Attach Accept count : 1 - Attach Completed count : 1 - RoutingArea Update Request count: 1 - RoutingArea Update Accept count : 1 - Detach Request count : 4 - Detach Accept count : 2 - TLLI-Cache: 0 -PROCESSING RA UPD REQ from 0x01020304:1111 -00 00 10 02 01 80 00 de ad 00 00 04 08 88 00 f1 99 00 63 60 70 80 00 80 0e 00 3e 01 c0 31 08 08 10 11 22 33 40 50 60 1d 19 13 42 33 57 2b f7 c8 48 02 13 48 50 c8 48 02 14 48 50 c8 48 02 17 49 10 c8 48 02 00 19 8b b2 92 17 16 27 07 04 31 02 e5 e0 32 02 20 00 d8 cf d8 - -CALLBACK, event 0, msg length 85, bvci 0x1002 -00 00 10 02 01 80 00 de ad 00 00 04 08 88 00 f1 99 00 63 60 70 80 00 80 0e 00 3e 01 c0 31 08 08 10 11 22 33 40 50 60 1d 19 13 42 33 57 2b f7 c8 48 02 13 48 50 c8 48 02 14 48 50 c8 48 02 17 49 10 c8 48 02 00 19 8b b2 92 17 16 27 07 04 31 02 e5 e0 32 02 20 00 d8 cf d8 - -NS UNITDATA MESSAGE to BSS, BVCI 0x1002, msg length 24 (gprs_ns_sendmsg) -MESSAGE to BSS at 0x01020304:1111, msg length 28 -00 00 10 02 00 80 00 de ad 00 50 20 16 82 02 58 0e 00 09 41 c4 01 08 15 01 b7 f8 36 - -result (RA UPD REQ) = 0 - -PROCESSING RA UPD REQ from 0x01020304:1111 -00 00 10 02 01 80 00 de ad 00 00 04 08 88 00 f1 99 00 63 60 70 80 00 80 0e 00 3e 01 c0 35 08 08 10 11 22 33 40 50 60 1d 19 13 42 33 57 2b f7 c8 48 02 13 48 50 c8 48 02 14 48 50 c8 48 02 17 49 10 c8 48 02 00 19 8b b2 92 17 16 27 07 04 31 02 e5 e0 32 02 20 00 ac 9c 37 - -CALLBACK, event 0, msg length 85, bvci 0x1002 -00 00 10 02 01 80 00 de ad 00 00 04 08 88 00 f1 99 00 63 60 70 80 00 80 0e 00 3e 01 c0 35 08 08 10 11 22 33 40 50 60 1d 19 13 42 33 57 2b f7 c8 48 02 13 48 50 c8 48 02 14 48 50 c8 48 02 17 49 10 c8 48 02 00 19 8b b2 92 17 16 27 07 04 31 02 e5 e0 32 02 20 00 ac 9c 37 - -NS UNITDATA MESSAGE to BSS, BVCI 0x1002, msg length 24 (gprs_ns_sendmsg) -MESSAGE to BSS at 0x01020304:1111, msg length 28 -00 00 10 02 00 80 00 de ad 00 50 20 16 82 02 58 0e 00 09 41 c4 05 08 15 01 8f 47 9e - -result (RA UPD REQ) = 0 - -PROCESSING DETACH REQ 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 15 01 c0 39 08 05 01 18 05 f4 ef e2 b7 00 19 03 b9 97 cb 44 b6 8a - -CALLBACK, event 0, msg length 44, 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 15 01 c0 39 08 05 01 18 05 f4 ef e2 b7 00 19 03 b9 97 cb 44 b6 8a - -NS UNITDATA MESSAGE to BSS, BVCI 0x1002, msg length 24 (gprs_ns_sendmsg) -MESSAGE to BSS at 0x01020304:1111, msg length 28 -00 00 10 02 00 80 00 de ad 00 50 20 16 82 02 58 0e 00 09 41 c4 09 08 06 00 da 80 ca - -result (DETACH REQ) = 0 - -Peers: - NSEI 4096, BVCI 4098, not blocked, RAI 112-332-16464-96 - RAID patched (BSS ): 10 - RAID patched (SGSN): 4 - TLLI patched (BSS ): 10 - TLLI patched (SGSN): 11 - P-TMSI patched (SGSN): 2 - Attach Request count : 3 - Attach Accept count : 1 - Attach Completed count : 1 - RoutingArea Update Request count: 3 - RoutingArea Update Accept count : 1 - Detach Request count : 5 - Detach Accept count : 2 - TLLI-Cache: 0 -Gbproxy global: - Invalid Routing Area Identifier : 1 - BSSGP protocol error (SGSN): 1 - Patch error: no peer : 1 -=== test_gbproxy_secondary_sgsn === ---- Initialise SGSN 1 --- - -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) = 0 - -PROCESSING ALIVE_ACK from 0x05060708:32000 -0b - -MESSAGE to SGSN at 0x05060708:32000, msg length 1 -06 - -result (ALIVE_ACK) = 0 - -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) = 0 - ---- Initialise SGSN 2 --- - -MESSAGE to SGSN 2 at 0x15161718:32001, msg length 12 -02 00 81 01 01 82 01 03 04 82 01 02 - -PROCESSING RESET_ACK from 0x15161718:32001 -03 01 82 01 03 04 82 01 02 - -MESSAGE to SGSN 2 at 0x15161718:32001, msg length 1 -0a - -result (RESET_ACK) = 0 - -PROCESSING ALIVE_ACK from 0x15161718:32001 -0b - -MESSAGE to SGSN 2 at 0x15161718:32001, msg length 1 -06 - -result (ALIVE_ACK) = 0 - -PROCESSING UNBLOCK_ACK from 0x15161718:32001 -07 - -==> got signal NS_UNBLOCK, NS-VC 0x0103/21.22.23.24:32001 - -result (UNBLOCK_ACK) = 0 - -PROCESSING ALIVE from 0x15161718:32001 -0a - -MESSAGE to SGSN 2 at 0x15161718:32001, msg length 1 -0b - -result (ALIVE) = 0 - ---- 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) = 0 - -PROCESSING ALIVE from 0x01020304:1111 -0a - -MESSAGE to BSS at 0x01020304:1111, msg length 1 -0b - -result (ALIVE) = 0 - -PROCESSING UNBLOCK from 0x01020304:1111 -06 - -MESSAGE to BSS at 0x01020304:1111, msg length 1 -07 - -==> got signal NS_UNBLOCK, NS-VC 0x1001/1.2.3.4:1111 - -result (UNBLOCK) = 0 - -PROCESSING ALIVE_ACK from 0x01020304:1111 -0b - -result (ALIVE_ACK) = 0 - -Setup BSSGP: remote 0x01020304:1111, BVCI 0x0000(0) - -PROCESSING BVC_RESET from 0x01020304:1111 -00 00 00 00 22 04 82 00 00 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 00 00 07 81 08 08 88 11 22 33 40 50 60 10 00 - -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 00 00 - -result (BVC_RESET) = 0 - -PROCESSING BVC_RESET_ACK from 0x05060708:32000 -00 00 00 00 23 04 82 00 00 - -CALLBACK, event 0, msg length 5, bvci 0x0000 -00 00 00 00 23 04 82 00 00 - -result (BVC_RESET_ACK) = -2 - -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 2, BVCI 0x0000, msg length 18 (gprs_ns_sendmsg) -MESSAGE to SGSN 2 at 0x15161718:32001, 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 - -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) = 0 - -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) = 0 - -PROCESSING BVC_RESET_ACK from 0x15161718:32001 -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 - -result (BVC_RESET_ACK) = 0 - -Current NS-VCIs: - VCI 0x1001, NSEI 0x1000, peer 0x01020304:1111 - Packets at NS Level ( In): 6 - Packets at NS Level (Out): 6 - Bytes at NS Level ( In): 59 - Bytes at NS Level (Out): 30 - VCI 0x0103, NSEI 0x0102, peer 0x15161718:32001 - Packets at NS Level ( In): 5 - Packets at NS Level (Out): 5 - Bytes at NS Level ( In): 21 - Bytes at NS Level (Out): 37 - NS-VC Block count : 1 - VCI 0x0101, NSEI 0x0100, peer 0x05060708:32000 - Packets at NS Level ( In): 6 - Packets at NS Level (Out): 5 - Bytes at NS Level ( In): 30 - Bytes at NS Level (Out): 37 - NS-VC Block count : 1 - -Gbproxy global: - Invalid BVC Identifier : 1 - Patch error: no peer : 1 -Peers: - NSEI 4096, BVCI 4098, not blocked, RAI 112-332-16464-96 - RAID patched (BSS ): 1 - TLLI-Cache: 0 ---- Flow control --- - -PROCESSING FLOW_CONTROL_BVC from 0x01020304:1111 -00 00 10 02 26 1e 81 01 05 82 01 dc 03 82 02 76 01 82 00 50 1c 82 02 58 06 82 00 03 - -CALLBACK, event 0, msg length 24, bvci 0x1002 -00 00 10 02 26 1e 81 01 05 82 01 dc 03 82 02 76 01 82 00 50 1c 82 02 58 06 82 00 03 - -NS UNITDATA MESSAGE to SGSN 2, BVCI 0x1002, msg length 24 (gprs_ns_sendmsg) -MESSAGE to SGSN 2 at 0x15161718:32001, msg length 28 -00 00 10 02 26 1e 81 01 05 82 01 dc 03 82 02 76 01 82 00 50 1c 82 02 58 06 82 00 03 - -NS UNITDATA MESSAGE to SGSN, BVCI 0x1002, msg length 24 (gprs_ns_sendmsg) -MESSAGE to SGSN at 0x05060708:32000, msg length 28 -00 00 10 02 26 1e 81 01 05 82 01 dc 03 82 02 76 01 82 00 50 1c 82 02 58 06 82 00 03 - -result (FLOW_CONTROL_BVC) = 0 - -PROCESSING FLOW_CONTROL_BVC_ACK from 0x05060708:32000 -00 00 10 02 27 1e 81 01 - -CALLBACK, event 0, msg length 4, bvci 0x1002 -00 00 10 02 27 1e 81 01 - -NS UNITDATA MESSAGE to BSS, BVCI 0x1002, msg length 4 (gprs_ns_sendmsg) -MESSAGE to BSS at 0x01020304:1111, msg length 8 -00 00 10 02 27 1e 81 01 - -result (FLOW_CONTROL_BVC_ACK) = 0 - -PROCESSING FLOW_CONTROL_BVC_ACK from 0x15161718:32001 -00 00 10 02 27 1e 81 01 - -CALLBACK, event 0, msg length 4, bvci 0x1002 -00 00 10 02 27 1e 81 01 - -result (FLOW_CONTROL_BVC_ACK) = 0 - ---- Establish GPRS connection (SGSN 1) --- - -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 BSS, BVCI 0x1002, msg length 24 (gprs_ns_sendmsg) -MESSAGE to BSS at 0x01020304:1111, msg length 28 -00 00 10 02 00 80 00 de ad 00 50 20 16 82 02 58 0e 00 09 41 c4 01 08 15 01 b7 f8 36 - -result (ATTACH REQUEST) = 0 - -Peers: - NSEI 4096, BVCI 4098, not blocked, RAI 112-332-16464-96 - RAID patched (BSS ): 1 - Attach Request count : 1 - TLLI cache size : 1 - TLLI-Cache: 1 - TLLI 8000dead -> 78dead00, IMSI (none), AGE 0, STORED 1, IMSI acquisition in progress, SGSN NSEI 65535 -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 f8 07 e1 ae - -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 f8 07 e1 ae - -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 78 de ad 00 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 (IDENT RESPONSE) = 0 - -Peers: - NSEI 4096, BVCI 4098, not blocked, RAI 112-332-16464-96 - RAID patched (BSS ): 2 - TLLI patched (BSS ): 1 - Attach Request count : 1 - TLLI cache size : 1 - TLLI-Cache: 1 - TLLI 8000dead -> 78dead00, IMSI 12131415161718, AGE 0, SGSN NSEI 256 -PROCESSING IDENT REQUEST from 0x05060708:32000 -00 00 10 02 00 78 de ad 00 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 78 de ad 00 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) = 0 - -Peers: - NSEI 4096, BVCI 4098, not blocked, RAI 112-332-16464-96 - RAID patched (BSS ): 2 - TLLI patched (BSS ): 1 - TLLI patched (SGSN): 1 - Attach Request count : 1 - TLLI cache size : 1 - TLLI-Cache: 1 - TLLI 8000dead -> 78dead00, IMSI 12131415161718, AGE 0, SGSN NSEI 256 -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 09 08 16 08 11 12 13 14 15 16 17 f8 10 f0 45 - -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 09 08 16 08 11 12 13 14 15 16 17 f8 10 f0 45 - -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 78 de ad 00 00 00 04 08 88 21 63 54 40 50 60 12 34 00 80 0e 00 11 01 c0 09 08 16 08 11 12 13 14 15 16 17 f8 10 f0 45 - -result (IDENT RESPONSE) = 0 - -Peers: - NSEI 4096, BVCI 4098, not blocked, RAI 112-332-16464-96 - RAID patched (BSS ): 3 - TLLI patched (BSS ): 2 |