From f62d3da86bf1b89c20755c1e82a3674bc6387d63 Mon Sep 17 00:00:00 2001 From: Neels Hofmeyr Date: Mon, 4 Sep 2017 15:13:25 +0200 Subject: move include/openbsc to include/osmocom/sgsn Change-Id: I281ef585fffc2644682c8282224fb1c2da5ca795 --- configure.ac | 3 +- debian/copyright | 58 ++-- include/Makefile.am | 2 +- include/openbsc/Makefile.am | 28 -- include/openbsc/common.h | 6 - include/openbsc/crc24.h | 10 - include/openbsc/debug.h | 47 --- include/openbsc/gb_proxy.h | 288 ------------------ include/openbsc/gprs_gb_parse.h | 59 ---- include/openbsc/gprs_gmm.h | 35 --- include/openbsc/gprs_llc.h | 284 ----------------- include/openbsc/gprs_llc_xid.h | 57 ---- include/openbsc/gprs_sgsn.h | 484 ----------------------------- include/openbsc/gprs_sndcp.h | 79 ----- include/openbsc/gprs_sndcp_comp.h | 82 ----- include/openbsc/gprs_sndcp_dcomp.h | 53 ---- include/openbsc/gprs_sndcp_pcomp.h | 46 --- include/openbsc/gprs_sndcp_xid.h | 218 ------------- include/openbsc/gprs_subscriber.h | 31 -- include/openbsc/gprs_utils.h | 55 ---- include/openbsc/gsup_client.h | 63 ---- include/openbsc/gtphub.h | 523 -------------------------------- include/openbsc/oap_client.h | 82 ----- include/openbsc/rest_octets.h | 139 --------- include/openbsc/sgsn.h | 191 ------------ include/openbsc/signal.h | 52 ---- include/openbsc/slhc.h | 187 ------------ include/openbsc/v42bis.h | 147 --------- include/openbsc/v42bis_private.h | 126 -------- include/openbsc/vty.h | 9 - include/osmocom/Makefile.am | 3 + include/osmocom/sgsn/Makefile.am | 28 ++ include/osmocom/sgsn/common.h | 6 + include/osmocom/sgsn/crc24.h | 10 + include/osmocom/sgsn/debug.h | 47 +++ include/osmocom/sgsn/gb_proxy.h | 288 ++++++++++++++++++ include/osmocom/sgsn/gprs_gb_parse.h | 59 ++++ include/osmocom/sgsn/gprs_gmm.h | 35 +++ include/osmocom/sgsn/gprs_llc.h | 284 +++++++++++++++++ include/osmocom/sgsn/gprs_llc_xid.h | 57 ++++ include/osmocom/sgsn/gprs_sgsn.h | 484 +++++++++++++++++++++++++++++ include/osmocom/sgsn/gprs_sndcp.h | 79 +++++ include/osmocom/sgsn/gprs_sndcp_comp.h | 82 +++++ include/osmocom/sgsn/gprs_sndcp_dcomp.h | 53 ++++ include/osmocom/sgsn/gprs_sndcp_pcomp.h | 46 +++ include/osmocom/sgsn/gprs_sndcp_xid.h | 218 +++++++++++++ include/osmocom/sgsn/gprs_subscriber.h | 31 ++ include/osmocom/sgsn/gprs_utils.h | 55 ++++ include/osmocom/sgsn/gsup_client.h | 63 ++++ include/osmocom/sgsn/gtphub.h | 523 ++++++++++++++++++++++++++++++++ include/osmocom/sgsn/oap_client.h | 82 +++++ include/osmocom/sgsn/rest_octets.h | 139 +++++++++ include/osmocom/sgsn/sgsn.h | 191 ++++++++++++ include/osmocom/sgsn/signal.h | 52 ++++ include/osmocom/sgsn/slhc.h | 187 ++++++++++++ include/osmocom/sgsn/v42bis.h | 147 +++++++++ include/osmocom/sgsn/v42bis_private.h | 126 ++++++++ include/osmocom/sgsn/vty.h | 9 + src/gprs/crc24.c | 2 +- src/gprs/gb_proxy.c | 12 +- src/gprs/gb_proxy_main.c | 8 +- src/gprs/gb_proxy_patch.c | 8 +- src/gprs/gb_proxy_peer.c | 4 +- src/gprs/gb_proxy_tlli.c | 8 +- src/gprs/gb_proxy_vty.c | 8 +- src/gprs/gprs_gb_parse.c | 6 +- src/gprs/gprs_gmm.c | 18 +- src/gprs/gprs_llc.c | 18 +- src/gprs/gprs_llc_parse.c | 10 +- src/gprs/gprs_llc_vty.c | 6 +- src/gprs/gprs_llc_xid.c | 8 +- src/gprs/gprs_sgsn.c | 16 +- src/gprs/gprs_sndcp.c | 18 +- src/gprs/gprs_sndcp_comp.c | 10 +- src/gprs/gprs_sndcp_dcomp.c | 16 +- src/gprs/gprs_sndcp_pcomp.c | 14 +- src/gprs/gprs_sndcp_vty.c | 8 +- src/gprs/gprs_sndcp_xid.c | 8 +- src/gprs/gprs_subscriber.c | 14 +- src/gprs/gprs_utils.c | 2 +- src/gprs/gsup_client.c | 4 +- src/gprs/gtphub.c | 6 +- src/gprs/gtphub_ares.c | 6 +- src/gprs/gtphub_main.c | 6 +- src/gprs/gtphub_sock.c | 4 +- src/gprs/gtphub_vty.c | 6 +- src/gprs/oap_client.c | 4 +- src/gprs/sgsn_ares.c | 4 +- src/gprs/sgsn_auth.c | 10 +- src/gprs/sgsn_cdr.c | 10 +- src/gprs/sgsn_ctrl.c | 6 +- src/gprs/sgsn_libgtp.c | 16 +- src/gprs/sgsn_main.c | 12 +- src/gprs/sgsn_vty.c | 12 +- src/gprs/slhc.c | 4 +- src/gprs/v42bis.c | 6 +- src/libcommon/common_vty.c | 10 +- src/libcommon/debug.c | 4 +- src/libcommon/gsm_data.c | 6 +- src/libcommon/gsm_data_shared.c | 2 +- src/libcommon/gsm_subscriber_base.c | 6 +- src/libcommon/gsup_client.c | 4 +- src/libcommon/gsup_test_client.c | 4 +- src/libcommon/oap_client.c | 4 +- src/libcommon/socket.c | 4 +- tests/gbproxy/gbproxy_test.c | 10 +- tests/gprs/gprs_test.c | 6 +- tests/gtphub/gtphub_test.c | 4 +- tests/oap/oap_client_test.c | 4 +- tests/sgsn/sgsn_test.c | 16 +- tests/slhc/slhc_test.c | 4 +- tests/sndcp_xid/sndcp_xid_test.c | 4 +- tests/v42bis/v42bis_test.c | 6 +- tests/xid/xid_test.c | 4 +- 114 files changed, 3636 insertions(+), 3632 deletions(-) delete mode 100644 include/openbsc/Makefile.am delete mode 100644 include/openbsc/common.h delete mode 100644 include/openbsc/crc24.h delete mode 100644 include/openbsc/debug.h delete mode 100644 include/openbsc/gb_proxy.h delete mode 100644 include/openbsc/gprs_gb_parse.h delete mode 100644 include/openbsc/gprs_gmm.h delete mode 100644 include/openbsc/gprs_llc.h delete mode 100644 include/openbsc/gprs_llc_xid.h delete mode 100644 include/openbsc/gprs_sgsn.h delete mode 100644 include/openbsc/gprs_sndcp.h delete mode 100644 include/openbsc/gprs_sndcp_comp.h delete mode 100644 include/openbsc/gprs_sndcp_dcomp.h delete mode 100644 include/openbsc/gprs_sndcp_pcomp.h delete mode 100644 include/openbsc/gprs_sndcp_xid.h delete mode 100644 include/openbsc/gprs_subscriber.h delete mode 100644 include/openbsc/gprs_utils.h delete mode 100644 include/openbsc/gsup_client.h delete mode 100644 include/openbsc/gtphub.h delete mode 100644 include/openbsc/oap_client.h delete mode 100644 include/openbsc/rest_octets.h delete mode 100644 include/openbsc/sgsn.h delete mode 100644 include/openbsc/signal.h delete mode 100644 include/openbsc/slhc.h delete mode 100644 include/openbsc/v42bis.h delete mode 100644 include/openbsc/v42bis_private.h delete mode 100644 include/openbsc/vty.h create mode 100644 include/osmocom/Makefile.am create mode 100644 include/osmocom/sgsn/Makefile.am create mode 100644 include/osmocom/sgsn/common.h create mode 100644 include/osmocom/sgsn/crc24.h create mode 100644 include/osmocom/sgsn/debug.h create mode 100644 include/osmocom/sgsn/gb_proxy.h create mode 100644 include/osmocom/sgsn/gprs_gb_parse.h create mode 100644 include/osmocom/sgsn/gprs_gmm.h create mode 100644 include/osmocom/sgsn/gprs_llc.h create mode 100644 include/osmocom/sgsn/gprs_llc_xid.h create mode 100644 include/osmocom/sgsn/gprs_sgsn.h create mode 100644 include/osmocom/sgsn/gprs_sndcp.h create mode 100644 include/osmocom/sgsn/gprs_sndcp_comp.h create mode 100644 include/osmocom/sgsn/gprs_sndcp_dcomp.h create mode 100644 include/osmocom/sgsn/gprs_sndcp_pcomp.h create mode 100644 include/osmocom/sgsn/gprs_sndcp_xid.h create mode 100644 include/osmocom/sgsn/gprs_subscriber.h create mode 100644 include/osmocom/sgsn/gprs_utils.h create mode 100644 include/osmocom/sgsn/gsup_client.h create mode 100644 include/osmocom/sgsn/gtphub.h create mode 100644 include/osmocom/sgsn/oap_client.h create mode 100644 include/osmocom/sgsn/rest_octets.h create mode 100644 include/osmocom/sgsn/sgsn.h create mode 100644 include/osmocom/sgsn/signal.h create mode 100644 include/osmocom/sgsn/slhc.h create mode 100644 include/osmocom/sgsn/v42bis.h create mode 100644 include/osmocom/sgsn/v42bis_private.h create mode 100644 include/osmocom/sgsn/vty.h diff --git a/configure.ac b/configure.ac index f1167d6d1..5ded61fd3 100644 --- a/configure.ac +++ b/configure.ac @@ -179,8 +179,9 @@ AM_CONFIG_HEADER(bscconfig.h) AC_OUTPUT( osmo-sgsn.pc - include/openbsc/Makefile include/Makefile + include/osmocom/Makefile + include/osmocom/sgsn/Makefile src/Makefile src/gprs/Makefile tests/Makefile diff --git a/debian/copyright b/debian/copyright index b58117edc..1f7f6fde4 100644 --- a/debian/copyright +++ b/debian/copyright @@ -78,22 +78,22 @@ Files: .gitignore doc/osmo-nitb-data_structures.dot doc/paging.txt include/Makefile.am - include/openbsc/Makefile.am - include/openbsc/common.h - include/openbsc/crc24.h - include/openbsc/debug.h - include/openbsc/gb_proxy.h - include/openbsc/gprs_gb_parse.h - include/openbsc/gprs_gmm.h - include/openbsc/gprs_llc.h - include/openbsc/gprs_sgsn.h - include/openbsc/gprs_sndcp.h - include/openbsc/gprs_subscriber.h - include/openbsc/rest_octets.h - include/openbsc/sgsn.h - include/openbsc/vty.h + include/osmocom/sgsn/Makefile.am + include/osmocom/sgsn/common.h + include/osmocom/sgsn/crc24.h + include/osmocom/sgsn/debug.h + include/osmocom/sgsn/gb_proxy.h + include/osmocom/sgsn/gprs_gb_parse.h + include/osmocom/sgsn/gprs_gmm.h + include/osmocom/sgsn/gprs_llc.h + include/osmocom/sgsn/gprs_sgsn.h + include/osmocom/sgsn/gprs_sndcp.h + include/osmocom/sgsn/gprs_subscriber.h + include/osmocom/sgsn/rest_octets.h + include/osmocom/sgsn/sgsn.h + include/osmocom/sgsn/vty.h m4/README - openbsc.pc.in + osmo-sgsn.pc.in src/Makefile.am src/gprs/.gitignore src/gprs/Makefile.am @@ -130,17 +130,17 @@ Files: .gitignore Copyright: __NO_COPYRIGHT_NOR_LICENSE__ License: __NO_COPYRIGHT_NOR_LICENSE__ -Files: include/openbsc/a_reset.h - include/openbsc/gprs_llc_xid.h - include/openbsc/gprs_sndcp_comp.h - include/openbsc/gprs_sndcp_dcomp.h - include/openbsc/gprs_sndcp_pcomp.h - include/openbsc/gprs_sndcp_xid.h - include/openbsc/gprs_utils.h - include/openbsc/gsup_client.h - include/openbsc/gtphub.h - include/openbsc/oap_client.h - include/openbsc/signal.h +Files: include/osmocom/sgsn/a_reset.h + include/osmocom/sgsn/gprs_llc_xid.h + include/osmocom/sgsn/gprs_sndcp_comp.h + include/osmocom/sgsn/gprs_sndcp_dcomp.h + include/osmocom/sgsn/gprs_sndcp_pcomp.h + include/osmocom/sgsn/gprs_sndcp_xid.h + include/osmocom/sgsn/gprs_utils.h + include/osmocom/sgsn/gsup_client.h + include/osmocom/sgsn/gtphub.h + include/osmocom/sgsn/oap_client.h + include/osmocom/sgsn/signal.h src/gprs/crc24.c src/gprs/gb_proxy.c src/gprs/gb_proxy_main.c @@ -223,8 +223,8 @@ Copyright: 2013 Jacob Erlbeck 2015 sysmocom s.f.m.c. GmbH License: __NO_LICENSE__ -Files: include/openbsc/v42bis.h - include/openbsc/v42bis_private.h +Files: include/osmocom/sgsn/v42bis.h + include/osmocom/sgsn/v42bis_private.h Copyright: 2005-2011 Steve Underwood License: LGPL-2.1 This program is free software; you can redistribute it and/or modify @@ -367,7 +367,7 @@ License: LGPL-2.1 On Debian systems, the complete text of the GNU Lesser General Public License Version 2.1 can be found in `/usr/share/common-licenses/LGPL-2.1'. -Files: include/openbsc/slhc.h +Files: include/osmocom/sgsn/slhc.h Copyright: 1989 Regents of the University of California. License: __UNKNOWN__ Redistribution and use in source and binary forms are permitted diff --git a/include/Makefile.am b/include/Makefile.am index 677eec3aa..9d963a024 100644 --- a/include/Makefile.am +++ b/include/Makefile.am @@ -1,3 +1,3 @@ SUBDIRS = \ - openbsc \ + osmocom \ $(NULL) diff --git a/include/openbsc/Makefile.am b/include/openbsc/Makefile.am deleted file mode 100644 index 150212971..000000000 --- a/include/openbsc/Makefile.am +++ /dev/null @@ -1,28 +0,0 @@ -noinst_HEADERS = \ - common.h \ - crc24.h \ - debug.h \ - gb_proxy.h \ - gprs_gb_parse.h \ - gprs_gmm.h \ - gprs_llc.h \ - gprs_llc_xid.h \ - gprs_sgsn.h \ - gprs_sndcp_comp.h \ - gprs_sndcp_dcomp.h \ - gprs_sndcp.h \ - gprs_sndcp_pcomp.h \ - gprs_sndcp_xid.h \ - gprs_subscriber.h \ - gprs_utils.h \ - gsup_client.h \ - gtphub.h \ - oap_client.h \ - rest_octets.h \ - sgsn.h \ - signal.h \ - slhc.h \ - v42bis.h \ - v42bis_private.h \ - vty.h \ - $(NULL) diff --git a/include/openbsc/common.h b/include/openbsc/common.h deleted file mode 100644 index d91b3d39e..000000000 --- a/include/openbsc/common.h +++ /dev/null @@ -1,6 +0,0 @@ -#pragma once - -enum nsap_addr_enc { - NSAP_ADDR_ENC_X213, - NSAP_ADDR_ENC_V4RAW, -}; diff --git a/include/openbsc/crc24.h b/include/openbsc/crc24.h deleted file mode 100644 index 756638c03..000000000 --- a/include/openbsc/crc24.h +++ /dev/null @@ -1,10 +0,0 @@ -#ifndef _CRC24_H -#define _CRC24_H - -#include - -#define INIT_CRC24 0xffffff - -uint32_t crc24_calc(uint32_t fcs, uint8_t *cp, unsigned int len); - -#endif diff --git a/include/openbsc/debug.h b/include/openbsc/debug.h deleted file mode 100644 index 65e197d52..000000000 --- a/include/openbsc/debug.h +++ /dev/null @@ -1,47 +0,0 @@ -#pragma once - -#include -#include - -#define DEBUG -#include - -/* Debug Areas of the code */ -enum { - DRLL, - DCC, - DMM, - DRR, - DRSL, - DNM, - DMNCC, - DPAG, - DMEAS, - DSCCP, - DMSC, - DMGCP, - DHO, - DDB, - DREF, - DGPRS, - DNS, - DBSSGP, - DLLC, - DSNDCP, - DSLHC, - DNAT, - DCTRL, - DSMPP, - DFILTER, - DGTPHUB, - DRANAP, - DSUA, - DV42BIS, - DPCU, - DVLR, - DIUCS, - DSIGTRAN, - Debug_LastEntry, -}; - -extern const struct log_info log_info; diff --git a/include/openbsc/gb_proxy.h b/include/openbsc/gb_proxy.h deleted file mode 100644 index e10894fc3..000000000 --- a/include/openbsc/gb_proxy.h +++ /dev/null @@ -1,288 +0,0 @@ -#ifndef _GB_PROXY_H -#define _GB_PROXY_H - - -#include - -#include -#include - -#include -#include - -#define GBPROXY_INIT_VU_GEN_TX 256 - -struct rate_ctr_group; -struct gprs_gb_parse_context; -struct tlv_parsed; - -enum gbproxy_global_ctr { - GBPROX_GLOB_CTR_INV_BVCI, - GBPROX_GLOB_CTR_INV_LAI, - GBPROX_GLOB_CTR_INV_RAI, - GBPROX_GLOB_CTR_INV_NSEI, - GBPROX_GLOB_CTR_PROTO_ERR_BSS, - GBPROX_GLOB_CTR_PROTO_ERR_SGSN, - GBPROX_GLOB_CTR_NOT_SUPPORTED_BSS, - GBPROX_GLOB_CTR_NOT_SUPPORTED_SGSN, - GBPROX_GLOB_CTR_RESTART_RESET_SGSN, - GBPROX_GLOB_CTR_TX_ERR_SGSN, - GBPROX_GLOB_CTR_OTHER_ERR, - GBPROX_GLOB_CTR_PATCH_PEER_ERR, -}; - -enum gbproxy_peer_ctr { - GBPROX_PEER_CTR_BLOCKED, - GBPROX_PEER_CTR_UNBLOCKED, - GBPROX_PEER_CTR_DROPPED, - GBPROX_PEER_CTR_INV_NSEI, - GBPROX_PEER_CTR_TX_ERR, - GBPROX_PEER_CTR_RAID_PATCHED_BSS, - GBPROX_PEER_CTR_RAID_PATCHED_SGSN, - GBPROX_PEER_CTR_APN_PATCHED, - GBPROX_PEER_CTR_TLLI_PATCHED_BSS, - GBPROX_PEER_CTR_TLLI_PATCHED_SGSN, - GBPROX_PEER_CTR_PTMSI_PATCHED_BSS, - GBPROX_PEER_CTR_PTMSI_PATCHED_SGSN, - GBPROX_PEER_CTR_PATCH_CRYPT_ERR, - GBPROX_PEER_CTR_PATCH_ERR, - GBPROX_PEER_CTR_ATTACH_REQS, - GBPROX_PEER_CTR_ATTACH_REJS, - GBPROX_PEER_CTR_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, - GBPROX_KEEP_REATTACH, - GBPROX_KEEP_IDENTIFIED, - GBPROX_KEEP_ALWAYS, -}; - -enum gbproxy_match_id { - GBPROX_MATCH_PATCHING, - GBPROX_MATCH_ROUTING, - GBPROX_MATCH_LAST -}; - -struct gbproxy_match { - int enable; - char *re_str; - regex_t re_comp; -}; - -struct gbproxy_config { - /* parsed from config file */ - uint16_t nsip_sgsn_nsei; - - /* misc */ - struct gprs_ns_inst *nsi; - - /* Linked list of all Gb peers (except SGSN) */ - struct llist_head bts_peers; - - /* Counter */ - struct rate_ctr_group *ctrg; - - /* force mcc/mnc */ - int core_mnc; - int core_mcc; - uint8_t* core_apn; - size_t core_apn_size; - int tlli_max_age; - int tlli_max_len; - - /* Experimental config */ - int patch_ptmsi; - int acquire_imsi; - int route_to_sgsn2; - uint16_t nsip_sgsn2_nsei; - enum gbproxy_keep_mode keep_link_infos; - - /* IMSI checking/matching */ - struct gbproxy_match matches[GBPROX_MATCH_LAST]; -}; - -struct gbproxy_patch_state { - int local_mnc; - int local_mcc; - - /* List of TLLIs for which patching is enabled */ - struct llist_head logical_links; - int logical_link_count; -}; - -struct gbproxy_peer { - struct llist_head list; - - /* point back to the config */ - struct gbproxy_config *cfg; - - /* NSEI of the peer entity */ - uint16_t nsei; - - /* BVCI used for Point-to-Point to this peer */ - uint16_t bvci; - int blocked; - - /* Routeing Area that this peer is part of (raw 04.08 encoding) */ - uint8_t ra[6]; - - /* Counter */ - struct rate_ctr_group *ctrg; - - struct gbproxy_patch_state patch_state; -}; - -struct gbproxy_tlli_state { - uint32_t current; - uint32_t assigned; - int bss_validated; - int net_validated; - - uint32_t ptmsi; -}; - -struct gbproxy_link_info { - struct llist_head list; - - struct gbproxy_tlli_state tlli; - struct gbproxy_tlli_state sgsn_tlli; - uint32_t sgsn_nsei; - - time_t timestamp; - uint8_t *imsi; - size_t imsi_len; - - int imsi_acq_pending; - struct llist_head stored_msgs; - unsigned vu_gen_tx_bss; - - int is_deregistered; - - int is_matching[GBPROX_MATCH_LAST]; -}; - - -/* gb_proxy_vty .c */ - -int gbproxy_vty_init(void); -int gbproxy_parse_config(const char *config_file, struct gbproxy_config *cfg); - - -/* gb_proxy.c */ -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_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); - -/* 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); - -/* 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); - -#endif diff --git a/include/openbsc/gprs_gb_parse.h b/include/openbsc/gprs_gb_parse.h deleted file mode 100644 index 246839286..000000000 --- a/include/openbsc/gprs_gb_parse.h +++ /dev/null @@ -1,59 +0,0 @@ -#pragma once - -#include - -#include - -struct gprs_gb_parse_context { - /* Pointer to protocol specific parts */ - struct gsm48_hdr *g48_hdr; - struct bssgp_normal_hdr *bgp_hdr; - struct bssgp_ud_hdr *bud_hdr; - uint8_t *bssgp_data; - size_t bssgp_data_len; - uint8_t *llc; - size_t llc_len; - - /* Extracted information */ - struct gprs_llc_hdr_parsed llc_hdr_parsed; - struct tlv_parsed bssgp_tp; - int to_bss; - uint8_t *tlli_enc; - uint8_t *old_tlli_enc; - uint8_t *imsi; - size_t imsi_len; - uint8_t *apn_ie; - size_t apn_ie_len; - uint8_t *ptmsi_enc; - uint8_t *new_ptmsi_enc; - uint8_t *raid_enc; - uint8_t *old_raid_enc; - uint8_t *bssgp_raid_enc; - uint8_t *bssgp_ptmsi_enc; - - /* General info */ - const char *llc_msg_name; - int invalidate_tlli; - int await_reattach; - int need_decryption; - uint32_t tlli; - int pdu_type; - int old_raid_is_foreign; - int peer_nsei; -}; - -int gprs_gb_parse_dtap(uint8_t *data, size_t data_len, - struct gprs_gb_parse_context *parse_ctx); - -int gprs_gb_parse_llc(uint8_t *llc, size_t llc_len, - struct gprs_gb_parse_context *parse_ctx); - -int gprs_gb_parse_bssgp(uint8_t *bssgp, size_t bssgp_len, - struct gprs_gb_parse_context *parse_ctx); - -const char *gprs_gb_message_name(const struct gprs_gb_parse_context *parse_ctx, - const char *default_msg_name); - -void gprs_gb_log_parse_context(int log_level, - struct gprs_gb_parse_context *parse_ctx, - const char *default_msg_name); diff --git a/include/openbsc/gprs_gmm.h b/include/openbsc/gprs_gmm.h deleted file mode 100644 index c38e49f0d..000000000 --- a/include/openbsc/gprs_gmm.h +++ /dev/null @@ -1,35 +0,0 @@ -#ifndef _GPRS_GMM_H -#define _GPRS_GMM_H - -#include -#include - -#include - -int gsm48_tx_gsm_deact_pdp_req(struct sgsn_pdp_ctx *pdp, uint8_t sm_cause); -int gsm48_tx_gsm_act_pdp_rej(struct sgsn_mm_ctx *mm, uint8_t tid, - uint8_t cause, uint8_t pco_len, uint8_t *pco_v); -int gsm48_tx_gsm_act_pdp_acc(struct sgsn_pdp_ctx *pdp); -int gsm48_tx_gsm_deact_pdp_acc(struct sgsn_pdp_ctx *pdp); - -int gsm0408_gprs_rcvmsg_gb(struct msgb *msg, struct gprs_llc_llme *llme, - bool drop_cipherable); -int gsm0408_gprs_rcvmsg_iu(struct msgb *msg, struct gprs_ra_id *ra_id, - uint16_t *sai); -int gsm0408_gprs_force_reattach(struct sgsn_mm_ctx *mmctx); -int gsm0408_gprs_force_reattach_oldmsg(struct msgb *msg, - struct gprs_llc_llme *llme); -void gsm0408_gprs_access_granted(struct sgsn_mm_ctx *mmctx); -void gsm0408_gprs_access_denied(struct sgsn_mm_ctx *mmctx, int gmm_cause); -void gsm0408_gprs_access_cancelled(struct sgsn_mm_ctx *mmctx, int gmm_cause); -void gsm0408_gprs_authenticate(struct sgsn_mm_ctx *mmctx); - -int gprs_gmm_rx_suspend(struct gprs_ra_id *raid, uint32_t tlli); -int gprs_gmm_rx_resume(struct gprs_ra_id *raid, uint32_t tlli, - uint8_t suspend_ref); - -time_t gprs_max_time_to_idle(void); - -int iu_rab_act_ps(uint8_t rab_id, struct sgsn_pdp_ctx *pdp); - -#endif /* _GPRS_GMM_H */ diff --git a/include/openbsc/gprs_llc.h b/include/openbsc/gprs_llc.h deleted file mode 100644 index 8bc226781..000000000 --- a/include/openbsc/gprs_llc.h +++ /dev/null @@ -1,284 +0,0 @@ -#ifndef _GPRS_LLC_H -#define _GPRS_LLC_H - -#include -#include -#include -#include - -/* Section 4.7 LLC Layer Structure */ -enum gprs_llc_sapi { - GPRS_SAPI_GMM = 1, - GPRS_SAPI_TOM2 = 2, - GPRS_SAPI_SNDCP3 = 3, - GPRS_SAPI_SNDCP5 = 5, - GPRS_SAPI_SMS = 7, - GPRS_SAPI_TOM8 = 8, - GPRS_SAPI_SNDCP9 = 9, - GPRS_SAPI_SNDCP11 = 11, -}; - -/* Section 6.4 Commands and Responses */ -enum gprs_llc_u_cmd { - GPRS_LLC_U_DM_RESP = 0x01, - GPRS_LLC_U_DISC_CMD = 0x04, - GPRS_LLC_U_UA_RESP = 0x06, - GPRS_LLC_U_SABM_CMD = 0x07, - GPRS_LLC_U_FRMR_RESP = 0x08, - GPRS_LLC_U_XID = 0x0b, - GPRS_LLC_U_NULL_CMD = 0x00, -}; - -/* Section 6.4.1.6 / Table 6 */ -enum gprs_llc_xid_type { - GPRS_LLC_XID_T_VERSION = 0, - GPRS_LLC_XID_T_IOV_UI = 1, - GPRS_LLC_XID_T_IOV_I = 2, - GPRS_LLC_XID_T_T200 = 3, - GPRS_LLC_XID_T_N200 = 4, - GPRS_LLC_XID_T_N201_U = 5, - GPRS_LLC_XID_T_N201_I = 6, - GPRS_LLC_XID_T_mD = 7, - GPRS_LLC_XID_T_mU = 8, - GPRS_LLC_XID_T_kD = 9, - GPRS_LLC_XID_T_kU = 10, - GPRS_LLC_XID_T_L3_PAR = 11, - GPRS_LLC_XID_T_RESET = 12, -}; - -extern const struct value_string gprs_llc_xid_type_names[]; - -/* TS 04.64 Section 7.1.2 Table 7: LLC layer primitives (GMM/SNDCP/SMS/TOM) */ -/* TS 04.65 Section 5.1.2 Table 2: Service primitives used by SNDCP */ -enum gprs_llc_primitive { - /* GMM <-> LLME */ - LLGMM_ASSIGN_REQ, /* GMM tells us new TLLI: TLLI old, TLLI new, Kc, CiphAlg */ - LLGMM_RESET_REQ, /* GMM tells us to perform XID negotiation: TLLI */ - LLGMM_RESET_CNF, /* LLC informs GMM that XID has completed: TLLI */ - LLGMM_SUSPEND_REQ, /* GMM tells us MS has suspended: TLLI, Page */ - LLGMM_RESUME_REQ, /* GMM tells us MS has resumed: TLLI */ - LLGMM_PAGE_IND, /* LLC asks GMM to page MS: TLLI */ - LLGMM_IOV_REQ, /* GMM tells us to perform XID: TLLI */ - LLGMM_STATUS_IND, /* LLC informs GMM about error: TLLI, Cause */ - /* LLE <-> (GMM/SNDCP/SMS/TOM) */ - LL_RESET_IND, /* TLLI */ - LL_ESTABLISH_REQ, /* TLLI, XID Req */ - LL_ESTABLISH_IND, /* TLLI, XID Req, N201-I, N201-U */ - LL_ESTABLISH_RESP, /* TLLI, XID Negotiated */ - LL_ESTABLISH_CONF, /* TLLI, XID Neg, N201-i, N201-U */ - LL_RELEASE_REQ, /* TLLI, Local */ - LL_RELEASE_IND, /* TLLI, Cause */ - LL_RELEASE_CONF, /* TLLI */ - LL_XID_REQ, /* TLLI, XID Requested */ - LL_XID_IND, /* TLLI, XID Req, N201-I, N201-U */ - LL_XID_RESP, /* TLLI, XID Negotiated */ - LL_XID_CONF, /* TLLI, XID Neg, N201-I, N201-U */ - LL_DATA_REQ, /* TLLI, SN-PDU, Ref, QoS, Radio Prio, Ciph */ - LL_DATA_IND, /* TLLI, SN-PDU */ - LL_DATA_CONF, /* TLLI, Ref */ - LL_UNITDATA_REQ, /* TLLI, SN-PDU, Ref, QoS, Radio Prio, Ciph */ - LL_UNITDATA_IND, /* TLLI, SN-PDU */ - LL_STATUS_IND, /* TLLI, Cause */ -}; - -/* Section 4.5.2 Logical Link States + Annex C.2 */ -enum gprs_llc_lle_state { - GPRS_LLES_UNASSIGNED = 1, /* No TLLI yet */ - GPRS_LLES_ASSIGNED_ADM = 2, /* TLLI assigned */ - GPRS_LLES_LOCAL_EST = 3, /* Local Establishment */ - GPRS_LLES_REMOTE_EST = 4, /* Remote Establishment */ - GPRS_LLES_ABM = 5, - GPRS_LLES_LOCAL_REL = 6, /* Local Release */ - GPRS_LLES_TIMER_REC = 7, /* Timer Recovery */ -}; - -enum gprs_llc_llme_state { - GPRS_LLMS_UNASSIGNED = 1, /* No TLLI yet */ - GPRS_LLMS_ASSIGNED = 2, /* TLLI assigned */ -}; - -/* Section 8.9.9 LLC layer parameter default values */ -struct gprs_llc_params { - uint16_t iov_i_exp; - uint16_t t200_201; - uint16_t n200; - uint16_t n201_u; - uint16_t n201_i; - uint16_t mD; - uint16_t mU; - uint16_t kD; - uint16_t kU; -}; - -/* Section 4.7.1: Logical Link Entity: One per DLCI (TLLI + SAPI) */ -struct gprs_llc_lle { - struct llist_head list; - - uint32_t sapi; - - struct gprs_llc_llme *llme; - - enum gprs_llc_lle_state state; - - struct osmo_timer_list t200; - struct osmo_timer_list t201; /* wait for acknowledgement */ - - uint16_t v_sent; - uint16_t v_ack; - uint16_t v_recv; - - uint16_t vu_send; - uint16_t vu_recv; - - /* non-standard LLC state */ - uint16_t vu_recv_last; - uint16_t vu_recv_duplicates; - - /* Overflow Counter for ABM */ - uint32_t oc_i_send; - uint32_t oc_i_recv; - - /* Overflow Counter for unconfirmed transfer */ - uint32_t oc_ui_send; - uint32_t oc_ui_recv; - - unsigned int retrans_ctr; - - struct gprs_llc_params params; -}; - -#define NUM_SAPIS 16 - -struct gprs_llc_llme { - struct llist_head list; - - enum gprs_llc_llme_state state; - - uint32_t tlli; - uint32_t old_tlli; - - /* Crypto parameters */ - enum gprs_ciph_algo algo; - uint8_t kc[16]; - uint8_t cksn; - /* 3GPP TS 44.064 § 8.9.2: */ - uint32_t iov_ui; - - /* over which BSSGP BTS ctx do we need to transmit */ - uint16_t bvci; - uint16_t nsei; - struct gprs_llc_lle lle[NUM_SAPIS]; - - /* Copy of the XID fields we have sent with the last - * network originated XID-Request. Since the phone - * may strip the optional fields in the confirmation - * we need to remeber those fields in order to be - * able to create the compression entity. */ - struct llist_head *xid; - - /* Compression entities */ - struct { - /* In these two list_heads we will store the - * data and protocol compression entities, - * together with their compression states */ - struct llist_head *proto; - struct llist_head *data; - } comp; - - /* Internal management */ - uint32_t age_timestamp; -}; - -#define GPRS_LLME_RESET_AGE (0) - -extern struct llist_head gprs_llc_llmes; - -/* LLC low level types */ - -enum gprs_llc_cmd { - GPRS_LLC_NULL, - GPRS_LLC_RR, - GPRS_LLC_ACK, - GPRS_LLC_RNR, - GPRS_LLC_SACK, - GPRS_LLC_DM, - GPRS_LLC_DISC, - GPRS_LLC_UA, - GPRS_LLC_SABM, - GPRS_LLC_FRMR, - GPRS_LLC_XID, - GPRS_LLC_UI, -}; - -struct gprs_llc_hdr_parsed { - uint8_t sapi; - uint8_t is_cmd:1, - ack_req:1, - is_encrypted:1; - uint32_t seq_rx; - uint32_t seq_tx; - uint32_t fcs; - uint32_t fcs_calc; - uint8_t *data; - uint16_t data_len; - uint16_t crc_length; - enum gprs_llc_cmd cmd; -}; - - -/* BSSGP-UL-UNITDATA.ind */ -int gprs_llc_rcvmsg(struct msgb *msg, struct tlv_parsed *tv); - -/* LL-UNITDATA.req */ -int gprs_llc_tx_ui(struct msgb *msg, uint8_t sapi, int command, - struct sgsn_mm_ctx *mmctx, bool encryptable); - -/* Chapter 7.2.1.2 LLGMM-RESET.req */ -int gprs_llgmm_reset(struct gprs_llc_llme *llme); -int gprs_llgmm_reset_oldmsg(struct msgb* oldmsg, uint8_t sapi, - struct gprs_llc_llme *llme); - -/* Set of LL-XID negotiation (See also: TS 101 351, Section 7.2.2.4) */ -int gprs_ll_xid_req(struct gprs_llc_lle *lle, - struct gprs_llc_xid_field *l3_xid_field); - -/* 04.64 Chapter 7.2.1.1 LLGMM-ASSIGN */ -int gprs_llgmm_assign(struct gprs_llc_llme *llme, - uint32_t old_tlli, uint32_t new_tlli); -int gprs_llgmm_unassign(struct gprs_llc_llme *llme); - -int gprs_llc_init(const char *cipher_plugin_path); -int gprs_llc_vty_init(void); - -/** - * \short Check if N(U) should be considered a retransmit - * - * Implements the range check as of GSM 04.64 8.4.2 - * Receipt of unacknowledged information. - * - * @returns Returns 1 if (V(UR)-32) <= N(U) < V(UR) - * @param nu N(U) unconfirmed sequence number of the UI frame - * @param vur V(UR) unconfirmend received state variable - */ -static inline int gprs_llc_is_retransmit(uint16_t nu, uint16_t vur) -{ - int delta = (vur - nu) & 0x1ff; - return 0 < delta && delta < 32; -} - -/* LLC low level functions */ -void gprs_llme_copy_key(struct sgsn_mm_ctx *mm, struct gprs_llc_llme *llme); - -/* parse a GPRS LLC header, also check for invalid frames */ -int gprs_llc_hdr_parse(struct gprs_llc_hdr_parsed *ghp, - uint8_t *llc_hdr, int len); -void gprs_llc_hdr_dump(struct gprs_llc_hdr_parsed *gph, struct gprs_llc_lle *lle); -int gprs_llc_fcs(uint8_t *data, unsigned int len); - - -/* LLME handling routines */ -struct llist_head *gprs_llme_list(void); -struct gprs_llc_lle *gprs_lle_get_or_create(const uint32_t tlli, uint8_t sapi); - - -#endif diff --git a/include/openbsc/gprs_llc_xid.h b/include/openbsc/gprs_llc_xid.h deleted file mode 100644 index d340d40b7..000000000 --- a/include/openbsc/gprs_llc_xid.h +++ /dev/null @@ -1,57 +0,0 @@ -/* GPRS LLC XID field encoding/decoding as per 3GPP TS 44.064 */ - -/* (C) 2016 by sysmocom s.f.m.c. GmbH - * All Rights Reserved - * - * Author: Philipp Maier - * - * 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 . - */ - -#pragma once - -#include -#include - -/* 3GPP TS 44.064 6.4.1.6 Exchange Identification (XID) - command/response parameter field */ -struct gprs_llc_xid_field { - struct llist_head list; - uint8_t type; /* See also Table 6: LLC layer parameter - negotiation */ - uint8_t *data; /* Payload data (memory is owned by the - * creator of the struct) */ - unsigned int data_len; /* Payload length */ -}; - -/* Transform a list with XID fields into a XID message (dst) */ -int gprs_llc_compile_xid(uint8_t *dst, int dst_maxlen, - const struct llist_head *xid_fields); - -/* Transform a XID message (dst) into a list of XID fields */ -struct llist_head *gprs_llc_parse_xid(const void *ctx, const uint8_t *src, - int src_len); - -/* Create a duplicate of an XID-Field */ -struct gprs_llc_xid_field *gprs_llc_dup_xid_field(const void *ctx, - const struct gprs_llc_xid_field *xid_field); - -/* Copy an llist with xid fields */ -struct llist_head *gprs_llc_copy_xid(const void *ctx, - const struct llist_head *xid_fields); - -/* Dump a list with XID fields (Debug) */ -void gprs_llc_dump_xid_fields(const struct llist_head *xid_fields, - unsigned int logl); - diff --git a/include/openbsc/gprs_sgsn.h b/include/openbsc/gprs_sgsn.h deleted file mode 100644 index c47fb0905..000000000 --- a/include/openbsc/gprs_sgsn.h +++ /dev/null @@ -1,484 +0,0 @@ -#ifndef _GPRS_SGSN_H -#define _GPRS_SGSN_H - -#include -#include - -#include - -#include - -#include -#include -#include - -#define GSM_EXTENSION_LENGTH 15 -#define GSM_APN_LENGTH 102 - -struct gprs_llc_lle; -struct ctrl_handle; -struct gprs_subscr; - -enum gsm48_gsm_cause; - -/* TS 04.08 4.1.3.3 GMM mobility management states on the network side */ -enum gprs_gmm_state { - GMM_DEREGISTERED, /* 4.1.3.3.1.1 */ - GMM_COMMON_PROC_INIT, /* 4.1.3.3.1.2 */ - GMM_REGISTERED_NORMAL, /* 4.1.3.3.2.1 */ - GMM_REGISTERED_SUSPENDED, /* 4.1.3.3.2.2 */ - GMM_DEREGISTERED_INIT, /* 4.1.3.3.1.4 */ -}; - -/* TS 23.060 6.1.1 and 6.1.2 Mobility management states A/Gb and Iu mode */ -enum gprs_pmm_state { - PMM_DETACHED, - PMM_CONNECTED, - PMM_IDLE, - MM_IDLE, - MM_READY, - MM_STANDBY, -}; - -enum gprs_mm_ctr { - GMM_CTR_PKTS_SIG_IN, - GMM_CTR_PKTS_SIG_OUT, - GMM_CTR_PKTS_UDATA_IN, - GMM_CTR_PKTS_UDATA_OUT, - GMM_CTR_BYTES_UDATA_IN, - GMM_CTR_BYTES_UDATA_OUT, - GMM_CTR_PDP_CTX_ACT, - GMM_CTR_SUSPEND, - GMM_CTR_PAGING_PS, - GMM_CTR_PAGING_CS, - GMM_CTR_RA_UPDATE, -}; - -enum gprs_pdp_ctx { - PDP_CTR_PKTS_UDATA_IN, - PDP_CTR_PKTS_UDATA_OUT, - PDP_CTR_BYTES_UDATA_IN, - PDP_CTR_BYTES_UDATA_OUT, -}; - -enum gprs_t3350_mode { - GMM_T3350_MODE_NONE, - GMM_T3350_MODE_ATT, - GMM_T3350_MODE_RAU, - GMM_T3350_MODE_PTMSI_REALL, -}; - -/* Authorization/ACL handling */ -enum sgsn_auth_state { - SGSN_AUTH_UNKNOWN, - SGSN_AUTH_AUTHENTICATE, - SGSN_AUTH_UMTS_RESYNC, - SGSN_AUTH_ACCEPTED, - SGSN_AUTH_REJECTED -}; - -#define MS_RADIO_ACCESS_CAPA - -enum sgsn_ggsn_lookup_state { - SGSN_GGSN_2DIGIT, - SGSN_GGSN_3DIGIT, -}; - -struct sgsn_ggsn_lookup { - int state; - - struct sgsn_mm_ctx *mmctx; - - /* APN string */ - char apn_str[GSM_APN_LENGTH]; - - /* the original data */ - struct msgb *orig_msg; - struct tlv_parsed tp; - - /* for dealing with re-transmissions */ - uint8_t nsapi; - uint8_t sapi; - uint8_t ti; -}; - -enum sgsn_ran_type { - /* GPRS/EDGE via Gb */ - MM_CTX_T_GERAN_Gb, - /* UMTS via Iu */ - MM_CTX_T_UTRAN_Iu, - /* GPRS/EDGE via Iu */ - MM_CTX_T_GERAN_Iu, -}; - -struct service_info { - uint8_t type; - uint16_t pdp_status; -}; - -struct ranap_ue_conn_ctx; - -struct gsm_auth_tuple { - int use_count; - int key_seq; - struct osmo_auth_vector vec; -}; -#define GSM_KEY_SEQ_INVAL 7 /* GSM 04.08 - 10.5.1.2 */ - -/* According to TS 03.60, Table 5: SGSN MM and PDP Contexts */ -/* Extended by 3GPP TS 23.060, Table 6: SGSN MM and PDP Contexts */ -struct sgsn_mm_ctx { - struct llist_head list; - - enum sgsn_ran_type ran_type; - - char imsi[GSM23003_IMSI_MAX_DIGITS+1]; - enum gprs_gmm_state gmm_state; - enum gprs_pmm_state pmm_state; /* Iu: page when in PMM-IDLE mode */ - uint32_t p_tmsi; - uint32_t p_tmsi_old; /* old P-TMSI before new is confirmed */ - uint32_t p_tmsi_sig; - char imei[GSM23003_IMEISV_NUM_DIGITS+1]; - /* Opt: Software Version Numbber / TS 23.195 */ - char msisdn[GSM_EXTENSION_LENGTH]; - struct gprs_ra_id ra; - struct { - uint16_t cell_id; /* Gb only */ - uint32_t cell_id_age; /* Gb only */ - uint8_t radio_prio_sms; - - /* Additional bits not present in the GSM TS */ - uint16_t nsei; - uint16_t bvci; - struct gprs_llc_llme *llme; - uint32_t tlli; - uint32_t tlli_new; - } gb; - struct { - int new_key; - uint16_t sac; /* Iu: Service Area Code */ - uint32_t sac_age; /* Iu: Service Area Code age */ - /* CSG ID */ - /* CSG Membership */ - /* Access Mode */ - /* Seelected CN Operator ID (TS 23.251) */ - /* CSG Subscription Data */ - /* LIPA Allowed */ - /* Voice Support Match Indicator */ - struct ranap_ue_conn_ctx *ue_ctx; - struct service_info service; - } iu; - /* VLR number */ - uint32_t new_sgsn_addr; - /* Authentication Triplet */ - struct gsm_auth_tuple auth_triplet; - /* Kc */ - /* Iu: CK, IK, KSI */ - /* CKSN */ - enum gprs_ciph_algo ciph_algo; - /* Auth & Ciphering Request reference from 3GPP TS 24.008 § 10.5.5.19: */ - uint8_t ac_ref_nr_used; - - struct { - uint8_t len; - uint8_t buf[50]; /* GSM 04.08 10.5.5.12a, extended in TS 24.008 */ - } ms_radio_access_capa; - /* Supported Codecs (SRVCC) */ - struct { - uint8_t len; - uint8_t buf[8]; /* GSM 04.08 10.5.5.12, extended in TS 24.008 */ - } ms_network_capa; - /* UE Netowrk Capability (E-UTRAN) */ - uint16_t drx_parms; - /* Active Time value for PSM */ - int mnrg; /* MS reported to HLR? */ - int ngaf; /* MS reported to MSC/VLR? */ - int ppf; /* paging for GPRS + non-GPRS? */ - /* Subscribed Charging Characteristics */ - /* Trace Reference */ - /* Trace Type */ - /* Trigger ID */ - /* OMC Identity */ - /* SMS Parameters */ - int recovery; - /* Access Restriction */ - /* GPRS CSI (CAMEL) */ - /* MG-CSI (CAMEL) */ - /* Subscribed UE-AMBR */ - /* UE-AMBR */ - /* APN Subscribed */ - - struct llist_head pdp_list; - - struct rate_ctr_group *ctrg; - struct osmo_timer_list timer; - unsigned int T; /* Txxxx number */ - unsigned int num_T_exp; /* number of consecutive T expirations */ - - enum gprs_t3350_mode t3350_mode; - uint8_t t3370_id_type; - uint8_t pending_req; /* the request's message type */ - /* TODO: There isn't much semantic difference between t3350_mode - * (refers to the timer) and pending_req (refers to the procedure), - * where mm->T == 3350 => mm->t3350_mode == f(mm->pending_req). Check - * whether one of them can be dropped. */ - - enum sgsn_auth_state auth_state; - int is_authenticated; - - /* the string representation of the current hlr */ - char hlr[GSM_EXTENSION_LENGTH]; - - /* the current GGSN look-up operation */ - struct sgsn_ggsn_lookup *ggsn_lookup; - - struct gprs_subscr *subscr; -}; - -#define LOGMMCTXP(level, mm, fmt, args...) \ - LOGP(DMM, level, "MM(%s/%08x) " fmt, (mm) ? (mm)->imsi : "---", \ - (mm) ? (mm)->p_tmsi : GSM_RESERVED_TMSI, ## args) - -/* look-up a SGSN MM context based on TLLI + RAI */ -struct sgsn_mm_ctx *sgsn_mm_ctx_by_tlli(uint32_t tlli, - const struct gprs_ra_id *raid); -struct sgsn_mm_ctx *sgsn_mm_ctx_by_ptmsi(uint32_t tmsi); -struct sgsn_mm_ctx *sgsn_mm_ctx_by_imsi(const char *imsi); -struct sgsn_mm_ctx *sgsn_mm_ctx_by_ue_ctx(const void *uectx); - -/* look-up by matching TLLI and P-TMSI (think twice before using this) */ -struct sgsn_mm_ctx *sgsn_mm_ctx_by_tlli_and_ptmsi(uint32_t tlli, - const struct gprs_ra_id *raid); - -/* Allocate a new SGSN MM context */ -struct sgsn_mm_ctx *sgsn_mm_ctx_alloc_gb(uint32_t tlli, - const struct gprs_ra_id *raid); -struct sgsn_mm_ctx *sgsn_mm_ctx_alloc_iu(void *uectx); - -void sgsn_mm_ctx_cleanup_free(struct sgsn_mm_ctx *ctx); - -struct sgsn_ggsn_ctx *sgsn_mm_ctx_find_ggsn_ctx(struct sgsn_mm_ctx *mmctx, - struct tlv_parsed *tp, - enum gsm48_gsm_cause *gsm_cause, - char *apn_str); - -enum pdp_ctx_state { - PDP_STATE_NONE, - PDP_STATE_CR_REQ, - PDP_STATE_CR_CONF, - - /* 04.08 / Figure 6.2 / 6.1.2.2 */ - PDP_STATE_INACT_PEND, - PDP_STATE_INACTIVE = PDP_STATE_NONE, -}; - -enum pdp_type { - PDP_TYPE_NONE, - PDP_TYPE_ETSI_PPP, - PDP_TYPE_IANA_IPv4, - PDP_TYPE_IANA_IPv6, -}; - -struct sgsn_pdp_ctx { - struct llist_head list; /* list_head for mmctx->pdp_list */ - struct llist_head g_list; /* list_head for global list */ - struct sgsn_mm_ctx *mm; /* back pointer to MM CTX */ - int destroy_ggsn; /* destroy it on destruction */ - struct sgsn_ggsn_ctx *ggsn; /* which GGSN serves this PDP */ - struct rate_ctr_group *ctrg; - - //unsigned int id; - struct pdp_t *lib; /* pointer to libgtp PDP ctx */ - enum pdp_ctx_state state; - enum pdp_type type; - uint32_t address; - char *apn_subscribed; - //char *apn_used; - uint16_t nsapi; /* SNDCP */ - uint16_t sapi; /* LLC */ - uint8_t ti; /* transaction identifier */ - int vplmn_allowed; - uint32_t qos_profile_subscr; - //uint32_t qos_profile_req; - //uint32_t qos_profile_neg; - uint8_t radio_prio; - //uint32_t charging_id; - - struct osmo_timer_list timer; - unsigned int T; /* Txxxx number */ - unsigned int num_T_exp; /* number of consecutive T expirations */ - - struct osmo_timer_list cdr_timer; /* CDR record wird timer */ - struct timespec cdr_start; /* The start of the CDR */ - uint64_t cdr_bytes_in; - uint64_t cdr_bytes_out; - uint32_t cdr_charging_id; -}; - -#define LOGPDPCTXP(level, pdp, fmt, args...) \ - LOGP(DGPRS, level, "PDP(%s/%u) " \ - fmt, (pdp)->mm ? (pdp)->mm->imsi : "---", (pdp)->ti, ## args) - -/* look up PDP context by MM context and NSAPI */ -struct sgsn_pdp_ctx *sgsn_pdp_ctx_by_nsapi(const struct sgsn_mm_ctx *mm, - uint8_t nsapi); -/* look up PDP context by MM context and transaction ID */ -struct sgsn_pdp_ctx *sgsn_pdp_ctx_by_tid(const struct sgsn_mm_ctx *mm, - uint8_t tid); - -struct sgsn_pdp_ctx *sgsn_pdp_ctx_alloc(struct sgsn_mm_ctx *mm, - uint8_t nsapi); -void sgsn_pdp_ctx_terminate(struct sgsn_pdp_ctx *pdp); -void sgsn_pdp_ctx_free(struct sgsn_pdp_ctx *pdp); - - -struct sgsn_ggsn_ctx { - struct llist_head list; - uint32_t id; - unsigned int gtp_version; - struct in_addr remote_addr; - int remote_restart_ctr; - struct gsn_t *gsn; -}; -struct sgsn_ggsn_ctx *sgsn_ggsn_ctx_alloc(uint32_t id); -void sgsn_ggsn_ctx_free(struct sgsn_ggsn_ctx *ggc); -struct sgsn_ggsn_ctx *sgsn_ggsn_ctx_by_id(uint32_t id); -struct sgsn_ggsn_ctx *sgsn_ggsn_ctx_by_addr(struct in_addr *addr); -struct sgsn_ggsn_ctx *sgsn_ggsn_ctx_find_alloc(uint32_t id); - -struct apn_ctx { - struct llist_head list; - struct sgsn_ggsn_ctx *ggsn; - char *name; - char *imsi_prefix; - char *description; -}; - -struct apn_ctx *sgsn_apn_ctx_find_alloc(const char *name, const char *imsi_prefix); -void sgsn_apn_ctx_free(struct apn_ctx *actx); -struct apn_ctx *sgsn_apn_ctx_by_name(const char *name, const char *imsi_prefix); -struct apn_ctx *sgsn_apn_ctx_match(const char *name, const char *imsi_prefix); - -extern struct llist_head sgsn_mm_ctxts; -extern struct llist_head sgsn_ggsn_ctxts; -extern struct llist_head sgsn_apn_ctxts; -extern struct llist_head sgsn_pdp_ctxts; - -uint32_t sgsn_alloc_ptmsi(void); -void sgsn_inst_init(void); - -/* High-level function to be called in case a GGSN has disappeared or - * ottherwise lost state (recovery procedure) */ -int drop_all_pdp_for_ggsn(struct sgsn_ggsn_ctx *ggsn); - -char *gprs_pdpaddr2str(uint8_t *pdpa, uint8_t len); - -/* - * ctrl interface related work - */ -struct gsm_network; -struct ctrl_handle *sgsn_controlif_setup(struct gsm_network *, - const char *bind_addr, uint16_t port); -int sgsn_ctrl_cmds_install(void); - -/* - * Authorization/ACL handling - */ -struct imsi_acl_entry { - struct llist_head list; - char imsi[16+1]; -}; - -/* see GSM 09.02, 17.7.1, PDP-Context and GPRSSubscriptionData */ -/* see GSM 09.02, B.1, gprsSubscriptionData */ -struct sgsn_subscriber_pdp_data { - struct llist_head list; - - unsigned int context_id; - uint16_t pdp_type; - char apn_str[GSM_APN_LENGTH]; - uint8_t qos_subscribed[20]; - size_t qos_subscribed_len; - uint8_t pdp_charg[2]; - bool has_pdp_charg; -}; - -struct sgsn_subscriber_data { - struct sgsn_mm_ctx *mm; - struct gsm_auth_tuple auth_triplets[5]; - int auth_triplets_updated; - struct llist_head pdp_list; - int error_cause; - - uint8_t msisdn[9]; - size_t msisdn_len; - - uint8_t hlr[9]; - size_t hlr_len; - - uint8_t pdp_charg[2]; - bool has_pdp_charg; -}; - -#define SGSN_ERROR_CAUSE_NONE (-1) - -#define LOGGSUBSCRP(level, subscr, fmt, args...) \ - LOGP(DGPRS, level, "SUBSCR(%s) " fmt, \ - (subscr) ? (subscr)->imsi : "---", \ - ## args) - -struct sgsn_config; -struct sgsn_instance; -extern const struct value_string *sgsn_auth_state_names; - -void sgsn_auth_init(void); -struct imsi_acl_entry *sgsn_acl_lookup(const char *imsi, struct sgsn_config *cfg); -int sgsn_acl_add(const char *imsi, struct sgsn_config *cfg); -int sgsn_acl_del(const char *imsi, struct sgsn_config *cfg); -/* Request authorization */ -int sgsn_auth_request(struct sgsn_mm_ctx *mm); -enum sgsn_auth_state sgsn_auth_state(struct sgsn_mm_ctx *mm); -void sgsn_auth_update(struct sgsn_mm_ctx *mm); -struct gsm_auth_tuple *sgsn_auth_get_tuple(struct sgsn_mm_ctx *mmctx, - unsigned key_seq); - -/* - * GPRS subscriber data - */ -#define GPRS_SUBSCRIBER_FIRST_CONTACT 0x00000001 -#define GPRS_SUBSCRIBER_UPDATE_AUTH_INFO_PENDING (1 << 16) -#define GPRS_SUBSCRIBER_UPDATE_LOCATION_PENDING (1 << 17) -#define GPRS_SUBSCRIBER_CANCELLED (1 << 18) -#define GPRS_SUBSCRIBER_ENABLE_PURGE (1 << 19) - -#define GPRS_SUBSCRIBER_UPDATE_PENDING_MASK ( \ - GPRS_SUBSCRIBER_UPDATE_LOCATION_PENDING | \ - GPRS_SUBSCRIBER_UPDATE_AUTH_INFO_PENDING \ -) - -int gprs_subscr_init(struct sgsn_instance *sgi); -int gprs_subscr_request_update_location(struct sgsn_mm_ctx *mmctx); -int gprs_subscr_request_auth_info(struct sgsn_mm_ctx *mmctx, - const uint8_t *auts, - const uint8_t *auts_rand); -int gprs_subscr_auth_sync(struct gprs_subscr *subscr, - const uint8_t *auts, const uint8_t *auts_rand); -void gprs_subscr_cleanup(struct gprs_subscr *subscr); -struct gprs_subscr *gprs_subscr_get_or_create(const char *imsi); -struct gprs_subscr *gprs_subscr_get_or_create_by_mmctx( struct sgsn_mm_ctx *mmctx); -struct gprs_subscr *gprs_subscr_get_by_imsi(const char *imsi); -void gprs_subscr_cancel(struct gprs_subscr *subscr); -void gprs_subscr_update(struct gprs_subscr *subscr); -void gprs_subscr_update_auth_info(struct gprs_subscr *subscr); -int gprs_subscr_rx_gsup_message(struct msgb *msg); - -/* Called on subscriber data updates */ -void sgsn_update_subscriber_data(struct sgsn_mm_ctx *mmctx); - -int gprs_sndcp_vty_init(void); -struct sgsn_instance; -int sgsn_gtp_init(struct sgsn_instance *sgi); - -void sgsn_rate_ctr_init(); - -#endif /* _GPRS_SGSN_H */ diff --git a/include/openbsc/gprs_sndcp.h b/include/openbsc/gprs_sndcp.h deleted file mode 100644 index d970240e4..000000000 --- a/include/openbsc/gprs_sndcp.h +++ /dev/null @@ -1,79 +0,0 @@ -#ifndef _INT_SNDCP_H -#define _INT_SNDCP_H - -#include -#include - -/* A fragment queue header, maintaining list of fragments for one N-PDU */ -struct defrag_state { - /* PDU number for which the defragmentation state applies */ - uint16_t npdu; - /* highest segment number we have received so far */ - uint8_t highest_seg; - /* bitmask of the segments we already have */ - uint32_t seg_have; - /* do we still expect more segments? */ - unsigned int no_more; - /* total length of all segments together */ - unsigned int tot_len; - - /* linked list of defrag_queue_entry: one for each fragment */ - struct llist_head frag_list; - - struct osmo_timer_list timer; - - /* Holds state to know which compression mode is used - * when the packet is re-assembled */ - uint8_t pcomp; - uint8_t dcomp; - - /* Holds the pointers to the compression entity list - * that is used when the re-assembled packet is decompressed */ - struct llist_head *proto; - struct llist_head *data; -}; - -/* See 6.7.1.2 Reassembly */ -enum sndcp_rx_state { - SNDCP_RX_S_FIRST, - SNDCP_RX_S_SUBSEQ, - SNDCP_RX_S_DISCARD, -}; - -struct gprs_sndcp_entity { - struct llist_head list; - - /* FIXME: move this RA_ID up to the LLME or even higher */ - struct gprs_ra_id ra_id; - /* reference to the LLC Entity below this SNDCP entity */ - struct gprs_llc_lle *lle; - /* The NSAPI we shall use on top of LLC */ - uint8_t nsapi; - - /* NPDU number for the GTP->SNDCP side */ - uint16_t tx_npdu_nr; - /* SNDCP eeceiver state */ - enum sndcp_rx_state rx_state; - /* The defragmentation queue */ - struct defrag_state defrag; -}; - -extern struct llist_head gprs_sndcp_entities; - -/* Set of SNDCP-XID negotiation (See also: TS 144 065, - * Section 6.8 XID parameter negotiation) */ -int sndcp_sn_xid_req(struct gprs_llc_lle *lle, uint8_t nsapi); - -/* Process SNDCP-XID indication (See also: TS 144 065, - * Section 6.8 XID parameter negotiation) */ -int sndcp_sn_xid_ind(struct gprs_llc_xid_field *xid_field_indication, - struct gprs_llc_xid_field *xid_field_response, - struct gprs_llc_lle *lle); - -/* Process SNDCP-XID indication - * (See also: TS 144 065, Section 6.8 XID parameter negotiation) */ -int sndcp_sn_xid_conf(struct gprs_llc_xid_field *xid_field_conf, - struct gprs_llc_xid_field *xid_field_request, - struct gprs_llc_lle *lle); - -#endif /* INT_SNDCP_H */ diff --git a/include/openbsc/gprs_sndcp_comp.h b/include/openbsc/gprs_sndcp_comp.h deleted file mode 100644 index 87ab6382a..000000000 --- a/include/openbsc/gprs_sndcp_comp.h +++ /dev/null @@ -1,82 +0,0 @@ -/* GPRS SNDCP header compression entity management tools */ - -/* (C) 2016 by sysmocom s.f.m.c. GmbH - * All Rights Reserved - * - * Author: Philipp Maier - * - * 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 . - */ - -#pragma once - -#include -#include -#include - -/* Header / Data compression entity */ -struct gprs_sndcp_comp { - struct llist_head list; - - /* Serves as an ID in case we want to delete this entity later */ - unsigned int entity; /* see also: 6.5.1.1.3 and 6.6.1.1.3 */ - - /* Specifies to which NSAPIs the compression entity is assigned */ - uint8_t nsapi_len; /* Number of applicable NSAPIs (default 0) */ - uint8_t nsapi[MAX_NSAPI]; /* Applicable NSAPIs (default 0) */ - - /* Assigned pcomp values */ - uint8_t comp_len; /* Number of contained PCOMP / DCOMP values */ - uint8_t comp[MAX_COMP]; /* see also: 6.5.1.1.5 and 6.6.1.1.5 */ - - /* Algorithm parameters */ - int algo; /* Algorithm type (see gprs_sndcp_xid.h) */ - int compclass; /* See gprs_sndcp_xid.h/c */ - void *state; /* Algorithm status and parameters */ -}; - -#define MAX_COMP 16 /* Maximum number of possible pcomp/dcomp values */ -#define MAX_NSAPI 11 /* Maximum number usable NSAPIs */ - -/* Allocate a compression enitiy list */ -struct llist_head *gprs_sndcp_comp_alloc(const void *ctx); - -/* Free a compression entitiy list */ -void gprs_sndcp_comp_free(struct llist_head *comp_entities); - -/* Delete a compression entity */ -void gprs_sndcp_comp_delete(struct llist_head *comp_entities, unsigned int entity); - -/* Create and Add a new compression entity - * (returns a pointer to the compression entity that has just been created) */ -struct gprs_sndcp_comp *gprs_sndcp_comp_add(const void *ctx, - struct llist_head *comp_entities, - const struct gprs_sndcp_comp_field - *comp_field); - -/* Find which compression entity handles the specified pcomp/dcomp */ -struct gprs_sndcp_comp *gprs_sndcp_comp_by_comp(const struct llist_head - *comp_entities, uint8_t comp); - -/* Find which compression entity handles the specified nsapi */ -struct gprs_sndcp_comp *gprs_sndcp_comp_by_nsapi(const struct llist_head - *comp_entities, uint8_t nsapi); - -/* Find a comp_index for a given pcomp/dcomp value */ -uint8_t gprs_sndcp_comp_get_idx(const struct gprs_sndcp_comp *comp_entity, - uint8_t comp); - -/* Find a pcomp/dcomp value for a given comp_index */ -uint8_t gprs_sndcp_comp_get_comp(const struct gprs_sndcp_comp *comp_entity, - uint8_t comp_index); diff --git a/include/openbsc/gprs_sndcp_dcomp.h b/include/openbsc/gprs_sndcp_dcomp.h deleted file mode 100644 index a76b4a4b3..000000000 --- a/include/openbsc/gprs_sndcp_dcomp.h +++ /dev/null @@ -1,53 +0,0 @@ -/* GPRS SNDCP data compression handler */ - -/* (C) 2016 by sysmocom s.f.m.c. GmbH - * All Rights Reserved - * - * Author: Philipp Maier - * - * 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 . - */ - -#pragma once - -#include -#include -#include - -/* Note: The decompressed packet may have a maximum size of: - * Return value * MAX_DATADECOMPR_FAC */ -#define MAX_DATADECOMPR_FAC 10 - -/* Note: In unacknowledged mode (SN_UNITDATA), the comression state is reset - * for every NPDU. The compressor needs a reasonably large payload to operate - * effectively (yield positive compression gain). For packets shorter than 100 - * byte, no positive compression gain can be expected so we will skip the - * compression for short packets. */ -#define MIN_COMPR_PAYLOAD 100 - -/* Initalize data compression */ -int gprs_sndcp_dcomp_init(const void *ctx, struct gprs_sndcp_comp *comp_entity, - const struct gprs_sndcp_comp_field *comp_field); - -/* Terminate data compression */ -void gprs_sndcp_dcomp_term(struct gprs_sndcp_comp *comp_entity); - -/* Expand packet */ -int gprs_sndcp_dcomp_expand(uint8_t *data, unsigned int len, uint8_t pcomp, - const struct llist_head *comp_entities); - -/* Compress packet */ -int gprs_sndcp_dcomp_compress(uint8_t *data, unsigned int len, uint8_t *pcomp, - const struct llist_head *comp_entities, - uint8_t nsapi); diff --git a/include/openbsc/gprs_sndcp_pcomp.h b/include/openbsc/gprs_sndcp_pcomp.h deleted file mode 100644 index 4e15b9be2..000000000 --- a/include/openbsc/gprs_sndcp_pcomp.h +++ /dev/null @@ -1,46 +0,0 @@ -/* GPRS SNDCP header compression handler */ - -/* (C) 2016 by sysmocom s.f.m.c. GmbH - * All Rights Reserved - * - * Author: Philipp Maier - * - * 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 . - */ - -#pragma once - -#include -#include -#include - -/* Note: The decompressed packet may have a maximum size of: - * Return value + MAX_DECOMPR_INCR */ -#define MAX_HDRDECOMPR_INCR 64 - -/* Initalize header compression */ -int gprs_sndcp_pcomp_init(const void *ctx, struct gprs_sndcp_comp *comp_entity, - const struct gprs_sndcp_comp_field *comp_field); - -/* Terminate header compression */ -void gprs_sndcp_pcomp_term(struct gprs_sndcp_comp *comp_entity); - -/* Expand packet header */ -int gprs_sndcp_pcomp_expand(uint8_t *data, unsigned int len, uint8_t pcomp, - const struct llist_head *comp_entities); - -/* Compress packet header */ -int gprs_sndcp_pcomp_compress(uint8_t *data, unsigned int len, uint8_t *pcomp, - const struct llist_head *comp_entities, - uint8_t nsapi); diff --git a/include/openbsc/gprs_sndcp_xid.h b/include/openbsc/gprs_sndcp_xid.h deleted file mode 100644 index e64bc5237..000000000 --- a/include/openbsc/gprs_sndcp_xid.h +++ /dev/null @@ -1,218 +0,0 @@ -/* GPRS SNDCP XID field encoding/decoding as per 3GPP TS 44.065 */ - -/* (C) 2016 by sysmocom s.f.m.c. GmbH - * All Rights Reserved - * - * Author: Philipp Maier - * - * 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 . - */ - -#pragma once - -#include -#include - -#define DEFAULT_SNDCP_VERSION 0 /* See 3GPP TS 44.065, clause 8 */ -#define MAX_ENTITIES 32 /* 3GPP TS 44.065 reserves 5 bit - * for compression enitity number */ - -#define MAX_COMP 16 /* Maximum number of possible pcomp/dcomp values */ -#define MAX_NSAPI 11 /* Maximum number usable NSAPIs */ -#define MAX_ROHC 16 /* Maximum number of ROHC compression profiles */ - -/* According to: 3GPP TS 44.065, 6.5.1.1 Format of the protocol control - * information compression field (Figure 7) and 3GPP TS 44.065, - * 6.6.1.1 Format of the data compression field (Figure 9) */ -struct gprs_sndcp_comp_field { - struct llist_head list; - - /* Propose bit (P), see also: 6.5.1.1.2 and 6.6.1.1.2 */ - unsigned int p; - - /* Entity number, see also: 6.5.1.1.3 and 6.6.1.1.3 */ - unsigned int entity; - - /* Algorithm identifier, see also: 6.5.1.1.4 and 6.6.1.1.4 */ - int algo; - - /* Number of contained PCOMP / DCOMP values */ - uint8_t comp_len; - - /* PCOMP / DCOMP values, see also: 6.5.1.1.5 and 6.6.1.1.5 */ - uint8_t comp[MAX_COMP]; - - /* Note: Only one of the following struct pointers may, - be used. Unused pointers must be set to NULL! */ - struct gprs_sndcp_pcomp_rfc1144_params *rfc1144_params; - struct gprs_sndcp_pcomp_rfc2507_params *rfc2507_params; - struct gprs_sndcp_pcomp_rohc_params *rohc_params; - struct gprs_sndcp_dcomp_v42bis_params *v42bis_params; - struct gprs_sndcp_dcomp_v44_params *v44_params; -}; - -/* According to: 3GPP TS 44.065, 6.5.1.1.4 Algorithm identifier */ -enum gprs_sndcp_hdr_comp_algo { - RFC_1144, /* TCP/IP header compression, see also 6.5.2 */ - RFC_2507, /* TCP/UDP/IP header compression, see also: 6.5.3 */ - ROHC /* Robust Header Compression, see also 6.5.4 */ -}; - -/* According to: 3GPP TS 44.065, 6.5.1.1.4 Algorithm identifier */ -enum gprs_sndcp_data_comp_algo { - V42BIS, /* V.42bis data compression, see also 6.6.2 */ - V44 /* V44 data compression, see also: 6.6.3 */ -}; - -/* According to: 3GPP TS 44.065, 8 SNDCP XID parameters */ -enum gprs_sndcp_xid_param_types { - SNDCP_XID_VERSION_NUMBER, - SNDCP_XID_DATA_COMPRESSION, /* See also: subclause 6.6.1 */ - SNDCP_XID_PROTOCOL_COMPRESSION, /* See also: subclause 6.5.1 */ -}; - -/* According to: 3GPP TS 44.065, 6.5.2.1 Parameters (Table 5) */ -struct gprs_sndcp_pcomp_rfc1144_params { - uint8_t nsapi_len; /* Number of applicable NSAPIs - * (default 0) */ - uint8_t nsapi[MAX_NSAPI]; /* Applicable NSAPIs (default 0) */ - int s01; /* (default 15) */ -}; - -/* According to: 3GPP TS 44.065, 6.5.2.2 Assignment of PCOMP values */ -enum gprs_sndcp_pcomp_rfc1144_pcomp { - RFC1144_PCOMP1, /* Uncompressed TCP */ - RFC1144_PCOMP2, /* Compressed TCP */ - RFC1144_PCOMP_NUM /* Number of pcomp values */ -}; - -/* According to: 3GPP TS 44.065, 6.5.3.1 Parameters (Table 6) */ -struct gprs_sndcp_pcomp_rfc2507_params { - uint8_t nsapi_len; /* Number of applicable NSAPIs - * (default 0) */ - uint8_t nsapi[MAX_NSAPI]; /* Applicable NSAPIs (default 0) */ - int f_max_period; /* (default 256) */ - int f_max_time; /* (default 5) */ - int max_header; /* (default 168) */ - int tcp_space; /* (default 15) */ - int non_tcp_space; /* (default 15) */ -}; - -/* According to: 3GPP TS 44.065, 6.5.3.2 Assignment of PCOMP values for RFC2507 */ -enum gprs_sndcp_pcomp_rfc2507_pcomp { - RFC2507_PCOMP1, /* Full Header */ - RFC2507_PCOMP2, /* Compressed TCP */ - RFC2507_PCOMP3, /* Compressed TCP non delta */ - RFC2507_PCOMP4, /* Compressed non TCP */ - RFC2507_PCOMP5, /* Context state */ - RFC2507_PCOMP_NUM /* Number of pcomp values */ -}; - -/* According to: 3GPP TS 44.065, 6.5.4.1 Parameter (Table 10) */ -struct gprs_sndcp_pcomp_rohc_params { - uint8_t nsapi_len; /* Number of applicable NSAPIs - * (default 0) */ - uint8_t nsapi[MAX_NSAPI]; /* Applicable NSAPIs (default 0) */ - int max_cid; /* (default 15) */ - int max_header; /* (default 168) */ - uint8_t profile_len; /* (default 1) */ - uint16_t profile[MAX_ROHC]; /* (default 0, ROHC uncompressed) */ -}; - -/* According to: 3GPP TS 44.065, 6.5.4.2 Assignment of PCOMP values for ROHC */ -enum gprs_sndcp_pcomp_rohc_pcomp { - ROHC_PCOMP1, /* ROHC small CIDs */ - ROHC_PCOMP2, /* ROHC large CIDs */ - ROHC_PCOMP_NUM /* Number of pcomp values */ -}; - -/* ROHC compression profiles, see also: - http://www.iana.org/assignments/rohc-pro-ids/rohc-pro-ids.xhtml */ -enum gprs_sndcp_xid_rohc_profiles { - ROHC_UNCOMPRESSED = 0x0000, /* ROHC uncompressed [RFC5795] */ - ROHC_RTP = 0x0001, /* ROHC RTP [RFC3095] */ - ROHCV2_RTP = 0x0101, /* ROHCv2 RTP [RFC5225] */ - ROHC_UDP = 0x0002, /* ROHC UDP [RFC3095] */ - ROHCv2_UDP = 0x0102, /* ROHCv2 UDP [RFC5225] */ - ROHC_ESP = 0x0003, /* ROHC ESP [RFC3095] */ - ROHCV2_ESP = 0x0103, /* ROHCv2 ESP [RFC5225] */ - ROHC_IP = 0x0004, /* ROHC IP [RFC3843] */ - ROHCV2_IP = 0x0104, /* ROHCv2 IP [RFC5225] */ - ROHC_LLA = 0x0005, /* ROHC LLA [RFC4362] */ - ROHC_LLA_WITH_R_MODE = 0x0105, /* ROHC LLA with R-mode [RFC3408] */ - ROHC_TCP = 0x0006, /* ROHC TCP [RFC6846] */ - ROHC_RTP_UDP_LITE = 0x0007, /* ROHC RTP/UDP-Lite [RFC4019] */ - ROHCV2_RTP_UDP_LITE = 0x0107, /* ROHCv2 RTP/UDP-Lite [RFC5225] */ - ROHC_UDP_LITE = 0x0008, /* ROHC UDP-Lite [RFC4019] */ - ROHCV2_UDP_LITE = 0x0108, /* ROHCv2 UDP-Lite [RFC5225] */ -}; - -/* According to: 3GPP TS 44.065, 6.6.2.1 Parameters (Table 7a) */ -struct gprs_sndcp_dcomp_v42bis_params { - uint8_t nsapi_len; /* Number of applicable NSAPIs - * (default 0) */ - uint8_t nsapi[MAX_NSAPI]; /* Applicable NSAPIs (default 0) */ - int p0; /* (default 3) */ - int p1; /* (default 2048) */ - int p2; /* (default 20) */ - -}; - -/* According to: 3GPP TS 44.065, 6.6.2.2 Assignment of DCOMP values */ -enum gprs_sndcp_dcomp_v42bis_dcomp { - V42BIS_DCOMP1, /* V.42bis enabled */ - V42BIS_DCOMP_NUM /* Number of dcomp values */ -}; - -/* According to: 3GPP TS 44.065, 6.6.3.1 Parameters (Table 7c) */ -struct gprs_sndcp_dcomp_v44_params { - uint8_t nsapi_len; /* Number of applicable NSAPIs - * (default 0) */ - uint8_t nsapi[MAX_NSAPI]; /* Applicable NSAPIs (default 0) */ - int c0; /* (default 10000000) */ - int p0; /* (default 3) */ - int p1t; /* Refer to subclause 6.6.3.1.4 */ - int p1r; /* Refer to subclause 6.6.3.1.5 */ - int p3t; /* (default 3 x p1t) */ - int p3r; /* (default 3 x p1r) */ -}; - -/* According to: 3GPP TS 44.065, 6.6.3.2 Assignment of DCOMP values */ -enum gprs_sndcp_dcomp_v44_dcomp { - V44_DCOMP1, /* Packet method compressed */ - V44_DCOMP2, /* Multi packet method compressed */ - V44_DCOMP_NUM /* Number of dcomp values */ -}; - -/* Transform a list with compression fields into an SNDCP-XID message (dst) */ -int gprs_sndcp_compile_xid(uint8_t *dst, unsigned int dst_maxlen, - const struct llist_head *comp_fields, int version); - -/* Transform an SNDCP-XID message (src) into a list of SNDCP-XID fields */ -struct llist_head *gprs_sndcp_parse_xid(int *version, - const void *ctx, - const uint8_t *src, - unsigned int src_len, - const struct llist_head - *comp_fields_req); - -/* Find out to which compression class the specified comp-field belongs - * (header compression or data compression?) */ -int gprs_sndcp_get_compression_class( - const struct gprs_sndcp_comp_field *comp_field); - -/* Dump a list with SNDCP-XID fields (Debug) */ -void gprs_sndcp_dump_comp_fields(const struct llist_head *comp_fields, - unsigned int logl); - diff --git a/include/openbsc/gprs_subscriber.h b/include/openbsc/gprs_subscriber.h deleted file mode 100644 index be78febff..000000000 --- a/include/openbsc/gprs_subscriber.h +++ /dev/null @@ -1,31 +0,0 @@ -/* GPRS subscriber details for use in SGSN land */ -#pragma once - -#include - -#include -#include - -extern struct llist_head * const gprs_subscribers; - -struct gprs_subscr { - struct llist_head entry; - int use_count; - - char imsi[GSM23003_IMSI_MAX_DIGITS+1]; - uint32_t tmsi; - char imei[GSM23003_IMEISV_NUM_DIGITS+1]; - bool authorized; - bool keep_in_ram; - uint32_t flags; - uint16_t lac; - - struct sgsn_subscriber_data *sgsn_data; -}; - -struct gprs_subscr *_gprs_subscr_get(struct gprs_subscr *gsub, - const char *file, int line); -struct gprs_subscr *_gprs_subscr_put(struct gprs_subscr *gsub, - const char *file, int line); -#define gprs_subscr_get(gsub) _gprs_subscr_get(gsub, __BASE_FILE__, __LINE__) -#define gprs_subscr_put(gsub) _gprs_subscr_put(gsub, __BASE_FILE__, __LINE__) diff --git a/include/openbsc/gprs_utils.h b/include/openbsc/gprs_utils.h deleted file mode 100644 index e06364dad..000000000 --- a/include/openbsc/gprs_utils.h +++ /dev/null @@ -1,55 +0,0 @@ -/* GPRS utility functions */ - -/* (C) 2010 by Harald Welte - * (C) 2010-2014 by On-Waves - * (C) 2013 by Holger Hans Peter Freyther - * All Rights Reserved - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as published by - * the Free Software Foundation; either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see . - * - */ -#pragma once - -#include -#include - -#include - -struct msgb; -struct gprs_ra_id; - -struct msgb *gprs_msgb_copy(const struct msgb *msg, const char *name); -int gprs_msgb_resize_area(struct msgb *msg, uint8_t *area, - size_t old_size, size_t new_size); -int gprs_str_to_apn(uint8_t *apn_enc, size_t max_len, const char *str); - -/* GSM 04.08, 10.5.7.3 GPRS Timer */ -int gprs_tmr_to_secs(uint8_t tmr); -uint8_t gprs_secs_to_tmr_floor(int secs); - -int gprs_is_mi_tmsi(const uint8_t *value, size_t value_len); -int gprs_is_mi_imsi(const uint8_t *value, size_t value_len); -int gprs_parse_mi_tmsi(const uint8_t *value, size_t value_len, uint32_t *tmsi); -void gprs_parse_tmsi(const uint8_t *value, uint32_t *tmsi); - -int gprs_ra_id_equals(const struct gprs_ra_id *id1, const struct gprs_ra_id *id2); - -#define GSM48_ALLOC_SIZE 2048 -#define GSM48_ALLOC_HEADROOM 256 - -static inline struct msgb *gsm48_msgb_alloc_name(const char *name) -{ - return msgb_alloc_headroom(GSM48_ALLOC_SIZE, GSM48_ALLOC_HEADROOM, - name); -} diff --git a/include/openbsc/gsup_client.h b/include/openbsc/gsup_client.h deleted file mode 100644 index 4a25490f6..000000000 --- a/include/openbsc/gsup_client.h +++ /dev/null @@ -1,63 +0,0 @@ -/* GPRS Subscriber Update Protocol client */ - -/* (C) 2014 by Sysmocom s.f.m.c. GmbH - * All Rights Reserved - * - * Author: Jacob Erlbeck - * - * 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 . - * - */ -#pragma once - -#include - -#include - -#define GSUP_CLIENT_RECONNECT_INTERVAL 10 -#define GSUP_CLIENT_PING_INTERVAL 20 - -struct msgb; -struct ipa_client_conn; -struct gsup_client; - -/* Expects message in msg->l2h */ -typedef int (*gsup_client_read_cb_t)(struct gsup_client *gsupc, - struct msgb *msg); - -struct gsup_client { - const char *unit_name; - - struct ipa_client_conn *link; - gsup_client_read_cb_t read_cb; - void *data; - - struct oap_client_state oap_state; - - struct osmo_timer_list ping_timer; - struct osmo_timer_list connect_timer; - int is_connected; - int got_ipa_pong; -}; - -struct gsup_client *gsup_client_create(const char *unit_name, - const char *ip_addr, - unsigned int tcp_port, - gsup_client_read_cb_t read_cb, - struct oap_client_config *oapc_config); - -void gsup_client_destroy(struct gsup_client *gsupc); -int gsup_client_send(struct gsup_client *gsupc, struct msgb *msg); -struct msgb *gsup_client_msgb_alloc(void); - diff --git a/include/openbsc/gtphub.h b/include/openbsc/gtphub.h deleted file mode 100644 index 9cb7605f8..000000000 --- a/include/openbsc/gtphub.h +++ /dev/null @@ -1,523 +0,0 @@ -/* GTP Hub Implementation */ - -/* (C) 2015 by sysmocom s.f.m.c. GmbH - * All Rights Reserved - * - * Author: Neels Hofmeyr - * - * 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 . - */ - -#pragma once - -#include -#include - -#include -#include -#include - -#include - - -/* support */ - -/* TODO move to osmocom/core/socket.c ? */ -#include /* for IPPROTO_* etc */ -struct osmo_sockaddr { - struct sockaddr_storage a; - socklen_t l; -}; - -/* TODO move to osmocom/core/socket.c ? */ -/*! \brief Initialize a sockaddr - * \param[out] addr Valid osmo_sockaddr pointer to write result to - * \param[in] family Address Family like AF_INET, AF_INET6, AF_UNSPEC - * \param[in] type Socket type like SOCK_DGRAM, SOCK_STREAM - * \param[in] proto Protocol like IPPROTO_TCP, IPPROTO_UDP - * \param[in] host Remote host name or IP address in string form - * \param[in] port Remote port number in host byte order - * \returns 0 on success, otherwise an error code (from getaddrinfo()). - * - * Copy the first result from a getaddrinfo() call with the given parameters to - * *addr and *addr_len. On error, do not change *addr and return nonzero. - */ -int osmo_sockaddr_init(struct osmo_sockaddr *addr, - uint16_t family, uint16_t type, uint8_t proto, - const char *host, uint16_t port); - -/* Conveniently pass AF_UNSPEC, SOCK_DGRAM and IPPROTO_UDP to - * osmo_sockaddr_init(). */ -static inline int osmo_sockaddr_init_udp(struct osmo_sockaddr *addr, - const char *host, uint16_t port) -{ - return osmo_sockaddr_init(addr, AF_UNSPEC, SOCK_DGRAM, IPPROTO_UDP, - host, port); -} - -/*! \brief convert sockaddr to human readable string. - * \param[out] addr_str Valid pointer to a buffer of length addr_str_len. - * \param[in] addr_str_len Size of buffer addr_str points at. - * \param[out] port_str Valid pointer to a buffer of length port_str_len. - * \param[in] port_str_len Size of buffer port_str points at. - * \param[in] addr Binary representation as returned by osmo_sockaddr_init(). - * \param[in] flags flags as passed to getnameinfo(). - * \returns 0 on success, an error code on error. - * - * Return the IPv4 or IPv6 address string and the port (a.k.a. service) string - * representations of the given struct osmo_sockaddr in two caller provided - * char buffers. Flags of (NI_NUMERICHOST | NI_NUMERICSERV) return numeric - * address and port. Either one of addr_str or port_str may be NULL, in which - * case nothing is returned there. - * - * See also osmo_sockaddr_to_str() (less flexible, but much more convenient). */ -int osmo_sockaddr_to_strs(char *addr_str, size_t addr_str_len, - char *port_str, size_t port_str_len, - const struct osmo_sockaddr *addr, - int flags); - - -/*! \brief concatenate the parts returned by osmo_sockaddr_to_strs(). - * \param[in] addr Binary representation as returned by osmo_sockaddr_init(). - * \param[in] buf A buffer to use for string operations. - * \param[in] buf_len Length of the buffer. - * \returns Address string (in buffer). - * - * Compose a string of the numeric IP-address and port represented by *addr of - * the form " port ". The returned string is valid until the - * next invocation of this function. - */ -const char *osmo_sockaddr_to_strb(const struct osmo_sockaddr *addr, - char *buf, size_t buf_len); - -/*! \brief conveniently return osmo_sockaddr_to_strb() in a static buffer. - * \param[in] addr Binary representation as returned by osmo_sockaddr_init(). - * \returns Address string in static buffer. - * - * See osmo_sockaddr_to_strb(). - * - * Note: only one osmo_sockaddr_to_str() call will work per print/log - * statement. For two or more, use osmo_sockaddr_to_strb() with a separate - * buffer each. - */ -const char *osmo_sockaddr_to_str(const struct osmo_sockaddr *addr); - -/*! \brief compare two osmo_sockaddr. - * \param[in] a The first address to compare. - * \param[in] b The other address to compare. - * \returns 0 if equal, otherwise -1 or 1. - */ -int osmo_sockaddr_cmp(const struct osmo_sockaddr *a, - const struct osmo_sockaddr *b); - -/*! \brief Overwrite *dst with *src. - * Like memcpy(), but copy only the valid bytes. */ -void osmo_sockaddr_copy(struct osmo_sockaddr *dst, - const struct osmo_sockaddr *src); - - -/* general */ - -enum gtphub_plane_idx { - GTPH_PLANE_CTRL = 0, - GTPH_PLANE_USER = 1, - GTPH_PLANE_N -}; - -enum gtphub_side_idx { - GTPH_SIDE_SGSN = 0, - GTPH_SIDE_GGSN = 1, - GTPH_SIDE_N -}; - -#define for_each_side(I) for (I = 0; I < GTPH_SIDE_N; I++) -#define for_each_plane(I) for (I = 0; I < GTPH_PLANE_N; I++) -#define for_each_side_and_plane(I,J) for_each_side(I) for_each_plane(J) - -static inline int other_side_idx(int side_idx) -{ - return (side_idx + 1) & 1; -} - -extern const char* const gtphub_plane_idx_names[GTPH_PLANE_N]; -extern const uint16_t gtphub_plane_idx_default_port[GTPH_PLANE_N]; - -extern const char* const gtphub_side_idx_names[GTPH_SIDE_N]; - -/* A host address in the form that is expected in the 7.7.32 GSN Address IE. - * len is either 4 (IPv4) or 16 (IPv6), any other value is invalid. If no - * address is set, len shall be 0. */ -struct gsn_addr { - uint16_t len; - uint8_t buf[16]; -}; - -void gsn_addr_copy(struct gsn_addr *gsna, const struct gsn_addr *src); -int gsn_addr_from_str(struct gsn_addr *gsna, const char *numeric_addr_str); - -/* Return gsna in numeric string form, in a static buffer. */ -const char *gsn_addr_to_str(const struct gsn_addr *gsna); - -/* note: strbuf_len doesn't need to be larger than INET6_ADDRSTRLEN + 1. */ -const char *gsn_addr_to_strb(const struct gsn_addr *gsna, - char *strbuf, int strbuf_len); - -/* Return 1 on match, zero otherwise. */ -int gsn_addr_same(const struct gsn_addr *a, const struct gsn_addr *b); - -/* Decode sa to gsna. Return 0 on success. If port is non-NULL, the port number - * from sa is also returned. */ -int gsn_addr_from_sockaddr(struct gsn_addr *gsna, uint16_t *port, - const struct osmo_sockaddr *sa); - -/* expiry */ - -struct expiring_item; -typedef void (*del_cb_t)(struct expiring_item *); - -struct expiring_item { - struct llist_head entry; - time_t expiry; - del_cb_t del_cb; -}; - -struct expiry { - int expiry_in_seconds; - struct llist_head items; -}; - -/* Initialize an expiry queue. */ -void expiry_init(struct expiry *exq, int expiry_in_seconds); - -/* Add a new mapping, or restart the expiry timeout for an already listed - * mapping. */ -void expiry_add(struct expiry *exq, struct expiring_item *item, time_t now); - -/* Initialize to all-empty; must be called before using the item in any way. */ -void expiring_item_init(struct expiring_item *item); - -/* Remove the given item from its expiry queue, and call item->del_cb, if set. - * This sets item->del_cb to NULL and is harmless when run a second time on the - * same item, so the del_cb may choose to call this function, too, to allow - * deleting items from several code paths. */ -void expiring_item_del(struct expiring_item *item); - -/* Carry out due expiry of mappings. Must be invoked regularly. - * 'now' is the current clock count in seconds and must correspond to the clock - * count passed to nr_map_add(). A monotonous clock counter should be used. */ -int expiry_tick(struct expiry *exq, time_t now); - -/* Expire all items. */ -void expiry_clear(struct expiry *exq); - - -/* number map */ - -/* A number map assigns a "random" mapped number to each user provided number. - * If the same number is requested multiple times, the same mapped number is - * returned. - * - * Number maps plug into possibly shared pools and expiry queues, for example: - * - * mapA -----------+-> pool1 <-+-- mapB - * {10->1, 11->5} | {1, 2, 3, ...} | {10->2, 11->3} - * | | - * | | - * /-> \-> expiry1 <-/ - * | (30 seconds) - * | - * mapC -------+-----> pool2 <-+-- mapD - * {10->1, 11->3} {1, 2, 3, ...} | {10->2, 11->5} - * | - * expiry2 <-/ - * (60 seconds) - * - * A map contains mappings ("10->1"). Each map needs a number pool, which can - * be shared with other maps. Each new mapping receives a number from the pool, - * which is then unavailable to any other map using the same pool. - * - * A map may point at an expiry queue, in which case all mappings added to it - * are also appended to the expiry queue (using a separate llist entry in the - * mapping). Any number of maps may submit to the same expiry queue, if they - * desire the same expiry timeout. An expiry queue stores the mappings in - * chronological order, so that expiry checking is needed only from the start - * of the queue; hence only mappings with identical expiry timeout can be added - * to the same expiry queue. Upon expiry, a mapping is dropped from the map it - * was submitted at. expiry_tick() needs to be called regularly for each expiry - * queue. - * - * A nr_mapping can be embedded in a larger struct: each mapping can have a - * distinct destructor (del_cb), and each del_cb can figure out the container - * struct's address and free that upon expiry or manual deletion. So in expiry - * queues (and even maps), mappings of different container types can be mixed. - * This can help to drastically reduce the amount of unnecessary visits during - * expiry checking, for the case that no expiry is pending. An expiry queue - * always knows which mappings to expire next, because they are right at the - * start of its list. - * - * Mapping allocation and a del_cb are provided by the caller. If del_cb is - * NULL, no deallocation will be done (allowing statically allocated entries). - */ - -typedef unsigned int nr_t; - -/* Generator for unused numbers. So far this counts upwards from zero, but the - * implementation may change in the future. Treat this like an opaque struct. - * If this becomes random, the tests need to be fixed. */ -struct nr_pool { - nr_t last_nr; - nr_t nr_min; - nr_t nr_max; -}; - -struct nr_mapping { - struct llist_head entry; - struct expiring_item expiry_entry; - - void *origin; - nr_t orig; - nr_t repl; -}; - -struct nr_map { - struct nr_pool *pool; /* multiple nr_maps can share a nr_pool. */ - struct expiry *add_items_to_expiry; - struct llist_head mappings; -}; - - -void nr_pool_init(struct nr_pool *pool, nr_t nr_min, nr_t nr_max); - -/* Return the next unused number from the nr_pool. */ -nr_t nr_pool_next(struct nr_pool *pool); - -/* Initialize the nr_mapping to zero/empty values. */ -void nr_mapping_init(struct nr_mapping *mapping); - -/* Remove the given mapping from its parent map and expiry queue, and call - * mapping->del_cb, if set. */ -void nr_mapping_del(struct nr_mapping *mapping); - -/* Initialize an (already allocated) nr_map, and set the map's number pool. - * Multiple nr_map instances may use the same nr_pool. Set the nr_map's expiry - * queue to exq, so that all added mappings are automatically expired after the - * time configured in exq. exq may be NULL to disable automatic expiry. */ -void nr_map_init(struct nr_map *map, struct nr_pool *pool, - struct expiry *exq); - -/* Add a new entry to the map. mapping->orig, mapping->origin and - * mapping->del_cb must be set before calling this function. The remaining - * fields of *mapping will be overwritten. mapping->repl is set to the next - * available mapped number from map->pool. 'now' is the current clock count in - * seconds; if no map->expiry is used, just pass 0 for 'now'. */ -void nr_map_add(struct nr_map *map, struct nr_mapping *mapping, - time_t now); - -/* Restart the timeout for the given mapping. mapping must be a member of map. - */ -void nr_map_refresh(struct nr_map *map, struct nr_mapping *mapping, - time_t now); - -/* Return a known mapping from nr_orig and the given origin. If nr_orig is - * unknown, return NULL. */ -struct nr_mapping *nr_map_get(const struct nr_map *map, - void *origin, nr_t nr_orig); - -/* Return a known mapping to nr_repl. If nr_repl is unknown, return NULL. */ -struct nr_mapping *nr_map_get_inv(const struct nr_map *map, nr_t nr_repl); - -/* Remove all mappings from map. */ -void nr_map_clear(struct nr_map *map); - -/* Return 1 if map has no entries, 0 otherwise. */ -int nr_map_empty(const struct nr_map *map); - - -/* config */ - -static const int GTPH_EXPIRE_QUICKLY_SECS = 30; /* TODO is there a spec for this? */ -static const int GTPH_EXPIRE_SLOWLY_MINUTES = 6 * 60; /* TODO is there a spec for this? */ - -struct gtphub_cfg_addr { - const char *addr_str; - uint16_t port; -}; - -struct gtphub_cfg_bind { - struct gtphub_cfg_addr bind; -}; - -struct gtphub_cfg { - struct gtphub_cfg_bind to_gsns[GTPH_SIDE_N][GTPH_PLANE_N]; - struct gtphub_cfg_addr proxy[GTPH_SIDE_N][GTPH_PLANE_N]; - int sgsn_use_sender; /* Use sender, not GSN addr IE with std ports */ -}; - - -/* state */ - -struct gtphub_peer { - struct llist_head entry; - - struct llist_head addresses; /* Alternatives, not load balancing. */ - struct nr_pool seq_pool; - struct nr_map seq_map; -}; - -struct gtphub_peer_addr { - struct llist_head entry; - - struct gtphub_peer *peer; - struct gsn_addr addr; - struct llist_head ports; -}; - -struct gtphub_peer_port { - struct llist_head entry; - - struct gtphub_peer_addr *peer_addr; - uint16_t port; - unsigned int ref_count; /* references from other peers' seq_maps */ - struct osmo_sockaddr sa; /* a "cache" for (peer_addr->addr, port) */ - int last_restart_count; /* 0..255 = valid, all else means unknown */ - - struct rate_ctr_group *counters_io; -}; - -struct gtphub_tunnel_endpoint { - struct gtphub_peer_port *peer; - uint32_t tei_orig; /* from/to peer */ - - struct rate_ctr_group *counters_io; -}; - -struct gtphub_tunnel { - struct llist_head entry; - struct expiring_item expiry_entry; - - uint32_t tei_repl; /* unique TEI to replace peers' TEIs */ - struct gtphub_tunnel_endpoint endpoint[GTPH_SIDE_N][GTPH_PLANE_N]; -}; - -struct gtphub_bind { - struct gsn_addr local_addr; - uint16_t local_port; - struct osmo_fd ofd; - - /* list of struct gtphub_peer */ - struct llist_head peers; - - const char *label; /* For logging */ - struct rate_ctr_group *counters_io; -}; - -struct gtphub_resolved_ggsn { - struct llist_head entry; - struct expiring_item expiry_entry; - - /* The APN OI, the Operator Identifier, is the combined address, - * including parts of the IMSI and APN NI, and ending with ".gprs". */ - char apn_oi_str[GSM_APN_LENGTH]; - - /* Which address and port we resolved that to. */ - struct gtphub_peer_port *peer; -}; - -struct gtphub { - struct gtphub_bind to_gsns[GTPH_SIDE_N][GTPH_PLANE_N]; - - /* pointers to an entry of to_gsns[s][p].peers */ - struct gtphub_peer_port *proxy[GTPH_SIDE_N][GTPH_PLANE_N]; - - /* The TEI numbers will simply wrap and be reused, which will work out - * in practice. Problems would arise if one given peer maintained the - * same TEI for a time long enough for the TEI nr map to wrap an entire - * uint32_t; if a new TEI were mapped every second, this would take - * more than 100 years (in which a single given TEI must not time out) - * to cause a problem. */ - struct nr_pool tei_pool; - - struct llist_head tunnels; /* struct gtphub_tunnel */ - struct llist_head pending_deletes; /* opaque (gtphub.c) */ - - struct llist_head ggsn_lookups; /* opaque (gtphub_ares.c) */ - struct llist_head resolved_ggsns; /* struct gtphub_resolved_ggsn */ - - struct osmo_timer_list gc_timer; - struct expiry expire_quickly; - struct expiry expire_slowly; - - uint8_t restart_counter; - - int sgsn_use_sender; -}; - -struct gtp_packet_desc; - - -/* api */ - -int gtphub_vty_init(struct gtphub *global_hub, struct gtphub_cfg *global_cfg); -int gtphub_cfg_read(struct gtphub_cfg *cfg, const char *config_file); - -/* Initialize and start gtphub: bind to ports, run expiry timers. */ -int gtphub_start(struct gtphub *hub, struct gtphub_cfg *cfg, - uint8_t restart_counter); - -/* Close all sockets, expire all maps and peers and free all allocations. The - * struct is then unusable, unless gtphub_start() is run on it again. */ -void gtphub_stop(struct gtphub *hub); - -time_t gtphub_now(void); - -/* Remove expired items, empty peers, ... */ -void gtphub_gc(struct gtphub *hub, time_t now); - -/* Return the string of the first address for this peer. */ -const char *gtphub_peer_str(struct gtphub_peer *peer); - -/* Return a human readable description of tun in a static buffer. */ -const char *gtphub_tunnel_str(struct gtphub_tunnel *tun); - -/* Return 1 if all of tun's endpoints are fully established, 0 otherwise. */ -int gtphub_tunnel_complete(struct gtphub_tunnel *tun); - -int gtphub_handle_buf(struct gtphub *hub, - unsigned int side_idx, - unsigned int port_idx, - const struct osmo_sockaddr *from_addr, - uint8_t *buf, - size_t received, - time_t now, - uint8_t **reply_buf, - struct osmo_fd **to_ofd, - struct osmo_sockaddr *to_addr); - -struct gtphub_peer_port *gtphub_port_have(struct gtphub *hub, - struct gtphub_bind *bind, - const struct gsn_addr *addr, - uint16_t port); - -struct gtphub_peer_port *gtphub_port_find_sa(const struct gtphub_bind *bind, - const struct osmo_sockaddr *addr); - -void gtphub_resolved_ggsn(struct gtphub *hub, const char *apn_oi_str, - struct gsn_addr *resolved_addr, - time_t now); - -const char *gtphub_port_str(struct gtphub_peer_port *port); - -int gtphub_write(const struct osmo_fd *to, - const struct osmo_sockaddr *to_addr, - const uint8_t *buf, size_t buf_len); diff --git a/include/openbsc/oap_client.h b/include/openbsc/oap_client.h deleted file mode 100644 index 80c86d5d6..000000000 --- a/include/openbsc/oap_client.h +++ /dev/null @@ -1,82 +0,0 @@ -/* Osmocom Authentication Protocol API */ - -/* (C) 2015 by Sysmocom s.f.m.c. GmbH - * All Rights Reserved - * - * Author: Neels Hofmeyr - * - * 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 . - * - */ - -#pragma once - -#include - -struct msgb; -struct osmo_oap_message; - -/* This is the config part for vty. It is essentially copied in - * oap_client_state, where values are copied over once the config is - * considered valid. */ -struct oap_client_config { - uint16_t client_id; - int secret_k_present; - uint8_t secret_k[16]; - int secret_opc_present; - uint8_t secret_opc[16]; -}; - -/* The runtime state of the OAP client. client_id and the secrets are in fact - * duplicated from oap_client_config, so that a separate validation of the - * config data is possible, and so that only a struct oap_client_state* is - * passed around. */ -struct oap_client_state { - enum { - OAP_UNINITIALIZED = 0, /* just allocated. */ - OAP_DISABLED, /* disabled by config. */ - OAP_INITIALIZED, /* enabled, config is valid. */ - OAP_REQUESTED_CHALLENGE, - OAP_SENT_CHALLENGE_RESULT, - OAP_REGISTERED - } state; - uint16_t client_id; - uint8_t secret_k[16]; - uint8_t secret_opc[16]; - int registration_failures; -}; - -/* From config, initialize state. Return 0 on success. */ -int oap_client_init(struct oap_client_config *config, - struct oap_client_state *state); - -/* Construct an OAP registration message and return in *msg_tx. Use - * state->client_id and update state->state. - * Return 0 on success, or a negative value on error. - * If an error is returned, *msg_tx is guaranteed to be NULL. */ -int oap_client_register(struct oap_client_state *state, struct msgb **msg_tx); - -/* Decode and act on a received OAP message msg_rx. Update state->state. If a - * non-NULL pointer is returned in *msg_tx, that msgb should be sent to the OAP - * server (and freed) by the caller. The received msg_rx is not freed. - * Return 0 on success, or a negative value on error. - * If an error is returned, *msg_tx is guaranteed to be NULL. */ -int oap_client_handle(struct oap_client_state *state, - const struct msgb *msg_rx, struct msgb **msg_tx); - -/* Allocate a msgb and in it, return the encoded oap_client_msg. Return - * NULL on error. (Like oap_client_encode(), but also allocates a msgb.) - * About the name: the idea is do_something(oap_client_encoded(my_struct)) - */ -struct msgb *oap_client_encoded(const struct osmo_oap_message *oap_client_msg); diff --git a/include/openbsc/rest_octets.h b/include/openbsc/rest_octets.h deleted file mode 100644 index 49a231296..000000000 --- a/include/openbsc/rest_octets.h +++ /dev/null @@ -1,139 +0,0 @@ -#ifndef _REST_OCTETS_H -#define _REST_OCTETS_H - -#include -#include -#include - -/* generate SI1 rest octets */ -int rest_octets_si1(uint8_t *data, uint8_t *nch_pos, int is1800_net); -int rest_octets_si2quater(uint8_t *data, struct gsm_bts *bts); -int rest_octets_si6(uint8_t *data, bool is1800_net); - -struct gsm48_si_selection_params { - uint16_t penalty_time:5, - temp_offs:3, - cell_resel_off:6, - cbq:1, - present:1; -}; - -struct gsm48_si_power_offset { - uint8_t power_offset:2, - present:1; -}; - -struct gsm48_si3_gprs_ind { - uint8_t si13_position:1, - ra_colour:3, - present:1; -}; - -struct gsm48_lsa_params { - uint32_t prio_thr:3, - lsa_offset:3, - mcc:12, - mnc:12; - unsigned int present; -}; - -struct gsm48_si_ro_info { - struct gsm48_si_selection_params selection_params; - struct gsm48_si_power_offset power_offset; - uint8_t si2ter_indicator; - uint8_t early_cm_ctrl; - struct { - uint8_t where:3, - present:1; - } scheduling; - struct gsm48_si3_gprs_ind gprs_ind; - /* SI 3 specific */ - uint8_t si2quater_indicator; - /* SI 4 specific */ - struct gsm48_lsa_params lsa_params; - uint16_t cell_id; - uint8_t break_ind; /* do we have SI7 + SI8 ? */ -}; - - -/* Generate SI3 Rest Octests (Chapter 10.5.2.34 / Table 10.4.72) */ -int rest_octets_si3(uint8_t *data, const struct gsm48_si_ro_info *si3); - -/* Generate SI4 Rest Octets (Chapter 10.5.2.35) */ -int rest_octets_si4(uint8_t *data, const struct gsm48_si_ro_info *si4, int len); - -enum pbcch_carrier_type { - PBCCH_BCCH, - PBCCH_ARFCN, - PBCCH_MAIO -}; - -/* TS 03.60 Chapter 6.3.3.1: Network Mode of Operation */ -enum gprs_nmo { - GPRS_NMO_I = 0, /* CS pagin on GPRS paging or traffic channel */ - GPRS_NMO_II = 1, /* all paging on CCCH */ - GPRS_NMO_III = 2, /* no paging coordination */ -}; - -/* TS 04.60 12.24 */ -struct gprs_cell_options { - enum gprs_nmo nmo; - /* T3168: wait for packet uplink assignment message */ - uint32_t t3168; /* in milliseconds */ - /* T3192: wait for release of the TBF after reception of the final block */ - uint32_t t3192; /* in milliseconds */ - uint32_t drx_timer_max;/* in seconds */ - uint32_t bs_cv_max; - uint8_t supports_egprs_11bit_rach; - bool ctrl_ack_type_use_block; /* use PACKET CONTROL ACKNOWLEDGMENT */ - - uint8_t ext_info_present; - struct { - uint8_t egprs_supported; - uint8_t use_egprs_p_ch_req; - uint8_t bep_period; - uint8_t pfc_supported; - uint8_t dtm_supported; - uint8_t bss_paging_coordination; - } ext_info; -}; - -/* TS 04.60 Table 12.9.2 */ -struct gprs_power_ctrl_pars { - uint8_t alpha; - uint8_t t_avg_w; - uint8_t t_avg_t; - uint8_t pc_meas_chan; - uint8_t n_avg_i; -}; - -struct gsm48_si13_info { - struct gprs_cell_options cell_opts; - struct gprs_power_ctrl_pars pwr_ctrl_pars; - uint8_t bcch_change_mark; - uint8_t si_change_field; - uint8_t pbcch_present; - - union { - struct { - uint8_t rac; - uint8_t spgc_ccch_sup; - uint8_t net_ctrl_ord; - uint8_t prio_acc_thr; - } no_pbcch; - struct { - uint8_t psi1_rep_per; - uint8_t pb; - uint8_t tsc; - uint8_t tn; - enum pbcch_carrier_type carrier_type; - uint16_t arfcn; - uint8_t maio; - } pbcch; - }; -}; - -/* Generate SI13 Rest Octests (Chapter 10.5.2.37b) */ -int rest_octets_si13(uint8_t *data, const struct gsm48_si13_info *si13); - -#endif /* _REST_OCTETS_H */ diff --git a/include/openbsc/sgsn.h b/include/openbsc/sgsn.h deleted file mode 100644 index f371dc695..000000000 --- a/include/openbsc/sgsn.h +++ /dev/null @@ -1,191 +0,0 @@ -#ifndef _SGSN_H -#define _SGSN_H - - -#include -#include -#include -#include -#include -#include - -#include - -struct gprs_gsup_client; -struct hostent; - -enum sgsn_auth_policy { - SGSN_AUTH_POLICY_OPEN, - SGSN_AUTH_POLICY_CLOSED, - SGSN_AUTH_POLICY_ACL_ONLY, - SGSN_AUTH_POLICY_REMOTE -}; - - -enum sgsn_rate_ctr_keys { - CTR_LLC_DL_BYTES, - CTR_LLC_UL_BYTES, - CTR_LLC_DL_PACKETS, - CTR_LLC_UL_PACKETS, - CTR_GPRS_ATTACH_REQUEST, - CTR_GPRS_ATTACH_ACKED, - CTR_GPRS_ATTACH_REJECTED, - CTR_GPRS_DETACH_REQUEST, - CTR_GPRS_DETACH_ACKED, - CTR_GPRS_ROUTING_AREA_REQUEST, - CTR_GPRS_ROUTING_AREA_ACKED, - CTR_GPRS_ROUTING_AREA_REJECT, - /* PDP single packet counter / GSM 04.08 9.5.1 - 9.5.9 */ - CTR_PDP_ACTIVATE_REQUEST, - CTR_PDP_ACTIVATE_REJECT, - CTR_PDP_ACTIVATE_ACCEPT, - CTR_PDP_REQUEST_ACTIVATE, /* unused */ - CTR_PDP_REQUEST_ACTIVATE_REJ, /* unused */ - CTR_PDP_MODIFY_REQUEST, /* unsued */ - CTR_PDP_MODIFY_ACCEPT, /* unused */ - CTR_PDP_DL_DEACTIVATE_REQUEST, - CTR_PDP_DL_DEACTIVATE_ACCEPT, - CTR_PDP_UL_DEACTIVATE_REQUEST, - CTR_PDP_UL_DEACTIVATE_ACCEPT, -}; - -struct sgsn_cdr { - char *filename; - int interval; -}; - -struct sgsn_config { - /* parsed from config file */ - - char *gtp_statedir; - struct sockaddr_in gtp_listenaddr; - - /* misc */ - struct gprs_ns_inst *nsi; - - enum sgsn_auth_policy auth_policy; - enum gprs_ciph_algo cipher; - struct llist_head imsi_acl; - - struct sockaddr_in gsup_server_addr; - int gsup_server_port; - - int require_authentication; - int require_update_location; - - /* CDR configuration */ - struct sgsn_cdr cdr; - - struct { - int T3312; - int T3322; - int T3350; - int T3360; - int T3370; - int T3313; - int T3314; - int T3316; - int T3385; - int T3386; - int T3395; - int T3397; - } timers; - - int dynamic_lookup; - - struct oap_client_config oap; - - /* RFC1144 TCP/IP header compression */ - struct { - int active; - int passive; - int s01; - } pcomp_rfc1144; - - /* V.42vis data compression */ - struct { - int active; - int passive; - int p0; - int p1; - int p2; - } dcomp_v42bis; - - struct { - int rab_assign_addr_enc; - } iu; -}; - -struct sgsn_instance { - char *config_file; - struct sgsn_config cfg; - /* File descriptor wrappers for LibGTP */ - struct osmo_fd gtp_fd0; - struct osmo_fd gtp_fd1c; - struct osmo_fd gtp_fd1u; - /* Timer for libGTP */ - struct osmo_timer_list gtp_timer; - /* GSN instance for libgtp */ - struct gsn_t *gsn; - /* Subscriber */ - struct gsup_client *gsup_client; - /* LLME inactivity timer */ - struct osmo_timer_list llme_timer; - - /* c-ares event loop integration */ - struct osmo_timer_list ares_timer; - struct llist_head ares_fds; - ares_channel ares_channel; - struct ares_addr_node *ares_servers; - - struct rate_ctr_group *rate_ctrs; -}; - -extern struct sgsn_instance *sgsn; - -/* sgsn_vty.c */ - -int sgsn_vty_init(struct sgsn_config *cfg); -int sgsn_parse_config(const char *config_file); - -/* sgsn.c */ - -/* Main input function for Gb proxy */ -int sgsn_rcvmsg(struct msgb *msg, struct gprs_nsvc *nsvc, uint16_t ns_bvci); - - -struct sgsn_pdp_ctx *sgsn_create_pdp_ctx(struct sgsn_ggsn_ctx *ggsn, - struct sgsn_mm_ctx *mmctx, - uint16_t nsapi, - struct tlv_parsed *tp); -int sgsn_delete_pdp_ctx(struct sgsn_pdp_ctx *pctx); -void sgsn_pdp_upd_gtp_u(struct sgsn_pdp_ctx *pdp, void *addr, size_t alen); - -/* gprs_sndcp.c */ - -/* Entry point for the SNSM-ACTIVATE.indication */ -int sndcp_sm_activate_ind(struct gprs_llc_lle *lle, uint8_t nsapi); -/* Entry point for the SNSM-DEACTIVATE.indication */ -int sndcp_sm_deactivate_ind(struct gprs_llc_lle *lle, uint8_t nsapi); -/* Called by SNDCP when it has received/re-assembled a N-PDU */ -int sgsn_rx_sndcp_ud_ind(struct gprs_ra_id *ra_id, int32_t tlli, uint8_t nsapi, - struct msgb *msg, uint32_t npdu_len, uint8_t *npdu); -int sndcp_unitdata_req(struct msgb *msg, struct gprs_llc_lle *lle, uint8_t nsapi, - void *mmcontext); -int sndcp_llunitdata_ind(struct msgb *msg, struct gprs_llc_lle *lle, - uint8_t *hdr, uint16_t len); - - -/* - * CDR related functionality - */ -int sgsn_cdr_init(struct sgsn_instance *sgsn); - - -/* - * C-ARES related functionality - */ -int sgsn_ares_init(struct sgsn_instance *sgsn); -int sgsn_ares_query(struct sgsn_instance *sgsm, const char *name, ares_host_callback cb, void *data); - -#endif diff --git a/include/openbsc/signal.h b/include/openbsc/signal.h deleted file mode 100644 index 4b6ba56f6..000000000 --- a/include/openbsc/signal.h +++ /dev/null @@ -1,52 +0,0 @@ -/* Generic signalling/notification infrastructure */ -/* (C) 2009-2010, 2015 by Holger Hans Peter Freyther - * (C) 2009 by Harald Welte - * (C) 2010 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 . - * - */ - -#ifndef OPENBSC_SIGNAL_H -#define OPENBSC_SIGNAL_H - -#include -#include - -#include - -enum signal_subsystems { - SS_SGSN, -}; - -/* GPRS SGSN signals SS_SGSN */ -enum signal_sgsn { - S_SGSN_ATTACH, - S_SGSN_DETACH, - S_SGSN_UPDATE, - S_SGSN_PDP_ACT, - S_SGSN_PDP_DEACT, - S_SGSN_PDP_TERMINATE, - S_SGSN_PDP_FREE, - S_SGSN_MM_FREE, -}; - -struct sgsn_mm_ctx; -struct sgsn_signal_data { - struct sgsn_mm_ctx *mm; - struct sgsn_pdp_ctx *pdp; /* non-NULL for PDP_ACT, PDP_DEACT, PDP_FREE */ -}; - -#endif diff --git a/include/openbsc/slhc.h b/include/openbsc/slhc.h deleted file mode 100644 index cd5a47cf4..000000000 --- a/include/openbsc/slhc.h +++ /dev/null @@ -1,187 +0,0 @@ -#ifndef _SLHC_H -#define _SLHC_H -/* - * Definitions for tcp compression routines. - * - * $Header: slcompress.h,v 1.10 89/12/31 08:53:02 van Exp $ - * - * Copyright (c) 1989 Regents of the University of California. - * All rights reserved. - * - * Redistribution and use in source and binary forms are permitted - * provided that the above copyright notice and this paragraph are - * duplicated in all such forms and that any documentation, - * advertising materials, and other materials related to such - * distribution and use acknowledge that the software was developed - * by the University of California, Berkeley. The name of the - * University may not be used to endorse or promote products derived - * from this software without specific prior written permission. - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. - * - * Van Jacobson (van@helios.ee.lbl.gov), Dec 31, 1989: - * - Initial distribution. - * - * - * modified for KA9Q Internet Software Package by - * Katie Stevens (dkstevens@ucdavis.edu) - * University of California, Davis - * Computing Services - * - 01-31-90 initial adaptation - * - * - Feb 1991 Bill_Simpson@um.cc.umich.edu - * variable number of conversation slots - * allow zero or one slots - * separate routines - * status display - */ - -/* - * Compressed packet format: - * - * The first octet contains the packet type (top 3 bits), TCP - * 'push' bit, and flags that indicate which of the 4 TCP sequence - * numbers have changed (bottom 5 bits). The next octet is a - * conversation number that associates a saved IP/TCP header with - * the compressed packet. The next two octets are the TCP checksum - * from the original datagram. The next 0 to 15 octets are - * sequence number changes, one change per bit set in the header - * (there may be no changes and there are two special cases where - * the receiver implicitly knows what changed -- see below). - * - * There are 5 numbers which can change (they are always inserted - * in the following order): TCP urgent pointer, window, - * acknowledgment, sequence number and IP ID. (The urgent pointer - * is different from the others in that its value is sent, not the - * change in value.) Since typical use of SLIP links is biased - * toward small packets (see comments on MTU/MSS below), changes - * use a variable length coding with one octet for numbers in the - * range 1 - 255 and 3 octets (0, MSB, LSB) for numbers in the - * range 256 - 65535 or 0. (If the change in sequence number or - * ack is more than 65535, an uncompressed packet is sent.) - */ - -/* - * Packet types (must not conflict with IP protocol version) - * - * The top nibble of the first octet is the packet type. There are - * three possible types: IP (not proto TCP or tcp with one of the - * control flags set); uncompressed TCP (a normal IP/TCP packet but - * with the 8-bit protocol field replaced by an 8-bit connection id -- - * this type of packet syncs the sender & receiver); and compressed - * TCP (described above). - * - * LSB of 4-bit field is TCP "PUSH" bit (a worthless anachronism) and - * is logically part of the 4-bit "changes" field that follows. Top - * three bits are actual packet type. For backward compatibility - * and in the interest of conserving bits, numbers are chosen so the - * IP protocol version number (4) which normally appears in this nibble - * means "IP packet". - */ - - -#include -#include - -/* SLIP compression masks for len/vers byte */ -#define SL_TYPE_IP 0x40 -#define SL_TYPE_UNCOMPRESSED_TCP 0x70 -#define SL_TYPE_COMPRESSED_TCP 0x80 -#define SL_TYPE_ERROR 0x00 - -/* Bits in first octet of compressed packet */ -#define NEW_C 0x40 /* flag bits for what changed in a packet */ -#define NEW_I 0x20 -#define NEW_S 0x08 -#define NEW_A 0x04 -#define NEW_W 0x02 -#define NEW_U 0x01 - -/* reserved, special-case values of above */ -#define SPECIAL_I (NEW_S|NEW_W|NEW_U) /* echoed interactive traffic */ -#define SPECIAL_D (NEW_S|NEW_A|NEW_W|NEW_U) /* unidirectional data */ -#define SPECIALS_MASK (NEW_S|NEW_A|NEW_W|NEW_U) - -#define TCP_PUSH_BIT 0x10 - -/* - * data type and sizes conversion assumptions: - * - * VJ code KA9Q style generic - * u_char byte_t unsigned char 8 bits - * u_short int16 unsigned short 16 bits - * u_int int16 unsigned short 16 bits - * u_long unsigned long unsigned long 32 bits - * int int32 long 32 bits - */ - -typedef __u8 byte_t; -typedef __u32 int32; - -/* - * "state" data for each active tcp conversation on the wire. This is - * basically a copy of the entire IP/TCP header from the last packet - * we saw from the conversation together with a small identifier - * the transmit & receive ends of the line use to locate saved header. - */ -struct cstate { - byte_t cs_this; /* connection id number (xmit) */ - struct cstate *next; /* next in ring (xmit) */ - struct iphdr cs_ip; /* ip/tcp hdr from most recent packet */ - struct tcphdr cs_tcp; - unsigned char cs_ipopt[64]; - unsigned char cs_tcpopt[64]; - int cs_hsize; -}; -#define NULLSLSTATE (struct cstate *)0 - -/* - * all the state data for one serial line (we need one of these per line). - */ -struct slcompress { - struct cstate *tstate; /* transmit connection states (array)*/ - struct cstate *rstate; /* receive connection states (array)*/ - - byte_t tslot_limit; /* highest transmit slot id (0-l)*/ - byte_t rslot_limit; /* highest receive slot id (0-l)*/ - - byte_t xmit_oldest; /* oldest xmit in ring */ - byte_t xmit_current; /* most recent xmit id */ - byte_t recv_current; /* most recent rcvd id */ - - byte_t flags; -#define SLF_TOSS 0x01 /* tossing rcvd frames until id received */ - - int32 sls_o_nontcp; /* outbound non-TCP packets */ - int32 sls_o_tcp; /* outbound TCP packets */ - int32 sls_o_uncompressed; /* outbound uncompressed packets */ - int32 sls_o_compressed; /* outbound compressed packets */ - int32 sls_o_searches; /* searches for connection state */ - int32 sls_o_misses; /* times couldn't find conn. state */ - - int32 sls_i_uncompressed; /* inbound uncompressed packets */ - int32 sls_i_compressed; /* inbound compressed packets */ - int32 sls_i_error; /* inbound error packets */ - int32 sls_i_tossed; /* inbound packets tossed because of error */ - - int32 sls_i_runt; - int32 sls_i_badcheck; -}; -#define NULLSLCOMPR (struct slcompress *)0 - -/* In slhc.c: */ -struct slcompress *slhc_init(const void *ctx, int rslots, int tslots); - -void slhc_free(struct slcompress *comp); - -int slhc_compress(struct slcompress *comp, unsigned char *icp, int isize, - unsigned char *ocp, unsigned char **cpp, int compress_cid); -int slhc_uncompress(struct slcompress *comp, unsigned char *icp, int isize); -int slhc_remember(struct slcompress *comp, unsigned char *icp, int isize); -int slhc_toss(struct slcompress *comp); - -void slhc_i_status(struct slcompress *comp); -void slhc_o_status(struct slcompress *comp); - -#endif /* _SLHC_H */ diff --git a/include/openbsc/v42bis.h b/include/openbsc/v42bis.h deleted file mode 100644 index 607a58e51..000000000 --- a/include/openbsc/v42bis.h +++ /dev/null @@ -1,147 +0,0 @@ -/* - * SpanDSP - a series of DSP components for telephony - * - * v42bis.h - * - * Written by Steve Underwood - * - * Copyright (C) 2005, 2011 Steve Underwood - * - * All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License version 2.1, - * as published by the Free Software Foundation. - * - * 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 Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -/*! \page v42bis_page V.42bis modem data compression -\section v42bis_page_sec_1 What does it do? -The v.42bis specification defines a data compression scheme, to work in -conjunction with the error correction scheme defined in V.42. - -\section v42bis_page_sec_2 How does it work? -*/ - -#include - -#if !defined(_SPANDSP_V42BIS_H_) -#define _SPANDSP_V42BIS_H_ - -#define SPAN_DECLARE(x) x - -#define V42BIS_MIN_STRING_SIZE 6 -#define V42BIS_MAX_STRING_SIZE 250 -#define V42BIS_MIN_DICTIONARY_SIZE 512 -#define V42BIS_MAX_BITS 12 -#define V42BIS_MAX_CODEWORDS 4096 /* 2^V42BIS_MAX_BITS */ -#define V42BIS_MAX_OUTPUT_LENGTH 1024 - -enum -{ - V42BIS_P0_NEITHER_DIRECTION = 0, - V42BIS_P0_INITIATOR_RESPONDER, - V42BIS_P0_RESPONDER_INITIATOR, - V42BIS_P0_BOTH_DIRECTIONS -}; - -enum -{ - V42BIS_COMPRESSION_MODE_DYNAMIC = 0, - V42BIS_COMPRESSION_MODE_ALWAYS, - V42BIS_COMPRESSION_MODE_NEVER -}; - -typedef void (*put_msg_func_t)(void *user_data, const uint8_t *msg, int len); - -/*! - V.42bis compression/decompression descriptor. This defines the working state for a - single instance of V.42bis compress/decompression. -*/ -typedef struct v42bis_state_s v42bis_state_t; - -#if defined(__cplusplus) -extern "C" -{ -#endif - -/*! Compress a block of octets. - \param s The V.42bis context. - \param buf The data to be compressed. - \param len The length of the data buffer. - \return 0 */ -SPAN_DECLARE(int) v42bis_compress(v42bis_state_t *s, const uint8_t buf[], int len); - -/*! Flush out any data remaining in a compression buffer. - \param s The V.42bis context. - \return 0 */ -SPAN_DECLARE(int) v42bis_compress_flush(v42bis_state_t *s); - -/*! Decompress a block of octets. - \param s The V.42bis context. - \param buf The data to be decompressed. - \param len The length of the data buffer. - \return 0 */ -SPAN_DECLARE(int) v42bis_decompress(v42bis_state_t *s, const uint8_t buf[], int len); - -/*! Flush out any data remaining in the decompression buffer. - \param s The V.42bis context. - \return 0 */ -SPAN_DECLARE(int) v42bis_decompress_flush(v42bis_state_t *s); - -/*! Set the compression mode. - \param s The V.42bis context. - \param mode One of the V.42bis compression modes - - V42BIS_COMPRESSION_MODE_DYNAMIC, - V42BIS_COMPRESSION_MODE_ALWAYS, - V42BIS_COMPRESSION_MODE_NEVER */ -SPAN_DECLARE(void) v42bis_compression_control(v42bis_state_t *s, int mode); - -/*! Initialise a V.42bis context. - \param s The V.42bis context. - \param negotiated_p0 The negotiated P0 parameter, from the V.42bis spec. - \param negotiated_p1 The negotiated P1 parameter, from the V.42bis spec. - \param negotiated_p2 The negotiated P2 parameter, from the V.42bis spec. - \param encode_handler Encode callback handler. - \param encode_user_data An opaque pointer passed to the encode callback handler. - \param max_encode_len The maximum length that should be passed to the encode handler. - \param decode_handler Decode callback handler. - \param decode_user_data An opaque pointer passed to the decode callback handler. - \param max_decode_len The maximum length that should be passed to the decode handler. - \return The V.42bis context. */ -SPAN_DECLARE(v42bis_state_t *) v42bis_init(const void *ctx, - v42bis_state_t *s, - int negotiated_p0, - int negotiated_p1, - int negotiated_p2, - put_msg_func_t encode_handler, - void *encode_user_data, - int max_encode_len, - put_msg_func_t decode_handler, - void *decode_user_data, - int max_decode_len); - -/*! Release a V.42bis context. - \param s The V.42bis context. - \return 0 if OK */ -SPAN_DECLARE(int) v42bis_release(v42bis_state_t *s); - -/*! Free a V.42bis context. - \param s The V.42bis context. - \return 0 if OK */ -SPAN_DECLARE(int) v42bis_free(v42bis_state_t *s); - -#if defined(__cplusplus) -} -#endif - -#endif -/*- End of file ------------------------------------------------------------*/ diff --git a/include/openbsc/v42bis_private.h b/include/openbsc/v42bis_private.h deleted file mode 100644 index daa5ea315..000000000 --- a/include/openbsc/v42bis_private.h +++ /dev/null @@ -1,126 +0,0 @@ -/* - * SpanDSP - a series of DSP components for telephony - * - * private/v42bis.h - * - * Written by Steve Underwood - * - * Copyright (C) 2005 Steve Underwood - * - * All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License version 2.1, - * as published by the Free Software Foundation. - * - * 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 Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -#if !defined(_SPANDSP_PRIVATE_V42BIS_H_) -#define _SPANDSP_PRIVATE_V42BIS_H_ - -/*! - V.42bis dictionary node. - Note that 0 is not a valid node to point to (0 is always a control code), so 0 is used - as a "no such value" marker in this structure. -*/ -typedef struct -{ - /*! \brief The value of the octet represented by the current dictionary node */ - uint8_t node_octet; - /*! \brief The parent of this node */ - uint16_t parent; - /*! \brief The first child of this node */ - uint16_t child; - /*! \brief The next node at the same depth */ - uint16_t next; -} v42bis_dict_node_t; - -/*! - V.42bis compression or decompression. This defines the working state for a single instance - of V.42bis compression or decompression. -*/ -typedef struct -{ - /*! \brief Compression enabled. */ - int v42bis_parm_p0; - /*! \brief Compression mode. */ - int compression_mode; - /*! \brief Callback function to handle output data. */ - put_msg_func_t handler; - /*! \brief An opaque pointer passed in calls to the data handler. */ - void *user_data; - /*! \brief The maximum amount to be passed to the data handler. */ - int max_output_len; - - /*! \brief TRUE if we are in transparent (i.e. uncompressable) mode */ - int transparent; - /*! \brief Next empty dictionary entry */ - uint16_t v42bis_parm_c1; - /*! \brief Current codeword size */ - uint16_t v42bis_parm_c2; - /*! \brief Threshold for codeword size change */ - uint16_t v42bis_parm_c3; - /*! \brief The current update point in the dictionary */ - uint16_t update_at; - /*! \brief The last entry matched in the dictionary */ - uint16_t last_matched; - /*! \brief The last entry added to the dictionary */ - uint16_t last_added; - /*! \brief Total number of codewords in the dictionary */ - int v42bis_parm_n2; - /*! \brief Maximum permitted string length */ - int v42bis_parm_n7; - /*! \brief The dictionary */ - v42bis_dict_node_t dict[V42BIS_MAX_CODEWORDS]; - - /*! \brief The octet string in progress */ - uint8_t string[V42BIS_MAX_STRING_SIZE]; - /*! \brief The current length of the octet string in progress */ - int string_length; - /*! \brief The amount of the octet string in progress which has already - been flushed out of the buffer */ - int flushed_length; - - /*! \brief Compression performance metric */ - uint16_t compression_performance; - - /*! \brief Outgoing bit buffer (compression), or incoming bit buffer (decompression) */ - uint32_t bit_buffer; - /*! \brief Outgoing bit count (compression), or incoming bit count (decompression) */ - int bit_count; - - /*! \brief The output composition buffer */ - uint8_t output_buf[V42BIS_MAX_OUTPUT_LENGTH]; - /*! \brief The length of the contents of the output composition buffer */ - int output_octet_count; - - /*! \brief The current value of the escape code */ - uint8_t escape_code; - /*! \brief TRUE if we just hit an escape code, and are waiting for the following octet */ - int escaped; -} v42bis_comp_state_t; - -/*! - V.42bis compression/decompression descriptor. This defines the working state for a - single instance of V.42bis compress/decompression. -*/ -struct v42bis_state_s -{ - /*! \brief Compression state. */ - v42bis_comp_state_t compress; - /*! \brief Decompression state. */ - v42bis_comp_state_t decompress; - - /*! \brief Error and flow logging control */ -}; - -#endif -/*- End of file ------------------------------------------------------------*/ diff --git a/include/openbsc/vty.h b/include/openbsc/vty.h deleted file mode 100644 index d2e3d9a73..000000000 --- a/include/openbsc/vty.h +++ /dev/null @@ -1,9 +0,0 @@ -#pragma once - -#include - -enum bsc_vty_node { - GBPROXY_NODE = _LAST_OSMOVTY_NODE + 1, - SGSN_NODE, - GTPHUB_NODE, -}; diff --git a/include/osmocom/Makefile.am b/include/osmocom/Makefile.am new file mode 100644 index 000000000..09db97a95 --- /dev/null +++ b/include/osmocom/Makefile.am @@ -0,0 +1,3 @@ +SUBDIRS = \ + sgsn \ + $(NULL) diff --git a/include/osmocom/sgsn/Makefile.am b/include/osmocom/sgsn/Makefile.am new file mode 100644 index 000000000..150212971 --- /dev/null +++ b/include/osmocom/sgsn/Makefile.am @@ -0,0 +1,28 @@ +noinst_HEADERS = \ + common.h \ + crc24.h \ + debug.h \ + gb_proxy.h \ + gprs_gb_parse.h \ + gprs_gmm.h \ + gprs_llc.h \ + gprs_llc_xid.h \ + gprs_sgsn.h \ + gprs_sndcp_comp.h \ + gprs_sndcp_dcomp.h \ + gprs_sndcp.h \ + gprs_sndcp_pcomp.h \ + gprs_sndcp_xid.h \ + gprs_subscriber.h \ + gprs_utils.h \ + gsup_client.h \ + gtphub.h \ + oap_client.h \ + rest_octets.h \ + sgsn.h \ + signal.h \ + slhc.h \ + v42bis.h \ + v42bis_private.h \ + vty.h \ + $(NULL) diff --git a/include/osmocom/sgsn/common.h b/include/osmocom/sgsn/common.h new file mode 100644 index 000000000..d91b3d39e --- /dev/null +++ b/include/osmocom/sgsn/common.h @@ -0,0 +1,6 @@ +#pragma once + +enum nsap_addr_enc { + NSAP_ADDR_ENC_X213, + NSAP_ADDR_ENC_V4RAW, +}; diff --git a/include/osmocom/sgsn/crc24.h b/include/osmocom/sgsn/crc24.h new file mode 100644 index 000000000..756638c03 --- /dev/null +++ b/include/osmocom/sgsn/crc24.h @@ -0,0 +1,10 @@ +#ifndef _CRC24_H +#define _CRC24_H + +#include + +#define INIT_CRC24 0xffffff + +uint32_t crc24_calc(uint32_t fcs, uint8_t *cp, unsigned int len); + +#endif diff --git a/include/osmocom/sgsn/debug.h b/include/osmocom/sgsn/debug.h new file mode 100644 index 000000000..65e197d52 --- /dev/null +++ b/include/osmocom/sgsn/debug.h @@ -0,0 +1,47 @@ +#pragma once + +#include +#include + +#define DEBUG +#include + +/* Debug Areas of the code */ +enum { + DRLL, + DCC, + DMM, + DRR, + DRSL, + DNM, + DMNCC, + DPAG, + DMEAS, + DSCCP, + DMSC, + DMGCP, + DHO, + DDB, + DREF, + DGPRS, + DNS, + DBSSGP, + DLLC, + DSNDCP, + DSLHC, + DNAT, + DCTRL, + DSMPP, + DFILTER, + DGTPHUB, + DRANAP, + DSUA, + DV42BIS, + DPCU, + DVLR, + DIUCS, + DSIGTRAN, + Debug_LastEntry, +}; + +extern const struct log_info log_info; diff --git a/include/osmocom/sgsn/gb_proxy.h b/include/osmocom/sgsn/gb_proxy.h new file mode 100644 index 000000000..e10894fc3 --- /dev/null +++ b/include/osmocom/sgsn/gb_proxy.h @@ -0,0 +1,288 @@ +#ifndef _GB_PROXY_H +#define _GB_PROXY_H + + +#include + +#include +#include + +#include +#include + +#define GBPROXY_INIT_VU_GEN_TX 256 + +struct rate_ctr_group; +struct gprs_gb_parse_context; +struct tlv_parsed; + +enum gbproxy_global_ctr { + GBPROX_GLOB_CTR_INV_BVCI, + GBPROX_GLOB_CTR_INV_LAI, + GBPROX_GLOB_CTR_INV_RAI, + GBPROX_GLOB_CTR_INV_NSEI, + GBPROX_GLOB_CTR_PROTO_ERR_BSS, + GBPROX_GLOB_CTR_PROTO_ERR_SGSN, + GBPROX_GLOB_CTR_NOT_SUPPORTED_BSS, + GBPROX_GLOB_CTR_NOT_SUPPORTED_SGSN, + GBPROX_GLOB_CTR_RESTART_RESET_SGSN, + GBPROX_GLOB_CTR_TX_ERR_SGSN, + GBPROX_GLOB_CTR_OTHER_ERR, + GBPROX_GLOB_CTR_PATCH_PEER_ERR, +}; + +enum gbproxy_peer_ctr { + GBPROX_PEER_CTR_BLOCKED, + GBPROX_PEER_CTR_UNBLOCKED, + GBPROX_PEER_CTR_DROPPED, + GBPROX_PEER_CTR_INV_NSEI, + GBPROX_PEER_CTR_TX_ERR, + GBPROX_PEER_CTR_RAID_PATCHED_BSS, + GBPROX_PEER_CTR_RAID_PATCHED_SGSN, + GBPROX_PEER_CTR_APN_PATCHED, + GBPROX_PEER_CTR_TLLI_PATCHED_BSS, + GBPROX_PEER_CTR_TLLI_PATCHED_SGSN, + GBPROX_PEER_CTR_PTMSI_PATCHED_BSS, + GBPROX_PEER_CTR_PTMSI_PATCHED_SGSN, + GBPROX_PEER_CTR_PATCH_CRYPT_ERR, + GBPROX_PEER_CTR_PATCH_ERR, + GBPROX_PEER_CTR_ATTACH_REQS, + GBPROX_PEER_CTR_ATTACH_REJS, + GBPROX_PEER_CTR_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, + GBPROX_KEEP_REATTACH, + GBPROX_KEEP_IDENTIFIED, + GBPROX_KEEP_ALWAYS, +}; + +enum gbproxy_match_id { + GBPROX_MATCH_PATCHING, + GBPROX_MATCH_ROUTING, + GBPROX_MATCH_LAST +}; + +struct gbproxy_match { + int enable; + char *re_str; + regex_t re_comp; +}; + +struct gbproxy_config { + /* parsed from config file */ + uint16_t nsip_sgsn_nsei; + + /* misc */ + struct gprs_ns_inst *nsi; + + /* Linked list of all Gb peers (except SGSN) */ + struct llist_head bts_peers; + + /* Counter */ + struct rate_ctr_group *ctrg; + + /* force mcc/mnc */ + int core_mnc; + int core_mcc; + uint8_t* core_apn; + size_t core_apn_size; + int tlli_max_age; + int tlli_max_len; + + /* Experimental config */ + int patch_ptmsi; + int acquire_imsi; + int route_to_sgsn2; + uint16_t nsip_sgsn2_nsei; + enum gbproxy_keep_mode keep_link_infos; + + /* IMSI checking/matching */ + struct gbproxy_match matches[GBPROX_MATCH_LAST]; +}; + +struct gbproxy_patch_state { + int local_mnc; + int local_mcc; + + /* List of TLLIs for which patching is enabled */ + struct llist_head logical_links; + int logical_link_count; +}; + +struct gbproxy_peer { + struct llist_head list; + + /* point back to the config */ + struct gbproxy_config *cfg; + + /* NSEI of the peer entity */ + uint16_t nsei; + + /* BVCI used for Point-to-Point to this peer */ + uint16_t bvci; + int blocked; + + /* Routeing Area that this peer is part of (raw 04.08 encoding) */ + uint8_t ra[6]; + + /* Counter */ + struct rate_ctr_group *ctrg; + + struct gbproxy_patch_state patch_state; +}; + +struct gbproxy_tlli_state { + uint32_t current; + uint32_t assigned; + int bss_validated; + int net_validated; + + uint32_t ptmsi; +}; + +struct gbproxy_link_info { + struct llist_head list; + + struct gbproxy_tlli_state tlli; + struct gbproxy_tlli_state sgsn_tlli; + uint32_t sgsn_nsei; + + time_t timestamp; + uint8_t *imsi; + size_t imsi_len; + + int imsi_acq_pending; + struct llist_head stored_msgs; + unsigned vu_gen_tx_bss; + + int is_deregistered; + + int is_matching[GBPROX_MATCH_LAST]; +}; + + +/* gb_proxy_vty .c */ + +int gbproxy_vty_init(void); +int gbproxy_parse_config(const char *config_file, struct gbproxy_config *cfg); + + +/* gb_proxy.c */ +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_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); + +/* 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); + +/* 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); + +#endif diff --git a/include/osmocom/sgsn/gprs_gb_parse.h b/include/osmocom/sgsn/gprs_gb_parse.h new file mode 100644 index 000000000..9f43faed6 --- /dev/null +++ b/include/osmocom/sgsn/gprs_gb_parse.h @@ -0,0 +1,59 @@ +#pragma once + +#include + +#include + +struct gprs_gb_parse_context { + /* Pointer to protocol specific parts */ + struct gsm48_hdr *g48_hdr; + struct bssgp_normal_hdr *bgp_hdr; + struct bssgp_ud_hdr *bud_hdr; + uint8_t *bssgp_data; + size_t bssgp_data_len; + uint8_t *llc; + size_t llc_len; + + /* Extracted information */ + struct gprs_llc_hdr_parsed llc_hdr_parsed; + struct tlv_parsed bssgp_tp; + int to_bss; + uint8_t *tlli_enc; + uint8_t *old_tlli_enc; + uint8_t *imsi; + size_t imsi_len; + uint8_t *apn_ie; + size_t apn_ie_len; + uint8_t *ptmsi_enc; + uint8_t *new_ptmsi_enc; + uint8_t *raid_enc; + uint8_t *old_raid_enc; + uint8_t *bssgp_raid_enc; + uint8_t *bssgp_ptmsi_enc; + + /* General info */ + const char *llc_msg_name; + int invalidate_tlli; + int await_reattach; + int need_decryption; + uint32_t tlli; + int pdu_type; + int old_raid_is_foreign; + int peer_nsei; +}; + +int gprs_gb_parse_dtap(uint8_t *data, size_t data_len, + struct gprs_gb_parse_context *parse_ctx); + +int gprs_gb_parse_llc(uint8_t *llc, size_t llc_len, + struct gprs_gb_parse_context *parse_ctx); + +int gprs_gb_parse_bssgp(uint8_t *bssgp, size_t bssgp_len, + struct gprs_gb_parse_context *parse_ctx); + +const char *gprs_gb_message_name(const struct gprs_gb_parse_context *parse_ctx, + const char *default_msg_name); + +void gprs_gb_log_parse_context(int log_level, + struct gprs_gb_parse_context *parse_ctx, + const char *default_msg_name); diff --git a/include/osmocom/sgsn/gprs_gmm.h b/include/osmocom/sgsn/gprs_gmm.h new file mode 100644 index 000000000..6324c5da7 --- /dev/null +++ b/include/osmocom/sgsn/gprs_gmm.h @@ -0,0 +1,35 @@ +#ifndef _GPRS_GMM_H +#define _GPRS_GMM_H + +#include +#include + +#include + +int gsm48_tx_gsm_deact_pdp_req(struct sgsn_pdp_ctx *pdp, uint8_t sm_cause); +int gsm48_tx_gsm_act_pdp_rej(struct sgsn_mm_ctx *mm, uint8_t tid, + uint8_t cause, uint8_t pco_len, uint8_t *pco_v); +int gsm48_tx_gsm_act_pdp_acc(struct sgsn_pdp_ctx *pdp); +int gsm48_tx_gsm_deact_pdp_acc(struct sgsn_pdp_ctx *pdp); + +int gsm0408_gprs_rcvmsg_gb(struct msgb *msg, struct gprs_llc_llme *llme, + bool drop_cipherable); +int gsm0408_gprs_rcvmsg_iu(struct msgb *msg, struct gprs_ra_id *ra_id, + uint16_t *sai); +int gsm0408_gprs_force_reattach(struct sgsn_mm_ctx *mmctx); +int gsm0408_gprs_force_reattach_oldmsg(struct msgb *msg, + struct gprs_llc_llme *llme); +void gsm0408_gprs_access_granted(struct sgsn_mm_ctx *mmctx); +void gsm0408_gprs_access_denied(struct sgsn_mm_ctx *mmctx, int gmm_cause); +void gsm0408_gprs_access_cancelled(struct sgsn_mm_ctx *mmctx, int gmm_cause); +void gsm0408_gprs_authenticate(struct sgsn_mm_ctx *mmctx); + +int gprs_gmm_rx_suspend(struct gprs_ra_id *raid, uint32_t tlli); +int gprs_gmm_rx_resume(struct gprs_ra_id *raid, uint32_t tlli, + uint8_t suspend_ref); + +time_t gprs_max_time_to_idle(void); + +int iu_rab_act_ps(uint8_t rab_id, struct sgsn_pdp_ctx *pdp); + +#endif /* _GPRS_GMM_H */ diff --git a/include/osmocom/sgsn/gprs_llc.h b/include/osmocom/sgsn/gprs_llc.h new file mode 100644 index 000000000..376ae9a1a --- /dev/null +++ b/include/osmocom/sgsn/gprs_llc.h @@ -0,0 +1,284 @@ +#ifndef _GPRS_LLC_H +#define _GPRS_LLC_H + +#include +#include +#include +#include + +/* Section 4.7 LLC Layer Structure */ +enum gprs_llc_sapi { + GPRS_SAPI_GMM = 1, + GPRS_SAPI_TOM2 = 2, + GPRS_SAPI_SNDCP3 = 3, + GPRS_SAPI_SNDCP5 = 5, + GPRS_SAPI_SMS = 7, + GPRS_SAPI_TOM8 = 8, + GPRS_SAPI_SNDCP9 = 9, + GPRS_SAPI_SNDCP11 = 11, +}; + +/* Section 6.4 Commands and Responses */ +enum gprs_llc_u_cmd { + GPRS_LLC_U_DM_RESP = 0x01, + GPRS_LLC_U_DISC_CMD = 0x04, + GPRS_LLC_U_UA_RESP = 0x06, + GPRS_LLC_U_SABM_CMD = 0x07, + GPRS_LLC_U_FRMR_RESP = 0x08, + GPRS_LLC_U_XID = 0x0b, + GPRS_LLC_U_NULL_CMD = 0x00, +}; + +/* Section 6.4.1.6 / Table 6 */ +enum gprs_llc_xid_type { + GPRS_LLC_XID_T_VERSION = 0, + GPRS_LLC_XID_T_IOV_UI = 1, + GPRS_LLC_XID_T_IOV_I = 2, + GPRS_LLC_XID_T_T200 = 3, + GPRS_LLC_XID_T_N200 = 4, + GPRS_LLC_XID_T_N201_U = 5, + GPRS_LLC_XID_T_N201_I = 6, + GPRS_LLC_XID_T_mD = 7, + GPRS_LLC_XID_T_mU = 8, + GPRS_LLC_XID_T_kD = 9, + GPRS_LLC_XID_T_kU = 10, + GPRS_LLC_XID_T_L3_PAR = 11, + GPRS_LLC_XID_T_RESET = 12, +}; + +extern const struct value_string gprs_llc_xid_type_names[]; + +/* TS 04.64 Section 7.1.2 Table 7: LLC layer primitives (GMM/SNDCP/SMS/TOM) */ +/* TS 04.65 Section 5.1.2 Table 2: Service primitives used by SNDCP */ +enum gprs_llc_primitive { + /* GMM <-> LLME */ + LLGMM_ASSIGN_REQ, /* GMM tells us new TLLI: TLLI old, TLLI new, Kc, CiphAlg */ + LLGMM_RESET_REQ, /* GMM tells us to perform XID negotiation: TLLI */ + LLGMM_RESET_CNF, /* LLC informs GMM that XID has completed: TLLI */ + LLGMM_SUSPEND_REQ, /* GMM tells us MS has suspended: TLLI, Page */ + LLGMM_RESUME_REQ, /* GMM tells us MS has resumed: TLLI */ + LLGMM_PAGE_IND, /* LLC asks GMM to page MS: TLLI */ + LLGMM_IOV_REQ, /* GMM tells us to perform XID: TLLI */ + LLGMM_STATUS_IND, /* LLC informs GMM about error: TLLI, Cause */ + /* LLE <-> (GMM/SNDCP/SMS/TOM) */ + LL_RESET_IND, /* TLLI */ + LL_ESTABLISH_REQ, /* TLLI, XID Req */ + LL_ESTABLISH_IND, /* TLLI, XID Req, N201-I, N201-U */ + LL_ESTABLISH_RESP, /* TLLI, XID Negotiated */ + LL_ESTABLISH_CONF, /* TLLI, XID Neg, N201-i, N201-U */ + LL_RELEASE_REQ, /* TLLI, Local */ + LL_RELEASE_IND, /* TLLI, Cause */ + LL_RELEASE_CONF, /* TLLI */ + LL_XID_REQ, /* TLLI, XID Requested */ + LL_XID_IND, /* TLLI, XID Req, N201-I, N201-U */ + LL_XID_RESP, /* TLLI, XID Negotiated */ + LL_XID_CONF, /* TLLI, XID Neg, N201-I, N201-U */ + LL_DATA_REQ, /* TLLI, SN-PDU, Ref, QoS, Radio Prio, Ciph */ + LL_DATA_IND, /* TLLI, SN-PDU */ + LL_DATA_CONF, /* TLLI, Ref */ + LL_UNITDATA_REQ, /* TLLI, SN-PDU, Ref, QoS, Radio Prio, Ciph */ + LL_UNITDATA_IND, /* TLLI, SN-PDU */ + LL_STATUS_IND, /* TLLI, Cause */ +}; + +/* Section 4.5.2 Logical Link States + Annex C.2 */ +enum gprs_llc_lle_state { + GPRS_LLES_UNASSIGNED = 1, /* No TLLI yet */ + GPRS_LLES_ASSIGNED_ADM = 2, /* TLLI assigned */ + GPRS_LLES_LOCAL_EST = 3, /* Local Establishment */ + GPRS_LLES_REMOTE_EST = 4, /* Remote Establishment */ + GPRS_LLES_ABM = 5, + GPRS_LLES_LOCAL_REL = 6, /* Local Release */ + GPRS_LLES_TIMER_REC = 7, /* Timer Recovery */ +}; + +enum gprs_llc_llme_state { + GPRS_LLMS_UNASSIGNED = 1, /* No TLLI yet */ + GPRS_LLMS_ASSIGNED = 2, /* TLLI assigned */ +}; + +/* Section 8.9.9 LLC layer parameter default values */ +struct gprs_llc_params { + uint16_t iov_i_exp; + uint16_t t200_201; + uint16_t n200; + uint16_t n201_u; + uint16_t n201_i; + uint16_t mD; + uint16_t mU; + uint16_t kD; + uint16_t kU; +}; + +/* Section 4.7.1: Logical Link Entity: One per DLCI (TLLI + SAPI) */ +struct gprs_llc_lle { + struct llist_head list; + + uint32_t sapi; + + struct gprs_llc_llme *llme; + + enum gprs_llc_lle_state state; + + struct osmo_timer_list t200; + struct osmo_timer_list t201; /* wait for acknowledgement */ + + uint16_t v_sent; + uint16_t v_ack; + uint16_t v_recv; + + uint16_t vu_send; + uint16_t vu_recv; + + /* non-standard LLC state */ + uint16_t vu_recv_last; + uint16_t vu_recv_duplicates; + + /* Overflow Counter for ABM */ + uint32_t oc_i_send; + uint32_t oc_i_recv; + + /* Overflow Counter for unconfirmed transfer */ + uint32_t oc_ui_send; + uint32_t oc_ui_recv; + + unsigned int retrans_ctr; + + struct gprs_llc_params params; +}; + +#define NUM_SAPIS 16 + +struct gprs_llc_llme { + struct llist_head list; + + enum gprs_llc_llme_state state; + + uint32_t tlli; + uint32_t old_tlli; + + /* Crypto parameters */ + enum gprs_ciph_algo algo; + uint8_t kc[16]; + uint8_t cksn; + /* 3GPP TS 44.064 § 8.9.2: */ + uint32_t iov_ui; + + /* over which BSSGP BTS ctx do we need to transmit */ + uint16_t bvci; + uint16_t nsei; + struct gprs_llc_lle lle[NUM_SAPIS]; + + /* Copy of the XID fields we have sent with the last + * network originated XID-Request. Since the phone + * may strip the optional fields in the confirmation + * we need to remeber those fields in order to be + * able to create the compression entity. */ + struct llist_head *xid; + + /* Compression entities */ + struct { + /* In these two list_heads we will store the + * data and protocol compression entities, + * together with their compression states */ + struct llist_head *proto; + struct llist_head *data; + } comp; + + /* Internal management */ + uint32_t age_timestamp; +}; + +#define GPRS_LLME_RESET_AGE (0) + +extern struct llist_head gprs_llc_llmes; + +/* LLC low level types */ + +enum gprs_llc_cmd { + GPRS_LLC_NULL, + GPRS_LLC_RR, + GPRS_LLC_ACK, + GPRS_LLC_RNR, + GPRS_LLC_SACK, + GPRS_LLC_DM, + GPRS_LLC_DISC, + GPRS_LLC_UA, + GPRS_LLC_SABM, + GPRS_LLC_FRMR, + GPRS_LLC_XID, + GPRS_LLC_UI, +}; + +struct gprs_llc_hdr_parsed { + uint8_t sapi; + uint8_t is_cmd:1, + ack_req:1, + is_encrypted:1; + uint32_t seq_rx; + uint32_t seq_tx; + uint32_t fcs; + uint32_t fcs_calc; + uint8_t *data; + uint16_t data_len; + uint16_t crc_length; + enum gprs_llc_cmd cmd; +}; + + +/* BSSGP-UL-UNITDATA.ind */ +int gprs_llc_rcvmsg(struct msgb *msg, struct tlv_parsed *tv); + +/* LL-UNITDATA.req */ +int gprs_llc_tx_ui(struct msgb *msg, uint8_t sapi, int command, + struct sgsn_mm_ctx *mmctx, bool encryptable); + +/* Chapter 7.2.1.2 LLGMM-RESET.req */ +int gprs_llgmm_reset(struct gprs_llc_llme *llme); +int gprs_llgmm_reset_oldmsg(struct msgb* oldmsg, uint8_t sapi, + struct gprs_llc_llme *llme); + +/* Set of LL-XID negotiation (See also: TS 101 351, Section 7.2.2.4) */ +int gprs_ll_xid_req(struct gprs_llc_lle *lle, + struct gprs_llc_xid_field *l3_xid_field); + +/* 04.64 Chapter 7.2.1.1 LLGMM-ASSIGN */ +int gprs_llgmm_assign(struct gprs_llc_llme *llme, + uint32_t old_tlli, uint32_t new_tlli); +int gprs_llgmm_unassign(struct gprs_llc_llme *llme); + +int gprs_llc_init(const char *cipher_plugin_path); +int gprs_llc_vty_init(void); + +/** + * \short Check if N(U) should be considered a retransmit + * + * Implements the range check as of GSM 04.64 8.4.2 + * Receipt of unacknowledged information. + * + * @returns Returns 1 if (V(UR)-32) <= N(U) < V(UR) + * @param nu N(U) unconfirmed sequence number of the UI frame + * @param vur V(UR) unconfirmend received state variable + */ +static inline int gprs_llc_is_retransmit(uint16_t nu, uint16_t vur) +{ + int delta = (vur - nu) & 0x1ff; + return 0 < delta && delta < 32; +} + +/* LLC low level functions */ +void gprs_llme_copy_key(struct sgsn_mm_ctx *mm, struct gprs_llc_llme *llme); + +/* parse a GPRS LLC header, also check for invalid frames */ +int gprs_llc_hdr_parse(struct gprs_llc_hdr_parsed *ghp, + uint8_t *llc_hdr, int len); +void gprs_llc_hdr_dump(struct gprs_llc_hdr_parsed *gph, struct gprs_llc_lle *lle); +int gprs_llc_fcs(uint8_t *data, unsigned int len); + + +/* LLME handling routines */ +struct llist_head *gprs_llme_list(void); +struct gprs_llc_lle *gprs_lle_get_or_create(const uint32_t tlli, uint8_t sapi); + + +#endif diff --git a/include/osmocom/sgsn/gprs_llc_xid.h b/include/osmocom/sgsn/gprs_llc_xid.h new file mode 100644 index 000000000..d340d40b7 --- /dev/null +++ b/include/osmocom/sgsn/gprs_llc_xid.h @@ -0,0 +1,57 @@ +/* GPRS LLC XID field encoding/decoding as per 3GPP TS 44.064 */ + +/* (C) 2016 by sysmocom s.f.m.c. GmbH + * All Rights Reserved + * + * Author: Philipp Maier + * + * 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 . + */ + +#pragma once + +#include +#include + +/* 3GPP TS 44.064 6.4.1.6 Exchange Identification (XID) + command/response parameter field */ +struct gprs_llc_xid_field { + struct llist_head list; + uint8_t type; /* See also Table 6: LLC layer parameter + negotiation */ + uint8_t *data; /* Payload data (memory is owned by the + * creator of the struct) */ + unsigned int data_len; /* Payload length */ +}; + +/* Transform a list with XID fields into a XID message (dst) */ +int gprs_llc_compile_xid(uint8_t *dst, int dst_maxlen, + const struct llist_head *xid_fields); + +/* Transform a XID message (dst) into a list of XID fields */ +struct llist_head *gprs_llc_parse_xid(const void *ctx, const uint8_t *src, + int src_len); + +/* Create a duplicate of an XID-Field */ +struct gprs_llc_xid_field *gprs_llc_dup_xid_field(const void *ctx, + const struct gprs_llc_xid_field *xid_field); + +/* Copy an llist with xid fields */ +struct llist_head *gprs_llc_copy_xid(const void *ctx, + const struct llist_head *xid_fields); + +/* Dump a list with XID fields (Debug) */ +void gprs_llc_dump_xid_fields(const struct llist_head *xid_fields, + unsigned int logl); + diff --git a/include/osmocom/sgsn/gprs_sgsn.h b/include/osmocom/sgsn/gprs_sgsn.h new file mode 100644 index 000000000..c47fb0905 --- /dev/null +++ b/include/osmocom/sgsn/gprs_sgsn.h @@ -0,0 +1,484 @@ +#ifndef _GPRS_SGSN_H +#define _GPRS_SGSN_H + +#include +#include + +#include + +#include + +#include +#include +#include + +#define GSM_EXTENSION_LENGTH 15 +#define GSM_APN_LENGTH 102 + +struct gprs_llc_lle; +struct ctrl_handle; +struct gprs_subscr; + +enum gsm48_gsm_cause; + +/* TS 04.08 4.1.3.3 GMM mobility management states on the network side */ +enum gprs_gmm_state { + GMM_DEREGISTERED, /* 4.1.3.3.1.1 */ + GMM_COMMON_PROC_INIT, /* 4.1.3.3.1.2 */ + GMM_REGISTERED_NORMAL, /* 4.1.3.3.2.1 */ + GMM_REGISTERED_SUSPENDED, /* 4.1.3.3.2.2 */ + GMM_DEREGISTERED_INIT, /* 4.1.3.3.1.4 */ +}; + +/* TS 23.060 6.1.1 and 6.1.2 Mobility management states A/Gb and Iu mode */ +enum gprs_pmm_state { + PMM_DETACHED, + PMM_CONNECTED, + PMM_IDLE, + MM_IDLE, + MM_READY, + MM_STANDBY, +}; + +enum gprs_mm_ctr { + GMM_CTR_PKTS_SIG_IN, + GMM_CTR_PKTS_SIG_OUT, + GMM_CTR_PKTS_UDATA_IN, + GMM_CTR_PKTS_UDATA_OUT, + GMM_CTR_BYTES_UDATA_IN, + GMM_CTR_BYTES_UDATA_OUT, + GMM_CTR_PDP_CTX_ACT, + GMM_CTR_SUSPEND, + GMM_CTR_PAGING_PS, + GMM_CTR_PAGING_CS, + GMM_CTR_RA_UPDATE, +}; + +enum gprs_pdp_ctx { + PDP_CTR_PKTS_UDATA_IN, + PDP_CTR_PKTS_UDATA_OUT, + PDP_CTR_BYTES_UDATA_IN, + PDP_CTR_BYTES_UDATA_OUT, +}; + +enum gprs_t3350_mode { + GMM_T3350_MODE_NONE, + GMM_T3350_MODE_ATT, + GMM_T3350_MODE_RAU, + GMM_T3350_MODE_PTMSI_REALL, +}; + +/* Authorization/ACL handling */ +enum sgsn_auth_state { + SGSN_AUTH_UNKNOWN, + SGSN_AUTH_AUTHENTICATE, + SGSN_AUTH_UMTS_RESYNC, + SGSN_AUTH_ACCEPTED, + SGSN_AUTH_REJECTED +}; + +#define MS_RADIO_ACCESS_CAPA + +enum sgsn_ggsn_lookup_state { + SGSN_GGSN_2DIGIT, + SGSN_GGSN_3DIGIT, +}; + +struct sgsn_ggsn_lookup { + int state; + + struct sgsn_mm_ctx *mmctx; + + /* APN string */ + char apn_str[GSM_APN_LENGTH]; + + /* the original data */ + struct msgb *orig_msg; + struct tlv_parsed tp; + + /* for dealing with re-transmissions */ + uint8_t nsapi; + uint8_t sapi; + uint8_t ti; +}; + +enum sgsn_ran_type { + /* GPRS/EDGE via Gb */ + MM_CTX_T_GERAN_Gb, + /* UMTS via Iu */ + MM_CTX_T_UTRAN_Iu, + /* GPRS/EDGE via Iu */ + MM_CTX_T_GERAN_Iu, +}; + +struct service_info { + uint8_t type; + uint16_t pdp_status; +}; + +struct ranap_ue_conn_ctx; + +struct gsm_auth_tuple { + int use_count; + int key_seq; + struct osmo_auth_vector vec; +}; +#define GSM_KEY_SEQ_INVAL 7 /* GSM 04.08 - 10.5.1.2 */ + +/* According to TS 03.60, Table 5: SGSN MM and PDP Contexts */ +/* Extended by 3GPP TS 23.060, Table 6: SGSN MM and PDP Contexts */ +struct sgsn_mm_ctx { + struct llist_head list; + + enum sgsn_ran_type ran_type; + + char imsi[GSM23003_IMSI_MAX_DIGITS+1]; + enum gprs_gmm_state gmm_state; + enum gprs_pmm_state pmm_state; /* Iu: page when in PMM-IDLE mode */ + uint32_t p_tmsi; + uint32_t p_tmsi_old; /* old P-TMSI before new is confirmed */ + uint32_t p_tmsi_sig; + char imei[GSM23003_IMEISV_NUM_DIGITS+1]; + /* Opt: Software Version Numbber / TS 23.195 */ + char msisdn[GSM_EXTENSION_LENGTH]; + struct gprs_ra_id ra; + struct { + uint16_t cell_id; /* Gb only */ + uint32_t cell_id_age; /* Gb only */ + uint8_t radio_prio_sms; + + /* Additional bits not present in the GSM TS */ + uint16_t nsei; + uint16_t bvci; + struct gprs_llc_llme *llme; + uint32_t tlli; + uint32_t tlli_new; + } gb; + struct { + int new_key; + uint16_t sac; /* Iu: Service Area Code */ + uint32_t sac_age; /* Iu: Service Area Code age */ + /* CSG ID */ + /* CSG Membership */ + /* Access Mode */ + /* Seelected CN Operator ID (TS 23.251) */ + /* CSG Subscription Data */ + /* LIPA Allowed */ + /* Voice Support Match Indicator */ + struct ranap_ue_conn_ctx *ue_ctx; + struct service_info service; + } iu; + /* VLR number */ + uint32_t new_sgsn_addr; + /* Authentication Triplet */ + struct gsm_auth_tuple auth_triplet; + /* Kc */ + /* Iu: CK, IK, KSI */ + /* CKSN */ + enum gprs_ciph_algo ciph_algo; + /* Auth & Ciphering Request reference from 3GPP TS 24.008 § 10.5.5.19: */ + uint8_t ac_ref_nr_used; + + struct { + uint8_t len; + uint8_t buf[50]; /* GSM 04.08 10.5.5.12a, extended in TS 24.008 */ + } ms_radio_access_capa; + /* Supported Codecs (SRVCC) */ + struct { + uint8_t len; + uint8_t buf[8]; /* GSM 04.08 10.5.5.12, extended in TS 24.008 */ + } ms_network_capa; + /* UE Netowrk Capability (E-UTRAN) */ + uint16_t drx_parms; + /* Active Time value for PSM */ + int mnrg; /* MS reported to HLR? */ + int ngaf; /* MS reported to MSC/VLR? */ + int ppf; /* paging for GPRS + non-GPRS? */ + /* Subscribed Charging Characteristics */ + /* Trace Reference */ + /* Trace Type */ + /* Trigger ID */ + /* OMC Identity */ + /* SMS Parameters */ + int recovery; + /* Access Restriction */ + /* GPRS CSI (CAMEL) */ + /* MG-CSI (CAMEL) */ + /* Subscribed UE-AMBR */ + /* UE-AMBR */ + /* APN Subscribed */ + + struct llist_head pdp_list; + + struct rate_ctr_group *ctrg; + struct osmo_timer_list timer; + unsigned int T; /* Txxxx number */ + unsigned int num_T_exp; /* number of consecutive T expirations */ + + enum gprs_t3350_mode t3350_mode; + uint8_t t3370_id_type; + uint8_t pending_req; /* the request's message type */ + /* TODO: There isn't much semantic difference between t3350_mode + * (refers to the timer) and pending_req (refers to the procedure), + * where mm->T == 3350 => mm->t3350_mode == f(mm->pending_req). Check + * whether one of them can be dropped. */ + + enum sgsn_auth_state auth_state; + int is_authenticated; + + /* the string representation of the current hlr */ + char hlr[GSM_EXTENSION_LENGTH]; + + /* the current GGSN look-up operation */ + struct sgsn_ggsn_lookup *ggsn_lookup; + + struct gprs_subscr *subscr; +}; + +#define LOGMMCTXP(level, mm, fmt, args...) \ + LOGP(DMM, level, "MM(%s/%08x) " fmt, (mm) ? (mm)->imsi : "---", \ + (mm) ? (mm)->p_tmsi : GSM_RESERVED_TMSI, ## args) + +/* look-up a SGSN MM context based on TLLI + RAI */ +struct sgsn_mm_ctx *sgsn_mm_ctx_by_tlli(uint32_t tlli, + const struct gprs_ra_id *raid); +struct sgsn_mm_ctx *sgsn_mm_ctx_by_ptmsi(uint32_t tmsi); +struct sgsn_mm_ctx *sgsn_mm_ctx_by_imsi(const char *imsi); +struct sgsn_mm_ctx *sgsn_mm_ctx_by_ue_ctx(const void *uectx); + +/* look-up by matching TLLI and P-TMSI (think twice before using this) */ +struct sgsn_mm_ctx *sgsn_mm_ctx_by_tlli_and_ptmsi(uint32_t tlli, + const struct gprs_ra_id *raid); + +/* Allocate a new SGSN MM context */ +struct sgsn_mm_ctx *sgsn_mm_ctx_alloc_gb(uint32_t tlli, + const struct gprs_ra_id *raid); +struct sgsn_mm_ctx *sgsn_mm_ctx_alloc_iu(void *uectx); + +void sgsn_mm_ctx_cleanup_free(struct sgsn_mm_ctx *ctx); + +struct sgsn_ggsn_ctx *sgsn_mm_ctx_find_ggsn_ctx(struct sgsn_mm_ctx *mmctx, + struct tlv_parsed *tp, + enum gsm48_gsm_cause *gsm_cause, + char *apn_str); + +enum pdp_ctx_state { + PDP_STATE_NONE, + PDP_STATE_CR_REQ, + PDP_STATE_CR_CONF, + + /* 04.08 / Figure 6.2 / 6.1.2.2 */ + PDP_STATE_INACT_PEND, + PDP_STATE_INACTIVE = PDP_STATE_NONE, +}; + +enum pdp_type { + PDP_TYPE_NONE, + PDP_TYPE_ETSI_PPP, + PDP_TYPE_IANA_IPv4, + PDP_TYPE_IANA_IPv6, +}; + +struct sgsn_pdp_ctx { + struct llist_head list; /* list_head for mmctx->pdp_list */ + struct llist_head g_list; /* list_head for global list */ + struct sgsn_mm_ctx *mm; /* back pointer to MM CTX */ + int destroy_ggsn; /* destroy it on destruction */ + struct sgsn_ggsn_ctx *ggsn; /* which GGSN serves this PDP */ + struct rate_ctr_group *ctrg; + + //unsigned int id; + struct pdp_t *lib; /* pointer to libgtp PDP ctx */ + enum pdp_ctx_state state; + enum pdp_type type; + uint32_t address; + char *apn_subscribed; + //char *apn_used; + uint16_t nsapi; /* SNDCP */ + uint16_t sapi; /* LLC */ + uint8_t ti; /* transaction identifier */ + int vplmn_allowed; + uint32_t qos_profile_subscr; + //uint32_t qos_profile_req; + //uint32_t qos_profile_neg; + uint8_t radio_prio; + //uint32_t charging_id; + + struct osmo_timer_list timer; + unsigned int T; /* Txxxx number */ + unsigned int num_T_exp; /* number of consecutive T expirations */ + + struct osmo_timer_list cdr_timer; /* CDR record wird timer */ + struct timespec cdr_start; /* The start of the CDR */ + uint64_t cdr_bytes_in; + uint64_t cdr_bytes_out; + uint32_t cdr_charging_id; +}; + +#define LOGPDPCTXP(level, pdp, fmt, args...) \ + LOGP(DGPRS, level, "PDP(%s/%u) " \ + fmt, (pdp)->mm ? (pdp)->mm->imsi : "---", (pdp)->ti, ## args) + +/* look up PDP context by MM context and NSAPI */ +struct sgsn_pdp_ctx *sgsn_pdp_ctx_by_nsapi(const struct sgsn_mm_ctx *mm, + uint8_t nsapi); +/* look up PDP context by MM context and transaction ID */ +struct sgsn_pdp_ctx *sgsn_pdp_ctx_by_tid(const struct sgsn_mm_ctx *mm, + uint8_t tid); + +struct sgsn_pdp_ctx *sgsn_pdp_ctx_alloc(struct sgsn_mm_ctx *mm, + uint8_t nsapi); +void sgsn_pdp_ctx_terminate(struct sgsn_pdp_ctx *pdp); +void sgsn_pdp_ctx_free(struct sgsn_pdp_ctx *pdp); + + +struct sgsn_ggsn_ctx { + struct llist_head list; + uint32_t id; + unsigned int gtp_version; + struct in_addr remote_addr; + int remote_restart_ctr; + struct gsn_t *gsn; +}; +struct sgsn_ggsn_ctx *sgsn_ggsn_ctx_alloc(uint32_t id); +void sgsn_ggsn_ctx_free(struct sgsn_ggsn_ctx *ggc); +struct sgsn_ggsn_ctx *sgsn_ggsn_ctx_by_id(uint32_t id); +struct sgsn_ggsn_ctx *sgsn_ggsn_ctx_by_addr(struct in_addr *addr); +struct sgsn_ggsn_ctx *sgsn_ggsn_ctx_find_alloc(uint32_t id); + +struct apn_ctx { + struct llist_head list; + struct sgsn_ggsn_ctx *ggsn; + char *name; + char *imsi_prefix; + char *description; +}; + +struct apn_ctx *sgsn_apn_ctx_find_alloc(const char *name, const char *imsi_prefix); +void sgsn_apn_ctx_free(struct apn_ctx *actx); +struct apn_ctx *sgsn_apn_ctx_by_name(const char *name, const char *imsi_prefix); +struct apn_ctx *sgsn_apn_ctx_match(const char *name, const char *imsi_prefix); + +extern struct llist_head sgsn_mm_ctxts; +extern struct llist_head sgsn_ggsn_ctxts; +extern struct llist_head sgsn_apn_ctxts; +extern struct llist_head sgsn_pdp_ctxts; + +uint32_t sgsn_alloc_ptmsi(void); +void sgsn_inst_init(void); + +/* High-level function to be called in case a GGSN has disappeared or + * ottherwise lost state (recovery procedure) */ +int drop_all_pdp_for_ggsn(struct sgsn_ggsn_ctx *ggsn); + +char *gprs_pdpaddr2str(uint8_t *pdpa, uint8_t len); + +/* + * ctrl interface related work + */ +struct gsm_network; +struct ctrl_handle *sgsn_controlif_setup(struct gsm_network *, + const char *bind_addr, uint16_t port); +int sgsn_ctrl_cmds_install(void); + +/* + * Authorization/ACL handling + */ +struct imsi_acl_entry { + struct llist_head list; + char imsi[16+1]; +}; + +/* see GSM 09.02, 17.7.1, PDP-Context and GPRSSubscriptionData */ +/* see GSM 09.02, B.1, gprsSubscriptionData */ +struct sgsn_subscriber_pdp_data { + struct llist_head list; + + unsigned int context_id; + uint16_t pdp_type; + char apn_str[GSM_APN_LENGTH]; + uint8_t qos_subscribed[20]; + size_t qos_subscribed_len; + uint8_t pdp_charg[2]; + bool has_pdp_charg; +}; + +struct sgsn_subscriber_data { + struct sgsn_mm_ctx *mm; + struct gsm_auth_tuple auth_triplets[5]; + int auth_triplets_updated; + struct llist_head pdp_list; + int error_cause; + + uint8_t msisdn[9]; + size_t msisdn_len; + + uint8_t hlr[9]; + size_t hlr_len; + + uint8_t pdp_charg[2]; + bool has_pdp_charg; +}; + +#define SGSN_ERROR_CAUSE_NONE (-1) + +#define LOGGSUBSCRP(level, subscr, fmt, args...) \ + LOGP(DGPRS, level, "SUBSCR(%s) " fmt, \ + (subscr) ? (subscr)->imsi : "---", \ + ## args) + +struct sgsn_config; +struct sgsn_instance; +extern const struct value_string *sgsn_auth_state_names; + +void sgsn_auth_init(void); +struct imsi_acl_entry *sgsn_acl_lookup(const char *imsi, struct sgsn_config *cfg); +int sgsn_acl_add(const char *imsi, struct sgsn_config *cfg); +int sgsn_acl_del(const char *imsi, struct sgsn_config *cfg); +/* Request authorization */ +int sgsn_auth_request(struct sgsn_mm_ctx *mm); +enum sgsn_auth_state sgsn_auth_state(struct sgsn_mm_ctx *mm); +void sgsn_auth_update(struct sgsn_mm_ctx *mm); +struct gsm_auth_tuple *sgsn_auth_get_tuple(struct sgsn_mm_ctx *mmctx, + unsigned key_seq); + +/* + * GPRS subscriber data + */ +#define GPRS_SUBSCRIBER_FIRST_CONTACT 0x00000001 +#define GPRS_SUBSCRIBER_UPDATE_AUTH_INFO_PENDING (1 << 16) +#define GPRS_SUBSCRIBER_UPDATE_LOCATION_PENDING (1 << 17) +#define GPRS_SUBSCRIBER_CANCELLED (1 << 18) +#define GPRS_SUBSCRIBER_ENABLE_PURGE (1 << 19) + +#define GPRS_SUBSCRIBER_UPDATE_PENDING_MASK ( \ + GPRS_SUBSCRIBER_UPDATE_LOCATION_PENDING | \ + GPRS_SUBSCRIBER_UPDATE_AUTH_INFO_PENDING \ +) + +int gprs_subscr_init(struct sgsn_instance *sgi); +int gprs_subscr_request_update_location(struct sgsn_mm_ctx *mmctx); +int gprs_subscr_request_auth_info(struct sgsn_mm_ctx *mmctx, + const uint8_t *auts, + const uint8_t *auts_rand); +int gprs_subscr_auth_sync(struct gprs_subscr *subscr, + const uint8_t *auts, const uint8_t *auts_rand); +void gprs_subscr_cleanup(struct gprs_subscr *subscr); +struct gprs_subscr *gprs_subscr_get_or_create(const char *imsi); +struct gprs_subscr *gprs_subscr_get_or_create_by_mmctx( struct sgsn_mm_ctx *mmctx); +struct gprs_subscr *gprs_subscr_get_by_imsi(const char *imsi); +void gprs_subscr_cancel(struct gprs_subscr *subscr); +void gprs_subscr_update(struct gprs_subscr *subscr); +void gprs_subscr_update_auth_info(struct gprs_subscr *subscr); +int gprs_subscr_rx_gsup_message(struct msgb *msg); + +/* Called on subscriber data updates */ +void sgsn_update_subscriber_data(struct sgsn_mm_ctx *mmctx); + +int gprs_sndcp_vty_init(void); +struct sgsn_instance; +int sgsn_gtp_init(struct sgsn_instance *sgi); + +void sgsn_rate_ctr_init(); + +#endif /* _GPRS_SGSN_H */ diff --git a/include/osmocom/sgsn/gprs_sndcp.h b/include/osmocom/sgsn/gprs_sndcp.h new file mode 100644 index 000000000..d970240e4 --- /dev/null +++ b/include/osmocom/sgsn/gprs_sndcp.h @@ -0,0 +1,79 @@ +#ifndef _INT_SNDCP_H +#define _INT_SNDCP_H + +#include +#include + +/* A fragment queue header, maintaining list of fragments for one N-PDU */ +struct defrag_state { + /* PDU number for which the defragmentation state applies */ + uint16_t npdu; + /* highest segment number we have received so far */ + uint8_t highest_seg; + /* bitmask of the segments we already have */ + uint32_t seg_have; + /* do we still expect more segments? */ + unsigned int no_more; + /* total length of all segments together */ + unsigned int tot_len; + + /* linked list of defrag_queue_entry: one for each fragment */ + struct llist_head frag_list; + + struct osmo_timer_list timer; + + /* Holds state to know which compression mode is used + * when the packet is re-assembled */ + uint8_t pcomp; + uint8_t dcomp; + + /* Holds the pointers to the compression entity list + * that is used when the re-assembled packet is decompressed */ + struct llist_head *proto; + struct llist_head *data; +}; + +/* See 6.7.1.2 Reassembly */ +enum sndcp_rx_state { + SNDCP_RX_S_FIRST, + SNDCP_RX_S_SUBSEQ, + SNDCP_RX_S_DISCARD, +}; + +struct gprs_sndcp_entity { + struct llist_head list; + + /* FIXME: move this RA_ID up to the LLME or even higher */ + struct gprs_ra_id ra_id; + /* reference to the LLC Entity below this SNDCP entity */ + struct gprs_llc_lle *lle; + /* The NSAPI we shall use on top of LLC */ + uint8_t nsapi; + + /* NPDU number for the GTP->SNDCP side */ + uint16_t tx_npdu_nr; + /* SNDCP eeceiver state */ + enum sndcp_rx_state rx_state; + /* The defragmentation queue */ + struct defrag_state defrag; +}; + +extern struct llist_head gprs_sndcp_entities; + +/* Set of SNDCP-XID negotiation (See also: TS 144 065, + * Section 6.8 XID parameter negotiation) */ +int sndcp_sn_xid_req(struct gprs_llc_lle *lle, uint8_t nsapi); + +/* Process SNDCP-XID indication (See also: TS 144 065, + * Section 6.8 XID parameter negotiation) */ +int sndcp_sn_xid_ind(struct gprs_llc_xid_field *xid_field_indication, + struct gprs_llc_xid_field *xid_field_response, + struct gprs_llc_lle *lle); + +/* Process SNDCP-XID indication + * (See also: TS 144 065, Section 6.8 XID parameter negotiation) */ +int sndcp_sn_xid_conf(struct gprs_llc_xid_field *xid_field_conf, + struct gprs_llc_xid_field *xid_field_request, + struct gprs_llc_lle *lle); + +#endif /* INT_SNDCP_H */ diff --git a/include/osmocom/sgsn/gprs_sndcp_comp.h b/include/osmocom/sgsn/gprs_sndcp_comp.h new file mode 100644 index 000000000..c04f7d49a --- /dev/null +++ b/include/osmocom/sgsn/gprs_sndcp_comp.h @@ -0,0 +1,82 @@ +/* GPRS SNDCP header compression entity management tools */ + +/* (C) 2016 by sysmocom s.f.m.c. GmbH + * All Rights Reserved + * + * Author: Philipp Maier + * + * 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 . + */ + +#pragma once + +#include +#include +#include + +/* Header / Data compression entity */ +struct gprs_sndcp_comp { + struct llist_head list; + + /* Serves as an ID in case we want to delete this entity later */ + unsigned int entity; /* see also: 6.5.1.1.3 and 6.6.1.1.3 */ + + /* Specifies to which NSAPIs the compression entity is assigned */ + uint8_t nsapi_len; /* Number of applicable NSAPIs (default 0) */ + uint8_t nsapi[MAX_NSAPI]; /* Applicable NSAPIs (default 0) */ + + /* Assigned pcomp values */ + uint8_t comp_len; /* Number of contained PCOMP / DCOMP values */ + uint8_t comp[MAX_COMP]; /* see also: 6.5.1.1.5 and 6.6.1.1.5 */ + + /* Algorithm parameters */ + int algo; /* Algorithm type (see gprs_sndcp_xid.h) */ + int compclass; /* See gprs_sndcp_xid.h/c */ + void *state; /* Algorithm status and parameters */ +}; + +#define MAX_COMP 16 /* Maximum number of possible pcomp/dcomp values */ +#define MAX_NSAPI 11 /* Maximum number usable NSAPIs */ + +/* Allocate a compression enitiy list */ +struct llist_head *gprs_sndcp_comp_alloc(const void *ctx); + +/* Free a compression entitiy list */ +void gprs_sndcp_comp_free(struct llist_head *comp_entities); + +/* Delete a compression entity */ +void gprs_sndcp_comp_delete(struct llist_head *comp_entities, unsigned int entity); + +/* Create and Add a new compression entity + * (returns a pointer to the compression entity that has just been created) */ +struct gprs_sndcp_comp *gprs_sndcp_comp_add(const void *ctx, + struct llist_head *comp_entities, + const struct gprs_sndcp_comp_field + *comp_field); + +/* Find which compression entity handles the specified pcomp/dcomp */ +struct gprs_sndcp_comp *gprs_sndcp_comp_by_comp(const struct llist_head + *comp_entities, uint8_t comp); + +/* Find which compression entity handles the specified nsapi */ +struct gprs_sndcp_comp *gprs_sndcp_comp_by_nsapi(const struct llist_head + *comp_entities, uint8_t nsapi); + +/* Find a comp_index for a given pcomp/dcomp value */ +uint8_t gprs_sndcp_comp_get_idx(const struct gprs_sndcp_comp *comp_entity, + uint8_t comp); + +/* Find a pcomp/dcomp value for a given comp_index */ +uint8_t gprs_sndcp_comp_get_comp(const struct gprs_sndcp_comp *comp_entity, + uint8_t comp_index); diff --git a/include/osmocom/sgsn/gprs_sndcp_dcomp.h b/include/osmocom/sgsn/gprs_sndcp_dcomp.h new file mode 100644 index 000000000..3e851421c --- /dev/null +++ b/include/osmocom/sgsn/gprs_sndcp_dcomp.h @@ -0,0 +1,53 @@ +/* GPRS SNDCP data compression handler */ + +/* (C) 2016 by sysmocom s.f.m.c. GmbH + * All Rights Reserved + * + * Author: Philipp Maier + * + * 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 . + */ + +#pragma once + +#include +#include +#include + +/* Note: The decompressed packet may have a maximum size of: + * Return value * MAX_DATADECOMPR_FAC */ +#define MAX_DATADECOMPR_FAC 10 + +/* Note: In unacknowledged mode (SN_UNITDATA), the comression state is reset + * for every NPDU. The compressor needs a reasonably large payload to operate + * effectively (yield positive compression gain). For packets shorter than 100 + * byte, no positive compression gain can be expected so we will skip the + * compression for short packets. */ +#define MIN_COMPR_PAYLOAD 100 + +/* Initalize data compression */ +int gprs_sndcp_dcomp_init(const void *ctx, struct gprs_sndcp_comp *comp_entity, + const struct gprs_sndcp_comp_field *comp_field); + +/* Terminate data compression */ +void gprs_sndcp_dcomp_term(struct gprs_sndcp_comp *comp_entity); + +/* Expand packet */ +int gprs_sndcp_dcomp_expand(uint8_t *data, unsigned int len, uint8_t pcomp, + const struct llist_head *comp_entities); + +/* Compress packet */ +int gprs_sndcp_dcomp_compress(uint8_t *data, unsigned int len, uint8_t *pcomp, + const struct llist_head *comp_entities, + uint8_t nsapi); diff --git a/include/osmocom/sgsn/gprs_sndcp_pcomp.h b/include/osmocom/sgsn/gprs_sndcp_pcomp.h new file mode 100644 index 000000000..3e3131b52 --- /dev/null +++ b/include/osmocom/sgsn/gprs_sndcp_pcomp.h @@ -0,0 +1,46 @@ +/* GPRS SNDCP header compression handler */ + +/* (C) 2016 by sysmocom s.f.m.c. GmbH + * All Rights Reserved + * + * Author: Philipp Maier + * + * 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 . + */ + +#pragma once + +#include +#include +#include + +/* Note: The decompressed packet may have a maximum size of: + * Return value + MAX_DECOMPR_INCR */ +#define MAX_HDRDECOMPR_INCR 64 + +/* Initalize header compression */ +int gprs_sndcp_pcomp_init(const void *ctx, struct gprs_sndcp_comp *comp_entity, + const struct gprs_sndcp_comp_field *comp_field); + +/* Terminate header compression */ +void gprs_sndcp_pcomp_term(struct gprs_sndcp_comp *comp_entity); + +/* Expand packet header */ +int gprs_sndcp_pcomp_expand(uint8_t *data, unsigned int len, uint8_t pcomp, + const struct llist_head *comp_entities); + +/* Compress packet header */ +int gprs_sndcp_pcomp_compress(uint8_t *data, unsigned int len, uint8_t *pcomp, + const struct llist_head *comp_entities, + uint8_t nsapi); diff --git a/include/osmocom/sgsn/gprs_sndcp_xid.h b/include/osmocom/sgsn/gprs_sndcp_xid.h new file mode 100644 index 000000000..e64bc5237 --- /dev/null +++ b/include/osmocom/sgsn/gprs_sndcp_xid.h @@ -0,0 +1,218 @@ +/* GPRS SNDCP XID field encoding/decoding as per 3GPP TS 44.065 */ + +/* (C) 2016 by sysmocom s.f.m.c. GmbH + * All Rights Reserved + * + * Author: Philipp Maier + * + * 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 . + */ + +#pragma once + +#include +#include + +#define DEFAULT_SNDCP_VERSION 0 /* See 3GPP TS 44.065, clause 8 */ +#define MAX_ENTITIES 32 /* 3GPP TS 44.065 reserves 5 bit + * for compression enitity number */ + +#define MAX_COMP 16 /* Maximum number of possible pcomp/dcomp values */ +#define MAX_NSAPI 11 /* Maximum number usable NSAPIs */ +#define MAX_ROHC 16 /* Maximum number of ROHC compression profiles */ + +/* According to: 3GPP TS 44.065, 6.5.1.1 Format of the protocol control + * information compression field (Figure 7) and 3GPP TS 44.065, + * 6.6.1.1 Format of the data compression field (Figure 9) */ +struct gprs_sndcp_comp_field { + struct llist_head list; + + /* Propose bit (P), see also: 6.5.1.1.2 and 6.6.1.1.2 */ + unsigned int p; + + /* Entity number, see also: 6.5.1.1.3 and 6.6.1.1.3 */ + unsigned int entity; + + /* Algorithm identifier, see also: 6.5.1.1.4 and 6.6.1.1.4 */ + int algo; + + /* Number of contained PCOMP / DCOMP values */ + uint8_t comp_len; + + /* PCOMP / DCOMP values, see also: 6.5.1.1.5 and 6.6.1.1.5 */ + uint8_t comp[MAX_COMP]; + + /* Note: Only one of the following struct pointers may, + be used. Unused pointers must be set to NULL! */ + struct gprs_sndcp_pcomp_rfc1144_params *rfc1144_params; + struct gprs_sndcp_pcomp_rfc2507_params *rfc2507_params; + struct gprs_sndcp_pcomp_rohc_params *rohc_params; + struct gprs_sndcp_dcomp_v42bis_params *v42bis_params; + struct gprs_sndcp_dcomp_v44_params *v44_params; +}; + +/* According to: 3GPP TS 44.065, 6.5.1.1.4 Algorithm identifier */ +enum gprs_sndcp_hdr_comp_algo { + RFC_1144, /* TCP/IP header compression, see also 6.5.2 */ + RFC_2507, /* TCP/UDP/IP header compression, see also: 6.5.3 */ + ROHC /* Robust Header Compression, see also 6.5.4 */ +}; + +/* According to: 3GPP TS 44.065, 6.5.1.1.4 Algorithm identifier */ +enum gprs_sndcp_data_comp_algo { + V42BIS, /* V.42bis data compression, see also 6.6.2 */ + V44 /* V44 data compression, see also: 6.6.3 */ +}; + +/* According to: 3GPP TS 44.065, 8 SNDCP XID parameters */ +enum gprs_sndcp_xid_param_types { + SNDCP_XID_VERSION_NUMBER, + SNDCP_XID_DATA_COMPRESSION, /* See also: subclause 6.6.1 */ + SNDCP_XID_PROTOCOL_COMPRESSION, /* See also: subclause 6.5.1 */ +}; + +/* According to: 3GPP TS 44.065, 6.5.2.1 Parameters (Table 5) */ +struct gprs_sndcp_pcomp_rfc1144_params { + uint8_t nsapi_len; /* Number of applicable NSAPIs + * (default 0) */ + uint8_t nsapi[MAX_NSAPI]; /* Applicable NSAPIs (default 0) */ + int s01; /* (default 15) */ +}; + +/* According to: 3GPP TS 44.065, 6.5.2.2 Assignment of PCOMP values */ +enum gprs_sndcp_pcomp_rfc1144_pcomp { + RFC1144_PCOMP1, /* Uncompressed TCP */ + RFC1144_PCOMP2, /* Compressed TCP */ + RFC1144_PCOMP_NUM /* Number of pcomp values */ +}; + +/* According to: 3GPP TS 44.065, 6.5.3.1 Parameters (Table 6) */ +struct gprs_sndcp_pcomp_rfc2507_params { + uint8_t nsapi_len; /* Number of applicable NSAPIs + * (default 0) */ + uint8_t nsapi[MAX_NSAPI]; /* Applicable NSAPIs (default 0) */ + int f_max_period; /* (default 256) */ + int f_max_time; /* (default 5) */ + int max_header; /* (default 168) */ + int tcp_space; /* (default 15) */ + int non_tcp_space; /* (default 15) */ +}; + +/* According to: 3GPP TS 44.065, 6.5.3.2 Assignment of PCOMP values for RFC2507 */ +enum gprs_sndcp_pcomp_rfc2507_pcomp { + RFC2507_PCOMP1, /* Full Header */ + RFC2507_PCOMP2, /* Compressed TCP */ + RFC2507_PCOMP3, /* Compressed TCP non delta */ + RFC2507_PCOMP4, /* Compressed non TCP */ + RFC2507_PCOMP5, /* Context state */ + RFC2507_PCOMP_NUM /* Number of pcomp values */ +}; + +/* According to: 3GPP TS 44.065, 6.5.4.1 Parameter (Table 10) */ +struct gprs_sndcp_pcomp_rohc_params { + uint8_t nsapi_len; /* Number of applicable NSAPIs + * (default 0) */ + uint8_t nsapi[MAX_NSAPI]; /* Applicable NSAPIs (default 0) */ + int max_cid; /* (default 15) */ + int max_header; /* (default 168) */ + uint8_t profile_len; /* (default 1) */ + uint16_t profile[MAX_ROHC]; /* (default 0, ROHC uncompressed) */ +}; + +/* According to: 3GPP TS 44.065, 6.5.4.2 Assignment of PCOMP values for ROHC */ +enum gprs_sndcp_pcomp_rohc_pcomp { + ROHC_PCOMP1, /* ROHC small CIDs */ + ROHC_PCOMP2, /* ROHC large CIDs */ + ROHC_PCOMP_NUM /* Number of pcomp values */ +}; + +/* ROHC compression profiles, see also: + http://www.iana.org/assignments/rohc-pro-ids/rohc-pro-ids.xhtml */ +enum gprs_sndcp_xid_rohc_profiles { + ROHC_UNCOMPRESSED = 0x0000, /* ROHC uncompressed [RFC5795] */ + ROHC_RTP = 0x0001, /* ROHC RTP [RFC3095] */ + ROHCV2_RTP = 0x0101, /* ROHCv2 RTP [RFC5225] */ + ROHC_UDP = 0x0002, /* ROHC UDP [RFC3095] */ + ROHCv2_UDP = 0x0102, /* ROHCv2 UDP [RFC5225] */ + ROHC_ESP = 0x0003, /* ROHC ESP [RFC3095] */ + ROHCV2_ESP = 0x0103, /* ROHCv2 ESP [RFC5225] */ + ROHC_IP = 0x0004, /* ROHC IP [RFC3843] */ + ROHCV2_IP = 0x0104, /* ROHCv2 IP [RFC5225] */ + ROHC_LLA = 0x0005, /* ROHC LLA [RFC4362] */ + ROHC_LLA_WITH_R_MODE = 0x0105, /* ROHC LLA with R-mode [RFC3408] */ + ROHC_TCP = 0x0006, /* ROHC TCP [RFC6846] */ + ROHC_RTP_UDP_LITE = 0x0007, /* ROHC RTP/UDP-Lite [RFC4019] */ + ROHCV2_RTP_UDP_LITE = 0x0107, /* ROHCv2 RTP/UDP-Lite [RFC5225] */ + ROHC_UDP_LITE = 0x0008, /* ROHC UDP-Lite [RFC4019] */ + ROHCV2_UDP_LITE = 0x0108, /* ROHCv2 UDP-Lite [RFC5225] */ +}; + +/* According to: 3GPP TS 44.065, 6.6.2.1 Parameters (Table 7a) */ +struct gprs_sndcp_dcomp_v42bis_params { + uint8_t nsapi_len; /* Number of applicable NSAPIs + * (default 0) */ + uint8_t nsapi[MAX_NSAPI]; /* Applicable NSAPIs (default 0) */ + int p0; /* (default 3) */ + int p1; /* (default 2048) */ + int p2; /* (default 20) */ + +}; + +/* According to: 3GPP TS 44.065, 6.6.2.2 Assignment of DCOMP values */ +enum gprs_sndcp_dcomp_v42bis_dcomp { + V42BIS_DCOMP1, /* V.42bis enabled */ + V42BIS_DCOMP_NUM /* Number of dcomp values */ +}; + +/* According to: 3GPP TS 44.065, 6.6.3.1 Parameters (Table 7c) */ +struct gprs_sndcp_dcomp_v44_params { + uint8_t nsapi_len; /* Number of applicable NSAPIs + * (default 0) */ + uint8_t nsapi[MAX_NSAPI]; /* Applicable NSAPIs (default 0) */ + int c0; /* (default 10000000) */ + int p0; /* (default 3) */ + int p1t; /* Refer to subclause 6.6.3.1.4 */ + int p1r; /* Refer to subclause 6.6.3.1.5 */ + int p3t; /* (default 3 x p1t) */ + int p3r; /* (default 3 x p1r) */ +}; + +/* According to: 3GPP TS 44.065, 6.6.3.2 Assignment of DCOMP values */ +enum gprs_sndcp_dcomp_v44_dcomp { + V44_DCOMP1, /* Packet method compressed */ + V44_DCOMP2, /* Multi packet method compressed */ + V44_DCOMP_NUM /* Number of dcomp values */ +}; + +/* Transform a list with compression fields into an SNDCP-XID message (dst) */ +int gprs_sndcp_compile_xid(uint8_t *dst, unsigned int dst_maxlen, + const struct llist_head *comp_fields, int version); + +/* Transform an SNDCP-XID message (src) into a list of SNDCP-XID fields */ +struct llist_head *gprs_sndcp_parse_xid(int *version, + const void *ctx, + const uint8_t *src, + unsigned int src_len, + const struct llist_head + *comp_fields_req); + +/* Find out to which compression class the specified comp-field belongs + * (header compression or data compression?) */ +int gprs_sndcp_get_compression_class( + const struct gprs_sndcp_comp_field *comp_field); + +/* Dump a list with SNDCP-XID fields (Debug) */ +void gprs_sndcp_dump_comp_fields(const struct llist_head *comp_fields, + unsigned int logl); + diff --git a/include/osmocom/sgsn/gprs_subscriber.h b/include/osmocom/sgsn/gprs_subscriber.h new file mode 100644 index 000000000..be78febff --- /dev/null +++ b/include/osmocom/sgsn/gprs_subscriber.h @@ -0,0 +1,31 @@ +/* GPRS subscriber details for use in SGSN land */ +#pragma once + +#include + +#include +#include + +extern struct llist_head * const gprs_subscribers; + +struct gprs_subscr { + struct llist_head entry; + int use_count; + + char imsi[GSM23003_IMSI_MAX_DIGITS+1]; + uint32_t tmsi; + char imei[GSM23003_IMEISV_NUM_DIGITS+1]; + bool authorized; + bool keep_in_ram; + uint32_t flags; + uint16_t lac; + + struct sgsn_subscriber_data *sgsn_data; +}; + +struct gprs_subscr *_gprs_subscr_get(struct gprs_subscr *gsub, + const char *file, int line); +struct gprs_subscr *_gprs_subscr_put(struct gprs_subscr *gsub, + const char *file, int line); +#define gprs_subscr_get(gsub) _gprs_subscr_get(gsub, __BASE_FILE__, __LINE__) +#define gprs_subscr_put(gsub) _gprs_subscr_put(gsub, __BASE_FILE__, __LINE__) diff --git a/include/osmocom/sgsn/gprs_utils.h b/include/osmocom/sgsn/gprs_utils.h new file mode 100644 index 000000000..e06364dad --- /dev/null +++ b/include/osmocom/sgsn/gprs_utils.h @@ -0,0 +1,55 @@ +/* GPRS utility functions */ + +/* (C) 2010 by Harald Welte + * (C) 2010-2014 by On-Waves + * (C) 2013 by Holger Hans Peter Freyther + * All Rights Reserved + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + * + */ +#pragma once + +#include +#include + +#include + +struct msgb; +struct gprs_ra_id; + +struct msgb *gprs_msgb_copy(const struct msgb *msg, const char *name); +int gprs_msgb_resize_area(struct msgb *msg, uint8_t *area, + size_t old_size, size_t new_size); +int gprs_str_to_apn(uint8_t *apn_enc, size_t max_len, const char *str); + +/* GSM 04.08, 10.5.7.3 GPRS Timer */ +int gprs_tmr_to_secs(uint8_t tmr); +uint8_t gprs_secs_to_tmr_floor(int secs); + +int gprs_is_mi_tmsi(const uint8_t *value, size_t value_len); +int gprs_is_mi_imsi(const uint8_t *value, size_t value_len); +int gprs_parse_mi_tmsi(const uint8_t *value, size_t value_len, uint32_t *tmsi); +void gprs_parse_tmsi(const uint8_t *value, uint32_t *tmsi); + +int gprs_ra_id_equals(const struct gprs_ra_id *id1, const struct gprs_ra_id *id2); + +#define GSM48_ALLOC_SIZE 2048 +#define GSM48_ALLOC_HEADROOM 256 + +static inline struct msgb *gsm48_msgb_alloc_name(const char *name) +{ + return msgb_alloc_headroom(GSM48_ALLOC_SIZE, GSM48_ALLOC_HEADROOM, + name); +} diff --git a/include/osmocom/sgsn/gsup_client.h b/include/osmocom/sgsn/gsup_client.h new file mode 100644 index 000000000..29092ad5b --- /dev/null +++ b/include/osmocom/sgsn/gsup_client.h @@ -0,0 +1,63 @@ +/* GPRS Subscriber Update Protocol client */ + +/* (C) 2014 by Sysmocom s.f.m.c. GmbH + * All Rights Reserved + * + * Author: Jacob Erlbeck + * + * 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 . + * + */ +#pragma once + +#include + +#include + +#define GSUP_CLIENT_RECONNECT_INTERVAL 10 +#define GSUP_CLIENT_PING_INTERVAL 20 + +struct msgb; +struct ipa_client_conn; +struct gsup_client; + +/* Expects message in msg->l2h */ +typedef int (*gsup_client_read_cb_t)(struct gsup_client *gsupc, + struct msgb *msg); + +struct gsup_client { + const char *unit_name; + + struct ipa_client_conn *link; + gsup_client_read_cb_t read_cb; + void *data; + + struct oap_client_state oap_state; + + struct osmo_timer_list ping_timer; + struct osmo_timer_list connect_timer; + int is_connected; + int got_ipa_pong; +}; + +struct gsup_client *gsup_client_create(const char *unit_name, + const char *ip_addr, + unsigned int tcp_port, + gsup_client_read_cb_t read_cb, + struct oap_client_config *oapc_config); + +void gsup_client_destroy(struct gsup_client *gsupc); +int gsup_client_send(struct gsup_client *gsupc, struct msgb *msg); +struct msgb *gsup_client_msgb_alloc(void); + diff --git a/include/osmocom/sgsn/gtphub.h b/include/osmocom/sgsn/gtphub.h new file mode 100644 index 000000000..8fd9f38cf --- /dev/null +++ b/include/osmocom/sgsn/gtphub.h @@ -0,0 +1,523 @@ +/* GTP Hub Implementation */ + +/* (C) 2015 by sysmocom s.f.m.c. GmbH + * All Rights Reserved + * + * Author: Neels Hofmeyr + * + * 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 . + */ + +#pragma once + +#include +#include + +#include +#include +#include + +#include + + +/* support */ + +/* TODO move to osmocom/core/socket.c ? */ +#include /* for IPPROTO_* etc */ +struct osmo_sockaddr { + struct sockaddr_storage a; + socklen_t l; +}; + +/* TODO move to osmocom/core/socket.c ? */ +/*! \brief Initialize a sockaddr + * \param[out] addr Valid osmo_sockaddr pointer to write result to + * \param[in] family Address Family like AF_INET, AF_INET6, AF_UNSPEC + * \param[in] type Socket type like SOCK_DGRAM, SOCK_STREAM + * \param[in] proto Protocol like IPPROTO_TCP, IPPROTO_UDP + * \param[in] host Remote host name or IP address in string form + * \param[in] port Remote port number in host byte order + * \returns 0 on success, otherwise an error code (from getaddrinfo()). + * + * Copy the first result from a getaddrinfo() call with the given parameters to + * *addr and *addr_len. On error, do not change *addr and return nonzero. + */ +int osmo_sockaddr_init(struct osmo_sockaddr *addr, + uint16_t family, uint16_t type, uint8_t proto, + const char *host, uint16_t port); + +/* Conveniently pass AF_UNSPEC, SOCK_DGRAM and IPPROTO_UDP to + * osmo_sockaddr_init(). */ +static inline int osmo_sockaddr_init_udp(struct osmo_sockaddr *addr, + const char *host, uint16_t port) +{ + return osmo_sockaddr_init(addr, AF_UNSPEC, SOCK_DGRAM, IPPROTO_UDP, + host, port); +} + +/*! \brief convert sockaddr to human readable string. + * \param[out] addr_str Valid pointer to a buffer of length addr_str_len. + * \param[in] addr_str_len Size of buffer addr_str points at. + * \param[out] port_str Valid pointer to a buffer of length port_str_len. + * \param[in] port_str_len Size of buffer port_str points at. + * \param[in] addr Binary representation as returned by osmo_sockaddr_init(). + * \param[in] flags flags as passed to getnameinfo(). + * \returns 0 on success, an error code on error. + * + * Return the IPv4 or IPv6 address string and the port (a.k.a. service) string + * representations of the given struct osmo_sockaddr in two caller provided + * char buffers. Flags of (NI_NUMERICHOST | NI_NUMERICSERV) return numeric + * address and port. Either one of addr_str or port_str may be NULL, in which + * case nothing is returned there. + * + * See also osmo_sockaddr_to_str() (less flexible, but much more convenient). */ +int osmo_sockaddr_to_strs(char *addr_str, size_t addr_str_len, + char *port_str, size_t port_str_len, + const struct osmo_sockaddr *addr, + int flags); + + +/*! \brief concatenate the parts returned by osmo_sockaddr_to_strs(). + * \param[in] addr Binary representation as returned by osmo_sockaddr_init(). + * \param[in] buf A buffer to use for string operations. + * \param[in] buf_len Length of the buffer. + * \returns Address string (in buffer). + * + * Compose a string of the numeric IP-address and port represented by *addr of + * the form " port ". The returned string is valid until the + * next invocation of this function. + */ +const char *osmo_sockaddr_to_strb(const struct osmo_sockaddr *addr, + char *buf, size_t buf_len); + +/*! \brief conveniently return osmo_sockaddr_to_strb() in a static buffer. + * \param[in] addr Binary representation as returned by osmo_sockaddr_init(). + * \returns Address string in static buffer. + * + * See osmo_sockaddr_to_strb(). + * + * Note: only one osmo_sockaddr_to_str() call will work per print/log + * statement. For two or more, use osmo_sockaddr_to_strb() with a separate + * buffer each. + */ +const char *osmo_sockaddr_to_str(const struct osmo_sockaddr *addr); + +/*! \brief compare two osmo_sockaddr. + * \param[in] a The first address to compare. + * \param[in] b The other address to compare. + * \returns 0 if equal, otherwise -1 or 1. + */ +int osmo_sockaddr_cmp(const struct osmo_sockaddr *a, + const struct osmo_sockaddr *b); + +/*! \brief Overwrite *dst with *src. + * Like memcpy(), but copy only the valid bytes. */ +void osmo_sockaddr_copy(struct osmo_sockaddr *dst, + const struct osmo_sockaddr *src); + + +/* general */ + +enum gtphub_plane_idx { + GTPH_PLANE_CTRL = 0, + GTPH_PLANE_USER = 1, + GTPH_PLANE_N +}; + +enum gtphub_side_idx { + GTPH_SIDE_SGSN = 0, + GTPH_SIDE_GGSN = 1, + GTPH_SIDE_N +}; + +#define for_each_side(I) for (I = 0; I < GTPH_SIDE_N; I++) +#define for_each_plane(I) for (I = 0; I < GTPH_PLANE_N; I++) +#define for_each_side_and_plane(I,J) for_each_side(I) for_each_plane(J) + +static inline int other_side_idx(int side_idx) +{ + return (side_idx + 1) & 1; +} + +extern const char* const gtphub_plane_idx_names[GTPH_PLANE_N]; +extern const uint16_t gtphub_plane_idx_default_port[GTPH_PLANE_N]; + +extern const char* const gtphub_side_idx_names[GTPH_SIDE_N]; + +/* A host address in the form that is expected in the 7.7.32 GSN Address IE. + * len is either 4 (IPv4) or 16 (IPv6), any other value is invalid. If no + * address is set, len shall be 0. */ +struct gsn_addr { + uint16_t len; + uint8_t buf[16]; +}; + +void gsn_addr_copy(struct gsn_addr *gsna, const struct gsn_addr *src); +int gsn_addr_from_str(struct gsn_addr *gsna, const char *numeric_addr_str); + +/* Return gsna in numeric string form, in a static buffer. */ +const char *gsn_addr_to_str(const struct gsn_addr *gsna); + +/* note: strbuf_len doesn't need to be larger than INET6_ADDRSTRLEN + 1. */ +const char *gsn_addr_to_strb(const struct gsn_addr *gsna, + char *strbuf, int strbuf_len); + +/* Return 1 on match, zero otherwise. */ +int gsn_addr_same(const struct gsn_addr *a, const struct gsn_addr *b); + +/* Decode sa to gsna. Return 0 on success. If port is non-NULL, the port number + * from sa is also returned. */ +int gsn_addr_from_sockaddr(struct gsn_addr *gsna, uint16_t *port, + const struct osmo_sockaddr *sa); + +/* expiry */ + +struct expiring_item; +typedef void (*del_cb_t)(struct expiring_item *); + +struct expiring_item { + struct llist_head entry; + time_t expiry; + del_cb_t del_cb; +}; + +struct expiry { + int expiry_in_seconds; + struct llist_head items; +}; + +/* Initialize an expiry queue. */ +void expiry_init(struct expiry *exq, int expiry_in_seconds); + +/* Add a new mapping, or restart the expiry timeout for an already listed + * mapping. */ +void expiry_add(struct expiry *exq, struct expiring_item *item, time_t now); + +/* Initialize to all-empty; must be called before using the item in any way. */ +void expiring_item_init(struct expiring_item *item); + +/* Remove the given item from its expiry queue, and call item->del_cb, if set. + * This sets item->del_cb to NULL and is harmless when run a second time on the + * same item, so the del_cb may choose to call this function, too, to allow + * deleting items from several code paths. */ +void expiring_item_del(struct expiring_item *item); + +/* Carry out due expiry of mappings. Must be invoked regularly. + * 'now' is the current clock count in seconds and must correspond to the clock + * count passed to nr_map_add(). A monotonous clock counter should be used. */ +int expiry_tick(struct expiry *exq, time_t now); + +/* Expire all items. */ +void expiry_clear(struct expiry *exq); + + +/* number map */ + +/* A number map assigns a "random" mapped number to each user provided number. + * If the same number is requested multiple times, the same mapped number is + * returned. + * + * Number maps plug into possibly shared pools and expiry queues, for example: + * + * mapA -----------+-> pool1 <-+-- mapB + * {10->1, 11->5} | {1, 2, 3, ...} | {10->2, 11->3} + * | | + * | | + * /-> \-> expiry1 <-/ + * | (30 seconds) + * | + * mapC -------+-----> pool2 <-+-- mapD + * {10->1, 11->3} {1, 2, 3, ...} | {10->2, 11->5} + * | + * expiry2 <-/ + * (60 seconds) + * + * A map contains mappings ("10->1"). Each map needs a number pool, which can + * be shared with other maps. Each new mapping receives a number from the pool, + * which is then unavailable to any other map using the same pool. + * + * A map may point at an expiry queue, in which case all mappings added to it + * are also appended to the expiry queue (using a separate llist entry in the + * mapping). Any number of maps may submit to the same expiry queue, if they + * desire the same expiry timeout. An expiry queue stores the mappings in + * chronological order, so that expiry checking is needed only from the start + * of the queue; hence only mappings with identical expiry timeout can be added + * to the same expiry queue. Upon expiry, a mapping is dropped from the map it + * was submitted at. expiry_tick() needs to be called regularly for each expiry + * queue. + * + * A nr_mapping can be embedded in a larger struct: each mapping can have a + * distinct destructor (del_cb), and each del_cb can figure out the container + * struct's address and free that upon expiry or manual deletion. So in expiry + * queues (and even maps), mappings of different container types can be mixed. + * This can help to drastically reduce the amount of unnecessary visits during + * expiry checking, for the case that no expiry is pending. An expiry queue + * always knows which mappings to expire next, because they are right at the + * start of its list. + * + * Mapping allocation and a del_cb are provided by the caller. If del_cb is + * NULL, no deallocation will be done (allowing statically allocated entries). + */ + +typedef unsigned int nr_t; + +/* Generator for unused numbers. So far this counts upwards from zero, but the + * implementation may change in the future. Treat this like an opaque struct. + * If this becomes random, the tests need to be fixed. */ +struct nr_pool { + nr_t last_nr; + nr_t nr_min; + nr_t nr_max; +}; + +struct nr_mapping { + struct llist_head entry; + struct expiring_item expiry_entry; + + void *origin; + nr_t orig; + nr_t repl; +}; + +struct nr_map { + struct nr_pool *pool; /* multiple nr_maps can share a nr_pool. */ + struct expiry *add_items_to_expiry; + struct llist_head mappings; +}; + + +void nr_pool_init(struct nr_pool *pool, nr_t nr_min, nr_t nr_max); + +/* Return the next unused number from the nr_pool. */ +nr_t nr_pool_next(struct nr_pool *pool); + +/* Initialize the nr_mapping to zero/empty values. */ +void nr_mapping_init(struct nr_mapping *mapping); + +/* Remove the given mapping from its parent map and expiry queue, and call + * mapping->del_cb, if set. */ +void nr_mapping_del(struct nr_mapping *mapping); + +/* Initialize an (already allocated) nr_map, and set the map's number pool. + * Multiple nr_map instances may use the same nr_pool. Set the nr_map's expiry + * queue to exq, so that all added mappings are automatically expired after the + * time configured in exq. exq may be NULL to disable automatic expiry. */ +void nr_map_init(struct nr_map *map, struct nr_pool *pool, + struct expiry *exq); + +/* Add a new entry to the map. mapping->orig, mapping->origin and + * mapping->del_cb must be set before calling this function. The remaining + * fields of *mapping will be overwritten. mapping->repl is set to the next + * available mapped number from map->pool. 'now' is the current clock count in + * seconds; if no map->expiry is used, just pass 0 for 'now'. */ +void nr_map_add(struct nr_map *map, struct nr_mapping *mapping, + time_t now); + +/* Restart the timeout for the given mapping. mapping must be a member of map. + */ +void nr_map_refresh(struct nr_map *map, struct nr_mapping *mapping, + time_t now); + +/* Return a known mapping from nr_orig and the given origin. If nr_orig is + * unknown, return NULL. */ +struct nr_mapping *nr_map_get(const struct nr_map *map, + void *origin, nr_t nr_orig); + +/* Return a known mapping to nr_repl. If nr_repl is unknown, return NULL. */ +struct nr_mapping *nr_map_get_inv(const struct nr_map *map, nr_t nr_repl); + +/* Remove all mappings from map. */ +void nr_map_clear(struct nr_map *map); + +/* Return 1 if map has no entries, 0 otherwise. */ +int nr_map_empty(const struct nr_map *map); + + +/* config */ + +static const int GTPH_EXPIRE_QUICKLY_SECS = 30; /* TODO is there a spec for this? */ +static const int GTPH_EXPIRE_SLOWLY_MINUTES = 6 * 60; /* TODO is there a spec for this? */ + +struct gtphub_cfg_addr { + const char *addr_str; + uint16_t port; +}; + +struct gtphub_cfg_bind { + struct gtphub_cfg_addr bind; +}; + +struct gtphub_cfg { + struct gtphub_cfg_bind to_gsns[GTPH_SIDE_N][GTPH_PLANE_N]; + struct gtphub_cfg_addr proxy[GTPH_SIDE_N][GTPH_PLANE_N]; + int sgsn_use_sender; /* Use sender, not GSN addr IE with std ports */ +}; + + +/* state */ + +struct gtphub_peer { + struct llist_head entry; + + struct llist_head addresses; /* Alternatives, not load balancing. */ + struct nr_pool seq_pool; + struct nr_map seq_map; +}; + +struct gtphub_peer_addr { + struct llist_head entry; + + struct gtphub_peer *peer; + struct gsn_addr addr; + struct llist_head ports; +}; + +struct gtphub_peer_port { + struct llist_head entry; + + struct gtphub_peer_addr *peer_addr; + uint16_t port; + unsigned int ref_count; /* references from other peers' seq_maps */ + struct osmo_sockaddr sa; /* a "cache" for (peer_addr->addr, port) */ + int last_restart_count; /* 0..255 = valid, all else means unknown */ + + struct rate_ctr_group *counters_io; +}; + +struct gtphub_tunnel_endpoint { + struct gtphub_peer_port *peer; + uint32_t tei_orig; /* from/to peer */ + + struct rate_ctr_group *counters_io; +}; + +struct gtphub_tunnel { + struct llist_head entry; + struct expiring_item expiry_entry; + + uint32_t tei_repl; /* unique TEI to replace peers' TEIs */ + struct gtphub_tunnel_endpoint endpoint[GTPH_SIDE_N][GTPH_PLANE_N]; +}; + +struct gtphub_bind { + struct gsn_addr local_addr; + uint16_t local_port; + struct osmo_fd ofd; + + /* list of struct gtphub_peer */ + struct llist_head peers; + + const char *label; /* For logging */ + struct rate_ctr_group *counters_io; +}; + +struct gtphub_resolved_ggsn { + struct llist_head entry; + struct expiring_item expiry_entry; + + /* The APN OI, the Operator Identifier, is the combined address, + * including parts of the IMSI and APN NI, and ending with ".gprs". */ + char apn_oi_str[GSM_APN_LENGTH]; + + /* Which address and port we resolved that to. */ + struct gtphub_peer_port *peer; +}; + +struct gtphub { + struct gtphub_bind to_gsns[GTPH_SIDE_N][GTPH_PLANE_N]; + + /* pointers to an entry of to_gsns[s][p].peers */ + struct gtphub_peer_port *proxy[GTPH_SIDE_N][GTPH_PLANE_N]; + + /* The TEI numbers will simply wrap and be reused, which will work out + * in practice. Problems would arise if one given peer maintained the + * same TEI for a time long enough for the TEI nr map to wrap an entire + * uint32_t; if a new TEI were mapped every second, this would take + * more than 100 years (in which a single given TEI must not time out) + * to cause a problem. */ + struct nr_pool tei_pool; + + struct llist_head tunnels; /* struct gtphub_tunnel */ + struct llist_head pending_deletes; /* opaque (gtphub.c) */ + + struct llist_head ggsn_lookups; /* opaque (gtphub_ares.c) */ + struct llist_head resolved_ggsns; /* struct gtphub_resolved_ggsn */ + + struct osmo_timer_list gc_timer; + struct expiry expire_quickly; + struct expiry expire_slowly; + + uint8_t restart_counter; + + int sgsn_use_sender; +}; + +struct gtp_packet_desc; + + +/* api */ + +int gtphub_vty_init(struct gtphub *global_hub, struct gtphub_cfg *global_cfg); +int gtphub_cfg_read(struct gtphub_cfg *cfg, const char *config_file); + +/* Initialize and start gtphub: bind to ports, run expiry timers. */ +int gtphub_start(struct gtphub *hub, struct gtphub_cfg *cfg, + uint8_t restart_counter); + +/* Close all sockets, expire all maps and peers and free all allocations. The + * struct is then unusable, unless gtphub_start() is run on it again. */ +void gtphub_stop(struct gtphub *hub); + +time_t gtphub_now(void); + +/* Remove expired items, empty peers, ... */ +void gtphub_gc(struct gtphub *hub, time_t now); + +/* Return the string of the first address for this peer. */ +const char *gtphub_peer_str(struct gtphub_peer *peer); + +/* Return a human readable description of tun in a static buffer. */ +const char *gtphub_tunnel_str(struct gtphub_tunnel *tun); + +/* Return 1 if all of tun's endpoints are fully established, 0 otherwise. */ +int gtphub_tunnel_complete(struct gtphub_tunnel *tun); + +int gtphub_handle_buf(struct gtphub *hub, + unsigned int side_idx, + unsigned int port_idx, + const struct osmo_sockaddr *from_addr, + uint8_t *buf, + size_t received, + time_t now, + uint8_t **reply_buf, + struct osmo_fd **to_ofd, + struct osmo_sockaddr *to_addr); + +struct gtphub_peer_port *gtphub_port_have(struct gtphub *hub, + struct gtphub_bind *bind, + const struct gsn_addr *addr, + uint16_t port); + +struct gtphub_peer_port *gtphub_port_find_sa(const struct gtphub_bind *bind, + const struct osmo_sockaddr *addr); + +void gtphub_resolved_ggsn(struct gtphub *hub, const char *apn_oi_str, + struct gsn_addr *resolved_addr, + time_t now); + +const char *gtphub_port_str(struct gtphub_peer_port *port); + +int gtphub_write(const struct osmo_fd *to, + const struct osmo_sockaddr *to_addr, + const uint8_t *buf, size_t buf_len); diff --git a/include/osmocom/sgsn/oap_client.h b/include/osmocom/sgsn/oap_client.h new file mode 100644 index 000000000..80c86d5d6 --- /dev/null +++ b/include/osmocom/sgsn/oap_client.h @@ -0,0 +1,82 @@ +/* Osmocom Authentication Protocol API */ + +/* (C) 2015 by Sysmocom s.f.m.c. GmbH + * All Rights Reserved + * + * Author: Neels Hofmeyr + * + * 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 . + * + */ + +#pragma once + +#include + +struct msgb; +struct osmo_oap_message; + +/* This is the config part for vty. It is essentially copied in + * oap_client_state, where values are copied over once the config is + * considered valid. */ +struct oap_client_config { + uint16_t client_id; + int secret_k_present; + uint8_t secret_k[16]; + int secret_opc_present; + uint8_t secret_opc[16]; +}; + +/* The runtime state of the OAP client. client_id and the secrets are in fact + * duplicated from oap_client_config, so that a separate validation of the + * config data is possible, and so that only a struct oap_client_state* is + * passed around. */ +struct oap_client_state { + enum { + OAP_UNINITIALIZED = 0, /* just allocated. */ + OAP_DISABLED, /* disabled by config. */ + OAP_INITIALIZED, /* enabled, config is valid. */ + OAP_REQUESTED_CHALLENGE, + OAP_SENT_CHALLENGE_RESULT, + OAP_REGISTERED + } state; + uint16_t client_id; + uint8_t secret_k[16]; + uint8_t secret_opc[16]; + int registration_failures; +}; + +/* From config, initialize state. Return 0 on success. */ +int oap_client_init(struct oap_client_config *config, + struct oap_client_state *state); + +/* Construct an OAP registration message and return in *msg_tx. Use + * state->client_id and update state->state. + * Return 0 on success, or a negative value on error. + * If an error is returned, *msg_tx is guaranteed to be NULL. */ +int oap_client_register(struct oap_client_state *state, struct msgb **msg_tx); + +/* Decode and act on a received OAP message msg_rx. Update state->state. If a + * non-NULL pointer is returned in *msg_tx, that msgb should be sent to the OAP + * server (and freed) by the caller. The received msg_rx is not freed. + * Return 0 on success, or a negative value on error. + * If an error is returned, *msg_tx is guaranteed to be NULL. */ +int oap_client_handle(struct oap_client_state *state, + const struct msgb *msg_rx, struct msgb **msg_tx); + +/* Allocate a msgb and in it, return the encoded oap_client_msg. Return + * NULL on error. (Like oap_client_encode(), but also allocates a msgb.) + * About the name: the idea is do_something(oap_client_encoded(my_struct)) + */ +struct msgb *oap_client_encoded(const struct osmo_oap_message *oap_client_msg); diff --git a/include/osmocom/sgsn/rest_octets.h b/include/osmocom/sgsn/rest_octets.h new file mode 100644 index 000000000..0dbe7ae13 --- /dev/null +++ b/include/osmocom/sgsn/rest_octets.h @@ -0,0 +1,139 @@ +#ifndef _REST_OCTETS_H +#define _REST_OCTETS_H + +#include +#include +#include + +/* generate SI1 rest octets */ +int rest_octets_si1(uint8_t *data, uint8_t *nch_pos, int is1800_net); +int rest_octets_si2quater(uint8_t *data, struct gsm_bts *bts); +int rest_octets_si6(uint8_t *data, bool is1800_net); + +struct gsm48_si_selection_params { + uint16_t penalty_time:5, + temp_offs:3, + cell_resel_off:6, + cbq:1, + present:1; +}; + +struct gsm48_si_power_offset { + uint8_t power_offset:2, + present:1; +}; + +struct gsm48_si3_gprs_ind { + uint8_t si13_position:1, + ra_colour:3, + present:1; +}; + +struct gsm48_lsa_params { + uint32_t prio_thr:3, + lsa_offset:3, + mcc:12, + mnc:12; + unsigned int present; +}; + +struct gsm48_si_ro_info { + struct gsm48_si_selection_params selection_params; + struct gsm48_si_power_offset power_offset; + uint8_t si2ter_indicator; + uint8_t early_cm_ctrl; + struct { + uint8_t where:3, + present:1; + } scheduling; + struct gsm48_si3_gprs_ind gprs_ind; + /* SI 3 specific */ + uint8_t si2quater_indicator; + /* SI 4 specific */ + struct gsm48_lsa_params lsa_params; + uint16_t cell_id; + uint8_t break_ind; /* do we have SI7 + SI8 ? */ +}; + + +/* Generate SI3 Rest Octests (Chapter 10.5.2.34 / Table 10.4.72) */ +int rest_octets_si3(uint8_t *data, const struct gsm48_si_ro_info *si3); + +/* Generate SI4 Rest Octets (Chapter 10.5.2.35) */ +int rest_octets_si4(uint8_t *data, const struct gsm48_si_ro_info *si4, int len); + +enum pbcch_carrier_type { + PBCCH_BCCH, + PBCCH_ARFCN, + PBCCH_MAIO +}; + +/* TS 03.60 Chapter 6.3.3.1: Network Mode of Operation */ +enum gprs_nmo { + GPRS_NMO_I = 0, /* CS pagin on GPRS paging or traffic channel */ + GPRS_NMO_II = 1, /* all paging on CCCH */ + GPRS_NMO_III = 2, /* no paging coordination */ +}; + +/* TS 04.60 12.24 */ +struct gprs_cell_options { + enum gprs_nmo nmo; + /* T3168: wait for packet uplink assignment message */ + uint32_t t3168; /* in milliseconds */ + /* T3192: wait for release of the TBF after reception of the final block */ + uint32_t t3192; /* in milliseconds */ + uint32_t drx_timer_max;/* in seconds */ + uint32_t bs_cv_max; + uint8_t supports_egprs_11bit_rach; + bool ctrl_ack_type_use_block; /* use PACKET CONTROL ACKNOWLEDGMENT */ + + uint8_t ext_info_present; + struct { + uint8_t egprs_supported; + uint8_t use_egprs_p_ch_req; + uint8_t bep_period; + uint8_t pfc_supported; + uint8_t dtm_supported; + uint8_t bss_paging_coordination; + } ext_info; +}; + +/* TS 04.60 Table 12.9.2 */ +struct gprs_power_ctrl_pars { + uint8_t alpha; + uint8_t t_avg_w; + uint8_t t_avg_t; + uint8_t pc_meas_chan; + uint8_t n_avg_i; +}; + +struct gsm48_si13_info { + struct gprs_cell_options cell_opts; + struct gprs_power_ctrl_pars pwr_ctrl_pars; + uint8_t bcch_change_mark; + uint8_t si_change_field; + uint8_t pbcch_present; + + union { + struct { + uint8_t rac; + uint8_t spgc_ccch_sup; + uint8_t net_ctrl_ord; + uint8_t prio_acc_thr; + } no_pbcch; + struct { + uint8_t psi1_rep_per; + uint8_t pb; + uint8_t tsc; + uint8_t tn; + enum pbcch_carrier_type carrier_type; + uint16_t arfcn; + uint8_t maio; + } pbcch; + }; +}; + +/* Generate SI13 Rest Octests (Chapter 10.5.2.37b) */ +int rest_octets_si13(uint8_t *data, const struct gsm48_si13_info *si13); + +#endif /* _REST_OCTETS_H */ diff --git a/include/osmocom/sgsn/sgsn.h b/include/osmocom/sgsn/sgsn.h new file mode 100644 index 000000000..e4eda17d2 --- /dev/null +++ b/include/osmocom/sgsn/sgsn.h @@ -0,0 +1,191 @@ +#ifndef _SGSN_H +#define _SGSN_H + + +#include +#include +#include +#include +#include +#include + +#include + +struct gprs_gsup_client; +struct hostent; + +enum sgsn_auth_policy { + SGSN_AUTH_POLICY_OPEN, + SGSN_AUTH_POLICY_CLOSED, + SGSN_AUTH_POLICY_ACL_ONLY, + SGSN_AUTH_POLICY_REMOTE +}; + + +enum sgsn_rate_ctr_keys { + CTR_LLC_DL_BYTES, + CTR_LLC_UL_BYTES, + CTR_LLC_DL_PACKETS, + CTR_LLC_UL_PACKETS, + CTR_GPRS_ATTACH_REQUEST, + CTR_GPRS_ATTACH_ACKED, + CTR_GPRS_ATTACH_REJECTED, + CTR_GPRS_DETACH_REQUEST, + CTR_GPRS_DETACH_ACKED, + CTR_GPRS_ROUTING_AREA_REQUEST, + CTR_GPRS_ROUTING_AREA_ACKED, + CTR_GPRS_ROUTING_AREA_REJECT, + /* PDP single packet counter / GSM 04.08 9.5.1 - 9.5.9 */ + CTR_PDP_ACTIVATE_REQUEST, + CTR_PDP_ACTIVATE_REJECT, + CTR_PDP_ACTIVATE_ACCEPT, + CTR_PDP_REQUEST_ACTIVATE, /* unused */ + CTR_PDP_REQUEST_ACTIVATE_REJ, /* unused */ + CTR_PDP_MODIFY_REQUEST, /* unsued */ + CTR_PDP_MODIFY_ACCEPT, /* unused */ + CTR_PDP_DL_DEACTIVATE_REQUEST, + CTR_PDP_DL_DEACTIVATE_ACCEPT, + CTR_PDP_UL_DEACTIVATE_REQUEST, + CTR_PDP_UL_DEACTIVATE_ACCEPT, +}; + +struct sgsn_cdr { + char *filename; + int interval; +}; + +struct sgsn_config { + /* parsed from config file */ + + char *gtp_statedir; + struct sockaddr_in gtp_listenaddr; + + /* misc */ + struct gprs_ns_inst *nsi; + + enum sgsn_auth_policy auth_policy; + enum gprs_ciph_algo cipher; + struct llist_head imsi_acl; + + struct sockaddr_in gsup_server_addr; + int gsup_server_port; + + int require_authentication; + int require_update_location; + + /* CDR configuration */ + struct sgsn_cdr cdr; + + struct { + int T3312; + int T3322; + int T3350; + int T3360; + int T3370; + int T3313; + int T3314; + int T3316; + int T3385; + int T3386; + int T3395; + int T3397; + } timers; + + int dynamic_lookup; + + struct oap_client_config oap; + + /* RFC1144 TCP/IP header compression */ + struct { + int active; + int passive; + int s01; + } pcomp_rfc1144; + + /* V.42vis data compression */ + struct { + int active; + int passive; + int p0; + int p1; + int p2; + } dcomp_v42bis; + + struct { + int rab_assign_addr_enc; + } iu; +}; + +struct sgsn_instance { + char *config_file; + struct sgsn_config cfg; + /* File descriptor wrappers for LibGTP */ + struct osmo_fd gtp_fd0; + struct osmo_fd gtp_fd1c; + struct osmo_fd gtp_fd1u; + /* Timer for libGTP */ + struct osmo_timer_list gtp_timer; + /* GSN instance for libgtp */ + struct gsn_t *gsn; + /* Subscriber */ + struct gsup_client *gsup_client; + /* LLME inactivity timer */ + struct osmo_timer_list llme_timer; + + /* c-ares event loop integration */ + struct osmo_timer_list ares_timer; + struct llist_head ares_fds; + ares_channel ares_channel; + struct ares_addr_node *ares_servers; + + struct rate_ctr_group *rate_ctrs; +}; + +extern struct sgsn_instance *sgsn; + +/* sgsn_vty.c */ + +int sgsn_vty_init(struct sgsn_config *cfg); +int sgsn_parse_config(const char *config_file); + +/* sgsn.c */ + +/* Main input function for Gb proxy */ +int sgsn_rcvmsg(struct msgb *msg, struct gprs_nsvc *nsvc, uint16_t ns_bvci); + + +struct sgsn_pdp_ctx *sgsn_create_pdp_ctx(struct sgsn_ggsn_ctx *ggsn, + struct sgsn_mm_ctx *mmctx, + uint16_t nsapi, + struct tlv_parsed *tp); +int sgsn_delete_pdp_ctx(struct sgsn_pdp_ctx *pctx); +void sgsn_pdp_upd_gtp_u(struct sgsn_pdp_ctx *pdp, void *addr, size_t alen); + +/* gprs_sndcp.c */ + +/* Entry point for the SNSM-ACTIVATE.indication */ +int sndcp_sm_activate_ind(struct gprs_llc_lle *lle, uint8_t nsapi); +/* Entry point for the SNSM-DEACTIVATE.indication */ +int sndcp_sm_deactivate_ind(struct gprs_llc_lle *lle, uint8_t nsapi); +/* Called by SNDCP when it has received/re-assembled a N-PDU */ +int sgsn_rx_sndcp_ud_ind(struct gprs_ra_id *ra_id, int32_t tlli, uint8_t nsapi, + struct msgb *msg, uint32_t npdu_len, uint8_t *npdu); +int sndcp_unitdata_req(struct msgb *msg, struct gprs_llc_lle *lle, uint8_t nsapi, + void *mmcontext); +int sndcp_llunitdata_ind(struct msgb *msg, struct gprs_llc_lle *lle, + uint8_t *hdr, uint16_t len); + + +/* + * CDR related functionality + */ +int sgsn_cdr_init(struct sgsn_instance *sgsn); + + +/* + * C-ARES related functionality + */ +int sgsn_ares_init(struct sgsn_instance *sgsn); +int sgsn_ares_query(struct sgsn_instance *sgsm, const char *name, ares_host_callback cb, void *data); + +#endif diff --git a/include/osmocom/sgsn/signal.h b/include/osmocom/sgsn/signal.h new file mode 100644 index 000000000..4b6ba56f6 --- /dev/null +++ b/include/osmocom/sgsn/signal.h @@ -0,0 +1,52 @@ +/* Generic signalling/notification infrastructure */ +/* (C) 2009-2010, 2015 by Holger Hans Peter Freyther + * (C) 2009 by Harald Welte + * (C) 2010 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 . + * + */ + +#ifndef OPENBSC_SIGNAL_H +#define OPENBSC_SIGNAL_H + +#include +#include + +#include + +enum signal_subsystems { + SS_SGSN, +}; + +/* GPRS SGSN signals SS_SGSN */ +enum signal_sgsn { + S_SGSN_ATTACH, + S_SGSN_DETACH, + S_SGSN_UPDATE, + S_SGSN_PDP_ACT, + S_SGSN_PDP_DEACT, + S_SGSN_PDP_TERMINATE, + S_SGSN_PDP_FREE, + S_SGSN_MM_FREE, +}; + +struct sgsn_mm_ctx; +struct sgsn_signal_data { + struct sgsn_mm_ctx *mm; + struct sgsn_pdp_ctx *pdp; /* non-NULL for PDP_ACT, PDP_DEACT, PDP_FREE */ +}; + +#endif diff --git a/include/osmocom/sgsn/slhc.h b/include/osmocom/sgsn/slhc.h new file mode 100644 index 000000000..cd5a47cf4 --- /dev/null +++ b/include/osmocom/sgsn/slhc.h @@ -0,0 +1,187 @@ +#ifndef _SLHC_H +#define _SLHC_H +/* + * Definitions for tcp compression routines. + * + * $Header: slcompress.h,v 1.10 89/12/31 08:53:02 van Exp $ + * + * Copyright (c) 1989 Regents of the University of California. + * All rights reserved. + * + * Redistribution and use in source and binary forms are permitted + * provided that the above copyright notice and this paragraph are + * duplicated in all such forms and that any documentation, + * advertising materials, and other materials related to such + * distribution and use acknowledge that the software was developed + * by the University of California, Berkeley. The name of the + * University may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. + * + * Van Jacobson (van@helios.ee.lbl.gov), Dec 31, 1989: + * - Initial distribution. + * + * + * modified for KA9Q Internet Software Package by + * Katie Stevens (dkstevens@ucdavis.edu) + * University of California, Davis + * Computing Services + * - 01-31-90 initial adaptation + * + * - Feb 1991 Bill_Simpson@um.cc.umich.edu + * variable number of conversation slots + * allow zero or one slots + * separate routines + * status display + */ + +/* + * Compressed packet format: + * + * The first octet contains the packet type (top 3 bits), TCP + * 'push' bit, and flags that indicate which of the 4 TCP sequence + * numbers have changed (bottom 5 bits). The next octet is a + * conversation number that associates a saved IP/TCP header with + * the compressed packet. The next two octets are the TCP checksum + * from the original datagram. The next 0 to 15 octets are + * sequence number changes, one change per bit set in the header + * (there may be no changes and there are two special cases where + * the receiver implicitly knows what changed -- see below). + * + * There are 5 numbers which can change (they are always inserted + * in the following order): TCP urgent pointer, window, + * acknowledgment, sequence number and IP ID. (The urgent pointer + * is different from the others in that its value is sent, not the + * change in value.) Since typical use of SLIP links is biased + * toward small packets (see comments on MTU/MSS below), changes + * use a variable length coding with one octet for numbers in the + * range 1 - 255 and 3 octets (0, MSB, LSB) for numbers in the + * range 256 - 65535 or 0. (If the change in sequence number or + * ack is more than 65535, an uncompressed packet is sent.) + */ + +/* + * Packet types (must not conflict with IP protocol version) + * + * The top nibble of the first octet is the packet type. There are + * three possible types: IP (not proto TCP or tcp with one of the + * control flags set); uncompressed TCP (a normal IP/TCP packet but + * with the 8-bit protocol field replaced by an 8-bit connection id -- + * this type of packet syncs the sender & receiver); and compressed + * TCP (described above). + * + * LSB of 4-bit field is TCP "PUSH" bit (a worthless anachronism) and + * is logically part of the 4-bit "changes" field that follows. Top + * three bits are actual packet type. For backward compatibility + * and in the interest of conserving bits, numbers are chosen so the + * IP protocol version number (4) which normally appears in this nibble + * means "IP packet". + */ + + +#include +#include + +/* SLIP compression masks for len/vers byte */ +#define SL_TYPE_IP 0x40 +#define SL_TYPE_UNCOMPRESSED_TCP 0x70 +#define SL_TYPE_COMPRESSED_TCP 0x80 +#define SL_TYPE_ERROR 0x00 + +/* Bits in first octet of compressed packet */ +#define NEW_C 0x40 /* flag bits for what changed in a packet */ +#define NEW_I 0x20 +#define NEW_S 0x08 +#define NEW_A 0x04 +#define NEW_W 0x02 +#define NEW_U 0x01 + +/* reserved, special-case values of above */ +#define SPECIAL_I (NEW_S|NEW_W|NEW_U) /* echoed interactive traffic */ +#define SPECIAL_D (NEW_S|NEW_A|NEW_W|NEW_U) /* unidirectional data */ +#define SPECIALS_MASK (NEW_S|NEW_A|NEW_W|NEW_U) + +#define TCP_PUSH_BIT 0x10 + +/* + * data type and sizes conversion assumptions: + * + * VJ code KA9Q style generic + * u_char byte_t unsigned char 8 bits + * u_short int16 unsigned short 16 bits + * u_int int16 unsigned short 16 bits + * u_long unsigned long unsigned long 32 bits + * int int32 long 32 bits + */ + +typedef __u8 byte_t; +typedef __u32 int32; + +/* + * "state" data for each active tcp conversation on the wire. This is + * basically a copy of the entire IP/TCP header from the last packet + * we saw from the conversation together with a small identifier + * the transmit & receive ends of the line use to locate saved header. + */ +struct cstate { + byte_t cs_this; /* connection id number (xmit) */ + struct cstate *next; /* next in ring (xmit) */ + struct iphdr cs_ip; /* ip/tcp hdr from most recent packet */ + struct tcphdr cs_tcp; + unsigned char cs_ipopt[64]; + unsigned char cs_tcpopt[64]; + int cs_hsize; +}; +#define NULLSLSTATE (struct cstate *)0 + +/* + * all the state data for one serial line (we need one of these per line). + */ +struct slcompress { + struct cstate *tstate; /* transmit connection states (array)*/ + struct cstate *rstate; /* receive connection states (array)*/ + + byte_t tslot_limit; /* highest transmit slot id (0-l)*/ + byte_t rslot_limit; /* highest receive slot id (0-l)*/ + + byte_t xmit_oldest; /* oldest xmit in ring */ + byte_t xmit_current; /* most recent xmit id */ + byte_t recv_current; /* most recent rcvd id */ + + byte_t flags; +#define SLF_TOSS 0x01 /* tossing rcvd frames until id received */ + + int32 sls_o_nontcp; /* outbound non-TCP packets */ + int32 sls_o_tcp; /* outbound TCP packets */ + int32 sls_o_uncompressed; /* outbound uncompressed packets */ + int32 sls_o_compressed; /* outbound compressed packets */ + int32 sls_o_searches; /* searches for connection state */ + int32 sls_o_misses; /* times couldn't find conn. state */ + + int32 sls_i_uncompressed; /* inbound uncompressed packets */ + int32 sls_i_compressed; /* inbound compressed packets */ + int32 sls_i_error; /* inbound error packets */ + int32 sls_i_tossed; /* inbound packets tossed because of error */ + + int32 sls_i_runt; + int32 sls_i_badcheck; +}; +#define NULLSLCOMPR (struct slcompress *)0 + +/* In slhc.c: */ +struct slcompress *slhc_init(const void *ctx, int rslots, int tslots); + +void slhc_free(struct slcompress *comp); + +int slhc_compress(struct slcompress *comp, unsigned char *icp, int isize, + unsigned char *ocp, unsigned char **cpp, int compress_cid); +int slhc_uncompress(struct slcompress *comp, unsigned char *icp, int isize); +int slhc_remember(struct slcompress *comp, unsigned char *icp, int isize); +int slhc_toss(struct slcompress *comp); + +void slhc_i_status(struct slcompress *comp); +void slhc_o_status(struct slcompress *comp); + +#endif /* _SLHC_H */ diff --git a/include/osmocom/sgsn/v42bis.h b/include/osmocom/sgsn/v42bis.h new file mode 100644 index 000000000..607a58e51 --- /dev/null +++ b/include/osmocom/sgsn/v42bis.h @@ -0,0 +1,147 @@ +/* + * SpanDSP - a series of DSP components for telephony + * + * v42bis.h + * + * Written by Steve Underwood + * + * Copyright (C) 2005, 2011 Steve Underwood + * + * All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 2.1, + * as published by the Free Software Foundation. + * + * 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +/*! \page v42bis_page V.42bis modem data compression +\section v42bis_page_sec_1 What does it do? +The v.42bis specification defines a data compression scheme, to work in +conjunction with the error correction scheme defined in V.42. + +\section v42bis_page_sec_2 How does it work? +*/ + +#include + +#if !defined(_SPANDSP_V42BIS_H_) +#define _SPANDSP_V42BIS_H_ + +#define SPAN_DECLARE(x) x + +#define V42BIS_MIN_STRING_SIZE 6 +#define V42BIS_MAX_STRING_SIZE 250 +#define V42BIS_MIN_DICTIONARY_SIZE 512 +#define V42BIS_MAX_BITS 12 +#define V42BIS_MAX_CODEWORDS 4096 /* 2^V42BIS_MAX_BITS */ +#define V42BIS_MAX_OUTPUT_LENGTH 1024 + +enum +{ + V42BIS_P0_NEITHER_DIRECTION = 0, + V42BIS_P0_INITIATOR_RESPONDER, + V42BIS_P0_RESPONDER_INITIATOR, + V42BIS_P0_BOTH_DIRECTIONS +}; + +enum +{ + V42BIS_COMPRESSION_MODE_DYNAMIC = 0, + V42BIS_COMPRESSION_MODE_ALWAYS, + V42BIS_COMPRESSION_MODE_NEVER +}; + +typedef void (*put_msg_func_t)(void *user_data, const uint8_t *msg, int len); + +/*! + V.42bis compression/decompression descriptor. This defines the working state for a + single instance of V.42bis compress/decompression. +*/ +typedef struct v42bis_state_s v42bis_state_t; + +#if defined(__cplusplus) +extern "C" +{ +#endif + +/*! Compress a block of octets. + \param s The V.42bis context. + \param buf The data to be compressed. + \param len The length of the data buffer. + \return 0 */ +SPAN_DECLARE(int) v42bis_compress(v42bis_state_t *s, const uint8_t buf[], int len); + +/*! Flush out any data remaining in a compression buffer. + \param s The V.42bis context. + \return 0 */ +SPAN_DECLARE(int) v42bis_compress_flush(v42bis_state_t *s); + +/*! Decompress a block of octets. + \param s The V.42bis context. + \param buf The data to be decompressed. + \param len The length of the data buffer. + \return 0 */ +SPAN_DECLARE(int) v42bis_decompress(v42bis_state_t *s, const uint8_t buf[], int len); + +/*! Flush out any data remaining in the decompression buffer. + \param s The V.42bis context. + \return 0 */ +SPAN_DECLARE(int) v42bis_decompress_flush(v42bis_state_t *s); + +/*! Set the compression mode. + \param s The V.42bis context. + \param mode One of the V.42bis compression modes - + V42BIS_COMPRESSION_MODE_DYNAMIC, + V42BIS_COMPRESSION_MODE_ALWAYS, + V42BIS_COMPRESSION_MODE_NEVER */ +SPAN_DECLARE(void) v42bis_compression_control(v42bis_state_t *s, int mode); + +/*! Initialise a V.42bis context. + \param s The V.42bis context. + \param negotiated_p0 The negotiated P0 parameter, from the V.42bis spec. + \param negotiated_p1 The negotiated P1 parameter, from the V.42bis spec. + \param negotiated_p2 The negotiated P2 parameter, from the V.42bis spec. + \param encode_handler Encode callback handler. + \param encode_user_data An opaque pointer passed to the encode callback handler. + \param max_encode_len The maximum length that should be passed to the encode handler. + \param decode_handler Decode callback handler. + \param decode_user_data An opaque pointer passed to the decode callback handler. + \param max_decode_len The maximum length that should be passed to the decode handler. + \return The V.42bis context. */ +SPAN_DECLARE(v42bis_state_t *) v42bis_init(const void *ctx, + v42bis_state_t *s, + int negotiated_p0, + int negotiated_p1, + int negotiated_p2, + put_msg_func_t encode_handler, + void *encode_user_data, + int max_encode_len, + put_msg_func_t decode_handler, + void *decode_user_data, + int max_decode_len); + +/*! Release a V.42bis context. + \param s The V.42bis context. + \return 0 if OK */ +SPAN_DECLARE(int) v42bis_release(v42bis_state_t *s); + +/*! Free a V.42bis context. + \param s The V.42bis context. + \return 0 if OK */ +SPAN_DECLARE(int) v42bis_free(v42bis_state_t *s); + +#if defined(__cplusplus) +} +#endif + +#endif +/*- End of file ------------------------------------------------------------*/ diff --git a/include/osmocom/sgsn/v42bis_private.h b/include/osmocom/sgsn/v42bis_private.h new file mode 100644 index 000000000..daa5ea315 --- /dev/null +++ b/include/osmocom/sgsn/v42bis_private.h @@ -0,0 +1,126 @@ +/* + * SpanDSP - a series of DSP components for telephony + * + * private/v42bis.h + * + * Written by Steve Underwood + * + * Copyright (C) 2005 Steve Underwood + * + * All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 2.1, + * as published by the Free Software Foundation. + * + * 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#if !defined(_SPANDSP_PRIVATE_V42BIS_H_) +#define _SPANDSP_PRIVATE_V42BIS_H_ + +/*! + V.42bis dictionary node. + Note that 0 is not a valid node to point to (0 is always a control code), so 0 is used + as a "no such value" marker in this structure. +*/ +typedef struct +{ + /*! \brief The value of the octet represented by the current dictionary node */ + uint8_t node_octet; + /*! \brief The parent of this node */ + uint16_t parent; + /*! \brief The first child of this node */ + uint16_t child; + /*! \brief The next node at the same depth */ + uint16_t next; +} v42bis_dict_node_t; + +/*! + V.42bis compression or decompression. This defines the working state for a single instance + of V.42bis compression or decompression. +*/ +typedef struct +{ + /*! \brief Compression enabled. */ + int v42bis_parm_p0; + /*! \brief Compression mode. */ + int compression_mode; + /*! \brief Callback function to handle output data. */ + put_msg_func_t handler; + /*! \brief An opaque pointer passed in calls to the data handler. */ + void *user_data; + /*! \brief The maximum amount to be passed to the data handler. */ + int max_output_len; + + /*! \brief TRUE if we are in transparent (i.e. uncompressable) mode */ + int transparent; + /*! \brief Next empty dictionary entry */ + uint16_t v42bis_parm_c1; + /*! \brief Current codeword size */ + uint16_t v42bis_parm_c2; + /*! \brief Threshold for codeword size change */ + uint16_t v42bis_parm_c3; + /*! \brief The current update point in the dictionary */ + uint16_t update_at; + /*! \brief The last entry matched in the dictionary */ + uint16_t last_matched; + /*! \brief The last entry added to the dictionary */ + uint16_t last_added; + /*! \brief Total number of codewords in the dictionary */ + int v42bis_parm_n2; + /*! \brief Maximum permitted string length */ + int v42bis_parm_n7; + /*! \brief The dictionary */ + v42bis_dict_node_t dict[V42BIS_MAX_CODEWORDS]; + + /*! \brief The octet string in progress */ + uint8_t string[V42BIS_MAX_STRING_SIZE]; + /*! \brief The current length of the octet string in progress */ + int string_length; + /*! \brief The amount of the octet string in progress which has already + been flushed out of the buffer */ + int flushed_length; + + /*! \brief Compression performance metric */ + uint16_t compression_performance; + + /*! \brief Outgoing bit buffer (compression), or incoming bit buffer (decompression) */ + uint32_t bit_buffer; + /*! \brief Outgoing bit count (compression), or incoming bit count (decompression) */ + int bit_count; + + /*! \brief The output composition buffer */ + uint8_t output_buf[V42BIS_MAX_OUTPUT_LENGTH]; + /*! \brief The length of the contents of the output composition buffer */ + int output_octet_count; + + /*! \brief The current value of the escape code */ + uint8_t escape_code; + /*! \brief TRUE if we just hit an escape code, and are waiting for the following octet */ + int escaped; +} v42bis_comp_state_t; + +/*! + V.42bis compression/decompression descriptor. This defines the working state for a + single instance of V.42bis compress/decompression. +*/ +struct v42bis_state_s +{ + /*! \brief Compression state. */ + v42bis_comp_state_t compress; + /*! \brief Decompression state. */ + v42bis_comp_state_t decompress; + + /*! \brief Error and flow logging control */ +}; + +#endif +/*- End of file ------------------------------------------------------------*/ diff --git a/include/osmocom/sgsn/vty.h b/include/osmocom/sgsn/vty.h new file mode 100644 index 000000000..d2e3d9a73 --- /dev/null +++ b/include/osmocom/sgsn/vty.h @@ -0,0 +1,9 @@ +#pragma once + +#include + +enum bsc_vty_node { + GBPROXY_NODE = _LAST_OSMOVTY_NODE + 1, + SGSN_NODE, + GTPHUB_NODE, +}; diff --git a/src/gprs/crc24.c b/src/gprs/crc24.c index 1a420ed66..da269b375 100644 --- a/src/gprs/crc24.c +++ b/src/gprs/crc24.c @@ -19,7 +19,7 @@ * */ -#include +#include /* CRC24 table - FCS */ static const uint32_t tbl_crc24[256] = { diff --git a/src/gprs/gb_proxy.c b/src/gprs/gb_proxy.c index d288cb314..eb2bbccd5 100644 --- a/src/gprs/gb_proxy.c +++ b/src/gprs/gb_proxy.c @@ -41,14 +41,14 @@ #include -#include -#include -#include -#include +#include +#include +#include +#include -#include +#include #include -#include +#include #include diff --git a/src/gprs/gb_proxy_main.c b/src/gprs/gb_proxy_main.c index 853a763a2..9f9c6051e 100644 --- a/src/gprs/gb_proxy_main.c +++ b/src/gprs/gb_proxy_main.c @@ -41,10 +41,10 @@ #include #include -#include -#include -#include -#include +#include +#include +#include +#include #include #include diff --git a/src/gprs/gb_proxy_patch.c b/src/gprs/gb_proxy_patch.c index bee315036..48627550f 100644 --- a/src/gprs/gb_proxy_patch.c +++ b/src/gprs/gb_proxy_patch.c @@ -18,12 +18,12 @@ * */ -#include +#include -#include -#include +#include +#include -#include +#include #include #include diff --git a/src/gprs/gb_proxy_peer.c b/src/gprs/gb_proxy_peer.c index a83630bc1..69cce3ac0 100644 --- a/src/gprs/gb_proxy_peer.c +++ b/src/gprs/gb_proxy_peer.c @@ -20,9 +20,9 @@ * */ -#include +#include -#include +#include #include #include diff --git a/src/gprs/gb_proxy_tlli.c b/src/gprs/gb_proxy_tlli.c index 3b3b976a5..183212281 100644 --- a/src/gprs/gb_proxy_tlli.c +++ b/src/gprs/gb_proxy_tlli.c @@ -20,12 +20,12 @@ #include -#include +#include -#include -#include +#include +#include -#include +#include #include diff --git a/src/gprs/gb_proxy_vty.c b/src/gprs/gb_proxy_vty.c index bd5bb1b5b..156f33783 100644 --- a/src/gprs/gb_proxy_vty.c +++ b/src/gprs/gb_proxy_vty.c @@ -31,10 +31,10 @@ #include #include -#include -#include -#include -#include +#include +#include +#include +#include #include #include diff --git a/src/gprs/gprs_gb_parse.c b/src/gprs/gprs_gb_parse.c index d5a122bda..ba78e8977 100644 --- a/src/gprs/gprs_gb_parse.c +++ b/src/gprs/gprs_gb_parse.c @@ -21,11 +21,11 @@ #include #include -#include +#include -#include +#include -#include +#include #include diff --git a/src/gprs/gprs_gmm.c b/src/gprs/gprs_gmm.c index 7301bf1c2..7e109b4f5 100644 --- a/src/gprs/gprs_gmm.c +++ b/src/gprs/gprs_gmm.c @@ -54,15 +54,15 @@ #include #endif -#include -#include -#include -#include -#include -#include -#include -#include -#include +#include +#include +#include +#include +#include +#include +#include +#include +#include #include diff --git a/src/gprs/gprs_llc.c b/src/gprs/gprs_llc.c index 904ec7e07..22743fe91 100644 --- a/src/gprs/gprs_llc.c +++ b/src/gprs/gprs_llc.c @@ -33,15 +33,15 @@ #include #include -#include -#include -#include -#include -#include -#include -#include -#include -#include +#include +#include +#include +#include +#include +#include +#include +#include +#include static struct gprs_llc_llme *llme_alloc(uint32_t tlli); static int gprs_llc_tx_xid(struct gprs_llc_lle *lle, struct msgb *msg, diff --git a/src/gprs/gprs_llc_parse.c b/src/gprs/gprs_llc_parse.c index be634974a..1d97004e0 100644 --- a/src/gprs/gprs_llc_parse.c +++ b/src/gprs/gprs_llc_parse.c @@ -28,11 +28,11 @@ #include #include -#include -#include -#include -#include -#include +#include +#include +#include +#include +#include static const struct value_string llc_cmd_strs[] = { { GPRS_LLC_NULL, "NULL" }, diff --git a/src/gprs/gprs_llc_vty.c b/src/gprs/gprs_llc_vty.c index 626d6ef1b..1433efefc 100644 --- a/src/gprs/gprs_llc_vty.c +++ b/src/gprs/gprs_llc_vty.c @@ -32,9 +32,9 @@ #include #include #include -#include -#include -#include +#include +#include +#include #include #include diff --git a/src/gprs/gprs_llc_xid.c b/src/gprs/gprs_llc_xid.c index fe631715a..de60e49ee 100644 --- a/src/gprs/gprs_llc_xid.c +++ b/src/gprs/gprs_llc_xid.c @@ -30,10 +30,10 @@ #include #include -#include -#include -#include -#include +#include +#include +#include +#include const struct value_string gprs_llc_xid_type_names[] = { { GPRS_LLC_XID_T_VERSION, "VERSION"}, diff --git a/src/gprs/gprs_sgsn.c b/src/gprs/gprs_sgsn.c index 560485de5..4cd3df16f 100644 --- a/src/gprs/gprs_sgsn.c +++ b/src/gprs/gprs_sgsn.c @@ -33,14 +33,14 @@ #include #include -#include -#include -#include -#include -#include -#include -#include -#include "openbsc/gprs_llc.h" +#include +#include +#include +#include +#include +#include +#include +#include #include diff --git a/src/gprs/gprs_sndcp.c b/src/gprs/gprs_sndcp.c index 05dad6603..77f8ca663 100644 --- a/src/gprs/gprs_sndcp.c +++ b/src/gprs/gprs_sndcp.c @@ -30,15 +30,15 @@ #include #include -#include -#include -#include -#include -#include -#include -#include -#include -#include +#include +#include +#include +#include +#include +#include +#include +#include +#include #define DEBUG_IP_PACKETS 0 /* 0=Disabled, 1=Enabled */ diff --git a/src/gprs/gprs_sndcp_comp.c b/src/gprs/gprs_sndcp_comp.c index a12c39aa6..60b15b92e 100644 --- a/src/gprs/gprs_sndcp_comp.c +++ b/src/gprs/gprs_sndcp_comp.c @@ -30,11 +30,11 @@ #include #include -#include -#include -#include -#include -#include +#include +#include +#include +#include +#include /* Create a new compression entity from a XID-Field */ static struct gprs_sndcp_comp *gprs_sndcp_comp_create(const void *ctx, diff --git a/src/gprs/gprs_sndcp_dcomp.c b/src/gprs/gprs_sndcp_dcomp.c index b0f95b486..04ff491f3 100644 --- a/src/gprs/gprs_sndcp_dcomp.c +++ b/src/gprs/gprs_sndcp_dcomp.c @@ -33,14 +33,14 @@ #include #include -#include -#include -#include -#include -#include -#include -#include -#include +#include +#include +#include +#include +#include +#include +#include +#include /* A struct to capture the output data of compressor and decompressor */ struct v42bis_output_buffer { diff --git a/src/gprs/gprs_sndcp_pcomp.c b/src/gprs/gprs_sndcp_pcomp.c index a2236c3b1..2911b5ebe 100644 --- a/src/gprs/gprs_sndcp_pcomp.c +++ b/src/gprs/gprs_sndcp_pcomp.c @@ -33,13 +33,13 @@ #include #include -#include -#include -#include -#include -#include -#include -#include +#include +#include +#include +#include +#include +#include +#include /* Initalize header compression */ int gprs_sndcp_pcomp_init(const void *ctx, struct gprs_sndcp_comp *comp_entity, diff --git a/src/gprs/gprs_sndcp_vty.c b/src/gprs/gprs_sndcp_vty.c index 4bad8b040..0994a4cd2 100644 --- a/src/gprs/gprs_sndcp_vty.c +++ b/src/gprs/gprs_sndcp_vty.c @@ -31,10 +31,10 @@ #include #include #include -#include -#include -#include -#include +#include +#include +#include +#include #include #include diff --git a/src/gprs/gprs_sndcp_xid.c b/src/gprs/gprs_sndcp_xid.c index dfea5febc..8f844b571 100644 --- a/src/gprs/gprs_sndcp_xid.c +++ b/src/gprs/gprs_sndcp_xid.c @@ -31,10 +31,10 @@ #include #include -#include -#include -#include -#include +#include +#include +#include +#include /* When the propose bit in an SNDCP-XID compression field is set to zero, * the algorithm identifier is stripped. The algoritm parameters are specific diff --git a/src/gprs/gprs_subscriber.c b/src/gprs/gprs_subscriber.c index 94297d0d6..bebdb1e4b 100644 --- a/src/gprs/gprs_subscriber.c +++ b/src/gprs/gprs_subscriber.c @@ -25,15 +25,15 @@ #include #include #include -#include -#include +#include +#include -#include -#include -#include -#include +#include +#include +#include +#include -#include +#include #include #include diff --git a/src/gprs/gprs_utils.c b/src/gprs/gprs_utils.c index 91a09d2db..307699bed 100644 --- a/src/gprs/gprs_utils.c +++ b/src/gprs/gprs_utils.c @@ -19,7 +19,7 @@ * along with this program. If not, see . * */ -#include +#include #include #include diff --git a/src/gprs/gsup_client.c b/src/gprs/gsup_client.c index 258f230cb..48357b475 100644 --- a/src/gprs/gsup_client.c +++ b/src/gprs/gsup_client.c @@ -21,14 +21,14 @@ * */ -#include +#include #include #include #include #include -#include +#include #include #include diff --git a/src/gprs/gtphub.c b/src/gprs/gtphub.c index 0a8e375ab..7e3e6631e 100644 --- a/src/gprs/gtphub.c +++ b/src/gprs/gtphub.c @@ -32,9 +32,9 @@ #include #include -#include -#include -#include +#include +#include +#include #include #include diff --git a/src/gprs/gtphub_ares.c b/src/gprs/gtphub_ares.c index afeeda657..87dc860c4 100644 --- a/src/gprs/gtphub_ares.c +++ b/src/gprs/gtphub_ares.c @@ -28,15 +28,15 @@ #include #include -#include -#include +#include +#include #include #include /* TODO split GRX ares from sgsn into a separate struct and allow use without * globals. */ -#include +#include extern struct sgsn_instance *sgsn; struct sgsn_instance sgsn_inst = { 0 }; diff --git a/src/gprs/gtphub_main.c b/src/gprs/gtphub_main.c index d7b3ba74b..782afb322 100644 --- a/src/gprs/gtphub_main.c +++ b/src/gprs/gtphub_main.c @@ -41,9 +41,9 @@ #include -#include -#include -#include +#include +#include +#include #include "../../bscconfig.h" diff --git a/src/gprs/gtphub_sock.c b/src/gprs/gtphub_sock.c index 60bebaaeb..1acd5a624 100644 --- a/src/gprs/gtphub_sock.c +++ b/src/gprs/gtphub_sock.c @@ -25,8 +25,8 @@ * along with this program. If not, see . */ -#include -#include +#include +#include /* Convenience makro, note: only within this C file. */ #define LOG(level, fmt, args...) \ diff --git a/src/gprs/gtphub_vty.c b/src/gprs/gtphub_vty.c index d611b1f9a..3a46e817d 100644 --- a/src/gprs/gtphub_vty.c +++ b/src/gprs/gtphub_vty.c @@ -30,12 +30,12 @@ #include #include -#include -#include +#include +#include /* TODO split GRX ares from sgsn into a separate struct and allow use without * globals. */ -#include +#include extern struct sgsn_instance *sgsn; extern void *tall_bsc_ctx; diff --git a/src/gprs/oap_client.c b/src/gprs/oap_client.c index 5128ac119..9ff84a6ea 100644 --- a/src/gprs/oap_client.c +++ b/src/gprs/oap_client.c @@ -27,8 +27,8 @@ #include #include -#include -#include +#include +#include int oap_client_init(struct oap_client_config *config, struct oap_client_state *state) diff --git a/src/gprs/sgsn_ares.c b/src/gprs/sgsn_ares.c index 623809911..17567c484 100644 --- a/src/gprs/sgsn_ares.c +++ b/src/gprs/sgsn_ares.c @@ -19,8 +19,8 @@ * */ -#include -#include +#include +#include #include diff --git a/src/gprs/sgsn_auth.c b/src/gprs/sgsn_auth.c index a64339c3e..92712ef98 100644 --- a/src/gprs/sgsn_auth.c +++ b/src/gprs/sgsn_auth.c @@ -21,11 +21,11 @@ #include #include -#include -#include -#include -#include -#include +#include +#include +#include +#include +#include const struct value_string auth_state_names[] = { { SGSN_AUTH_ACCEPTED, "accepted"}, diff --git a/src/gprs/sgsn_cdr.c b/src/gprs/sgsn_cdr.c index 16ea9d47a..474d41a9a 100644 --- a/src/gprs/sgsn_cdr.c +++ b/src/gprs/sgsn_cdr.c @@ -18,13 +18,13 @@ * */ -#include -#include -#include -#include +#include +#include +#include +#include #include -#include +#include #include #include diff --git a/src/gprs/sgsn_ctrl.c b/src/gprs/sgsn_ctrl.c index f7b1180be..dc5ae79ae 100644 --- a/src/gprs/sgsn_ctrl.c +++ b/src/gprs/sgsn_ctrl.c @@ -21,9 +21,9 @@ #include #include -#include -#include -#include +#include +#include +#include #include diff --git a/src/gprs/sgsn_libgtp.c b/src/gprs/sgsn_libgtp.c index 90b4d1636..9a002664f 100644 --- a/src/gprs/sgsn_libgtp.c +++ b/src/gprs/sgsn_libgtp.c @@ -42,14 +42,14 @@ #include #include -#include -#include -#include -#include -#include -#include -#include -#include +#include +#include +#include +#include +#include +#include +#include +#include #ifdef BUILD_IU #include diff --git a/src/gprs/sgsn_main.c b/src/gprs/sgsn_main.c index 8ffc6c83d..d79beb33f 100644 --- a/src/gprs/sgsn_main.c +++ b/src/gprs/sgsn_main.c @@ -52,12 +52,12 @@ #include -#include -#include -#include -#include -#include -#include +#include +#include +#include +#include +#include +#include #include #include diff --git a/src/gprs/sgsn_vty.c b/src/gprs/sgsn_vty.c index fce251885..18828525d 100644 --- a/src/gprs/sgsn_vty.c +++ b/src/gprs/sgsn_vty.c @@ -30,12 +30,12 @@ #include #include -#include -#include +#include +#include #include -#include -#include -#include +#include +#include +#include #include #include @@ -657,7 +657,7 @@ DEFUN(cfg_auth_policy, cfg_auth_policy_cmd, } /* Subscriber */ -#include +#include static void subscr_dump_full_vty(struct vty *vty, struct gprs_subscr *gsub, int pending) { diff --git a/src/gprs/slhc.c b/src/gprs/slhc.c index cbdf8dbd8..20e571d48 100644 --- a/src/gprs/slhc.c +++ b/src/gprs/slhc.c @@ -57,8 +57,8 @@ #include #include #include -#include -#include +#include +#include #define ERR_PTR(x) x diff --git a/src/gprs/v42bis.c b/src/gprs/v42bis.c index a04b0af5c..3bb9afcd3 100644 --- a/src/gprs/v42bis.c +++ b/src/gprs/v42bis.c @@ -38,9 +38,9 @@ #include #include -#include -#include -#include +#include +#include +#include #include diff --git a/src/libcommon/common_vty.c b/src/libcommon/common_vty.c index 856583e0c..ac3c7fc9f 100644 --- a/src/libcommon/common_vty.c +++ b/src/libcommon/common_vty.c @@ -23,11 +23,11 @@ #include -#include -#include -#include -#include -#include +#include +#include +#include +#include +#include #include #include diff --git a/src/libcommon/debug.c b/src/libcommon/debug.c index 723641335..607640998 100644 --- a/src/libcommon/debug.c +++ b/src/libcommon/debug.c @@ -31,8 +31,8 @@ #include #include #include -#include -#include +#include +#include /* default categories */ static const struct log_info_cat default_categories[] = { diff --git a/src/libcommon/gsm_data.c b/src/libcommon/gsm_data.c index 7be224082..a2837f38f 100644 --- a/src/libcommon/gsm_data.c +++ b/src/libcommon/gsm_data.c @@ -33,9 +33,9 @@ #include #include -#include -#include -#include +#include +#include +#include void *tall_bsc_ctx; diff --git a/src/libcommon/gsm_data_shared.c b/src/libcommon/gsm_data_shared.c index 26962730a..8d5f990ec 100644 --- a/src/libcommon/gsm_data_shared.c +++ b/src/libcommon/gsm_data_shared.c @@ -32,7 +32,7 @@ #include #include -#include +#include void gsm_abis_mo_reset(struct gsm_abis_mo *mo) { diff --git a/src/libcommon/gsm_subscriber_base.c b/src/libcommon/gsm_subscriber_base.c index 018ed210c..2a8a59fe0 100644 --- a/src/libcommon/gsm_subscriber_base.c +++ b/src/libcommon/gsm_subscriber_base.c @@ -29,9 +29,9 @@ #include #include -#include -#include -#include +#include +#include +#include LLIST_HEAD(active_subscribers); void *tall_subscr_ctx; diff --git a/src/libcommon/gsup_client.c b/src/libcommon/gsup_client.c index fd65e7b0b..89a9f7060 100644 --- a/src/libcommon/gsup_client.c +++ b/src/libcommon/gsup_client.c @@ -21,14 +21,14 @@ * */ -#include +#include #include #include #include #include -#include +#include #include #include diff --git a/src/libcommon/gsup_test_client.c b/src/libcommon/gsup_test_client.c index b6a8d6b7d..cc0f58b00 100644 --- a/src/libcommon/gsup_test_client.c +++ b/src/libcommon/gsup_test_client.c @@ -10,8 +10,8 @@ #include #include -#include -#include +#include +#include static struct gsup_client *g_gc; diff --git a/src/libcommon/oap_client.c b/src/libcommon/oap_client.c index 5128ac119..9ff84a6ea 100644 --- a/src/libcommon/oap_client.c +++ b/src/libcommon/oap_client.c @@ -27,8 +27,8 @@ #include #include -#include -#include +#include +#include int oap_client_init(struct oap_client_config *config, struct oap_client_state *state) diff --git a/src/libcommon/socket.c b/src/libcommon/socket.c index 2a64767f8..dfcb3934b 100644 --- a/src/libcommon/socket.c +++ b/src/libcommon/socket.c @@ -35,8 +35,8 @@ #include #include #include -#include -#include +#include +#include #include int make_sock(struct osmo_fd *bfd, int proto, diff --git a/tests/gbproxy/gbproxy_test.c b/tests/gbproxy/gbproxy_test.c index 9672dcba6..e8a4ef983 100644 --- a/tests/gbproxy/gbproxy_test.c +++ b/tests/gbproxy/gbproxy_test.c @@ -31,11 +31,11 @@ #include #include -#include -#include -#include -#include -#include +#include +#include +#include +#include +#include #include diff --git a/tests/gprs/gprs_test.c b/tests/gprs/gprs_test.c index aac9bb896..2dcbafaf7 100644 --- a/tests/gprs/gprs_test.c +++ b/tests/gprs/gprs_test.c @@ -2,10 +2,10 @@ #include #include -#include -#include +#include +#include -#include +#include #include #include diff --git a/tests/gtphub/gtphub_test.c b/tests/gtphub/gtphub_test.c index e7c27d2cb..ac0223b89 100644 --- a/tests/gtphub/gtphub_test.c +++ b/tests/gtphub/gtphub_test.c @@ -28,9 +28,9 @@ #include #include -#include +#include -#include +#include #include #include diff --git a/tests/oap/oap_client_test.c b/tests/oap/oap_client_test.c index e6501cb6d..7adae83ca 100644 --- a/tests/oap/oap_client_test.c +++ b/tests/oap/oap_client_test.c @@ -21,8 +21,8 @@ #include #include -#include -#include +#include +#include #include #include diff --git a/tests/sgsn/sgsn_test.c b/tests/sgsn/sgsn_test.c index d66c5dd84..a4867946e 100644 --- a/tests/sgsn/sgsn_test.c +++ b/tests/sgsn/sgsn_test.c @@ -19,15 +19,15 @@ * */ -#include -#include -#include -#include -#include +#include +#include +#include +#include +#include #include -#include -#include -#include +#include +#include +#include #include diff --git a/tests/slhc/slhc_test.c b/tests/slhc/slhc_test.c index d2e1cd9dc..bb0e26cb8 100644 --- a/tests/slhc/slhc_test.c +++ b/tests/slhc/slhc_test.c @@ -19,8 +19,8 @@ * along with this program. If not, see . */ -#include -#include +#include +#include #include #include diff --git a/tests/sndcp_xid/sndcp_xid_test.c b/tests/sndcp_xid/sndcp_xid_test.c index 151dd2bb5..dc6da8230 100644 --- a/tests/sndcp_xid/sndcp_xid_test.c +++ b/tests/sndcp_xid/sndcp_xid_test.c @@ -19,8 +19,8 @@ * along with this program. If not, see . */ -#include -#include +#include +#include #include #include diff --git a/tests/v42bis/v42bis_test.c b/tests/v42bis/v42bis_test.c index 7e907858d..41d23b02c 100644 --- a/tests/v42bis/v42bis_test.c +++ b/tests/v42bis/v42bis_test.c @@ -19,9 +19,9 @@ * along with this program. If not, see . */ -#include -#include -#include +#include +#include +#include #include #include diff --git a/tests/xid/xid_test.c b/tests/xid/xid_test.c index b77a4ae85..e30a14f97 100644 --- a/tests/xid/xid_test.c +++ b/tests/xid/xid_test.c @@ -19,8 +19,8 @@ * along with this program. If not, see . */ -#include -#include +#include +#include #include #include -- cgit v1.2.3