2016-05-10 10:50:31 +00:00
|
|
|
/* Code used by both libbsc and libmsc (common_cs means "BSC or MSC").
|
|
|
|
*
|
|
|
|
* (C) 2016 by sysmocom s.m.f.c. <info@sysmocom.de>
|
2016-05-11 16:48:39 +00:00
|
|
|
* (C) 2008-2010 by Harald Welte <laforge@gnumonks.org>
|
2016-05-10 10:50:31 +00:00
|
|
|
* All Rights Reserved
|
|
|
|
*
|
|
|
|
* This program is free software; you can redistribute it and/or modify
|
|
|
|
* it under the terms of the GNU Affero General Public License as published by
|
|
|
|
* the Free Software Foundation; either version 3 of the License, or
|
|
|
|
* (at your option) any later version.
|
|
|
|
*
|
|
|
|
* This program is distributed in the hope that it will be useful,
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
* GNU Affero General Public License for more details.
|
|
|
|
*
|
|
|
|
* You should have received a copy of the GNU Affero General Public License
|
|
|
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
|
|
*
|
|
|
|
*/
|
2016-05-11 16:48:39 +00:00
|
|
|
|
2016-05-11 23:16:58 +00:00
|
|
|
#include <osmocom/core/utils.h>
|
|
|
|
|
|
|
|
#include <osmocom/vty/command.h>
|
|
|
|
#include <osmocom/vty/logging.h>
|
|
|
|
#include <osmocom/vty/stats.h>
|
|
|
|
|
|
|
|
#include <openbsc/vty.h>
|
|
|
|
|
2016-05-11 16:48:39 +00:00
|
|
|
#include <openbsc/gsm_data.h>
|
2016-05-11 23:16:58 +00:00
|
|
|
#include <openbsc/gsm_subscriber.h>
|
|
|
|
|
|
|
|
struct cmd_node net_node = {
|
|
|
|
GSMNET_NODE,
|
|
|
|
"%s(config-net)# ",
|
|
|
|
1,
|
|
|
|
};
|
|
|
|
|
|
|
|
#define NETWORK_STR "Configure the GSM network\n"
|
|
|
|
#define CODE_CMD_STR "Code commands\n"
|
|
|
|
#define NAME_CMD_STR "Name Commands\n"
|
|
|
|
#define NAME_STR "Name to use\n"
|
|
|
|
|
|
|
|
DEFUN(cfg_net,
|
|
|
|
cfg_net_cmd,
|
|
|
|
"network", NETWORK_STR)
|
|
|
|
{
|
|
|
|
vty->index = gsmnet_from_vty(vty);
|
|
|
|
vty->node = GSMNET_NODE;
|
|
|
|
|
|
|
|
return CMD_SUCCESS;
|
|
|
|
}
|
|
|
|
|
|
|
|
DEFUN(cfg_net_ncc,
|
|
|
|
cfg_net_ncc_cmd,
|
|
|
|
"network country code <1-999>",
|
|
|
|
"Set the GSM network country code\n"
|
|
|
|
"Country commands\n"
|
|
|
|
CODE_CMD_STR
|
|
|
|
"Network Country Code to use\n")
|
|
|
|
{
|
|
|
|
struct gsm_network *gsmnet = gsmnet_from_vty(vty);
|
|
|
|
|
|
|
|
gsmnet->country_code = atoi(argv[0]);
|
|
|
|
|
|
|
|
return CMD_SUCCESS;
|
|
|
|
}
|
|
|
|
|
|
|
|
DEFUN(cfg_net_mnc,
|
|
|
|
cfg_net_mnc_cmd,
|
|
|
|
"mobile network code <0-999>",
|
|
|
|
"Set the GSM mobile network code\n"
|
|
|
|
"Network Commands\n"
|
|
|
|
CODE_CMD_STR
|
|
|
|
"Mobile Network Code to use\n")
|
|
|
|
{
|
|
|
|
struct gsm_network *gsmnet = gsmnet_from_vty(vty);
|
|
|
|
|
|
|
|
gsmnet->network_code = atoi(argv[0]);
|
|
|
|
|
|
|
|
return CMD_SUCCESS;
|
|
|
|
}
|
|
|
|
|
|
|
|
DEFUN(cfg_net_name_short,
|
|
|
|
cfg_net_name_short_cmd,
|
|
|
|
"short name NAME",
|
|
|
|
"Set the short GSM network name\n" NAME_CMD_STR NAME_STR)
|
|
|
|
{
|
|
|
|
struct gsm_network *gsmnet = gsmnet_from_vty(vty);
|
|
|
|
|
|
|
|
bsc_replace_string(gsmnet, &gsmnet->name_short, argv[0]);
|
|
|
|
return CMD_SUCCESS;
|
|
|
|
}
|
|
|
|
|
|
|
|
DEFUN(cfg_net_name_long,
|
|
|
|
cfg_net_name_long_cmd,
|
|
|
|
"long name NAME",
|
|
|
|
"Set the long GSM network name\n" NAME_CMD_STR NAME_STR)
|
|
|
|
{
|
|
|
|
struct gsm_network *gsmnet = gsmnet_from_vty(vty);
|
|
|
|
|
|
|
|
bsc_replace_string(gsmnet, &gsmnet->name_long, argv[0]);
|
|
|
|
return CMD_SUCCESS;
|
|
|
|
}
|
|
|
|
|
|
|
|
DEFUN(cfg_net_auth_policy,
|
|
|
|
cfg_net_auth_policy_cmd,
|
|
|
|
"auth policy (closed|accept-all|regexp|token)",
|
|
|
|
"Authentication (not cryptographic)\n"
|
|
|
|
"Set the GSM network authentication policy\n"
|
|
|
|
"Require the MS to be activated in HLR\n"
|
|
|
|
"Accept all MS, whether in HLR or not\n"
|
|
|
|
"Use regular expression for IMSI authorization decision\n"
|
|
|
|
"Use SMS-token based authentication\n")
|
|
|
|
{
|
|
|
|
enum gsm_auth_policy policy = gsm_auth_policy_parse(argv[0]);
|
|
|
|
struct gsm_network *gsmnet = gsmnet_from_vty(vty);
|
|
|
|
|
|
|
|
gsmnet->auth_policy = policy;
|
|
|
|
|
|
|
|
return CMD_SUCCESS;
|
|
|
|
}
|
|
|
|
|
|
|
|
DEFUN(cfg_net_authorize_regexp, cfg_net_authorize_regexp_cmd,
|
|
|
|
"authorized-regexp REGEXP",
|
|
|
|
"Set regexp for IMSI which will be used for authorization decision\n"
|
|
|
|
"Regular expression, IMSIs matching it are allowed to use the network\n")
|
|
|
|
{
|
|
|
|
struct gsm_network *gsmnet = gsmnet_from_vty(vty);
|
|
|
|
if (gsm_parse_reg(gsmnet, &gsmnet->authorized_regexp,
|
|
|
|
&gsmnet->authorized_reg_str, argc, argv) != 0) {
|
|
|
|
vty_out(vty, "%%Failed to parse the authorized-regexp: '%s'%s",
|
|
|
|
argv[0], VTY_NEWLINE);
|
|
|
|
return CMD_WARNING;
|
|
|
|
}
|
|
|
|
|
|
|
|
return CMD_SUCCESS;
|
|
|
|
}
|
|
|
|
|
|
|
|
DEFUN(cfg_net_reject_cause,
|
|
|
|
cfg_net_reject_cause_cmd,
|
|
|
|
"location updating reject cause <2-111>",
|
|
|
|
"Set the reject cause of location updating reject\n"
|
|
|
|
"Set the reject cause of location updating reject\n"
|
|
|
|
"Set the reject cause of location updating reject\n"
|
|
|
|
"Set the reject cause of location updating reject\n"
|
|
|
|
"Cause Value as Per GSM TS 04.08\n")
|
|
|
|
{
|
|
|
|
struct gsm_network *gsmnet = gsmnet_from_vty(vty);
|
|
|
|
|
|
|
|
gsmnet->reject_cause = atoi(argv[0]);
|
|
|
|
|
|
|
|
return CMD_SUCCESS;
|
|
|
|
}
|
|
|
|
|
|
|
|
DEFUN(cfg_net_encryption,
|
|
|
|
cfg_net_encryption_cmd,
|
|
|
|
"encryption a5 (0|1|2|3)",
|
|
|
|
"Encryption options\n"
|
|
|
|
"A5 encryption\n" "A5/0: No encryption\n"
|
|
|
|
"A5/1: Encryption\n" "A5/2: Export-grade Encryption\n"
|
|
|
|
"A5/3: 'New' Secure Encryption\n")
|
|
|
|
{
|
|
|
|
struct gsm_network *gsmnet = gsmnet_from_vty(vty);
|
|
|
|
|
2016-12-18 22:52:38 +00:00
|
|
|
gsmnet->a5_encryption = atoi(argv[0]);
|
2016-05-11 23:16:58 +00:00
|
|
|
|
|
|
|
return CMD_SUCCESS;
|
|
|
|
}
|
|
|
|
|
|
|
|
DEFUN(cfg_net_rrlp_mode, cfg_net_rrlp_mode_cmd,
|
|
|
|
"rrlp mode (none|ms-based|ms-preferred|ass-preferred)",
|
|
|
|
"Radio Resource Location Protocol\n"
|
|
|
|
"Set the Radio Resource Location Protocol Mode\n"
|
|
|
|
"Don't send RRLP request\n"
|
|
|
|
"Request MS-based location\n"
|
|
|
|
"Request any location, prefer MS-based\n"
|
|
|
|
"Request any location, prefer MS-assisted\n")
|
|
|
|
{
|
|
|
|
struct gsm_network *gsmnet = gsmnet_from_vty(vty);
|
|
|
|
|
|
|
|
gsmnet->rrlp.mode = rrlp_mode_parse(argv[0]);
|
|
|
|
|
|
|
|
return CMD_SUCCESS;
|
|
|
|
}
|
|
|
|
|
|
|
|
DEFUN(cfg_net_mm_info, cfg_net_mm_info_cmd,
|
|
|
|
"mm info (0|1)",
|
|
|
|
"Mobility Management\n"
|
|
|
|
"Send MM INFO after LOC UPD ACCEPT\n"
|
|
|
|
"Disable\n" "Enable\n")
|
|
|
|
{
|
|
|
|
struct gsm_network *gsmnet = gsmnet_from_vty(vty);
|
|
|
|
|
|
|
|
gsmnet->send_mm_info = atoi(argv[0]);
|
|
|
|
|
|
|
|
return CMD_SUCCESS;
|
|
|
|
}
|
|
|
|
|
|
|
|
DEFUN(cfg_net_subscr_keep,
|
|
|
|
cfg_net_subscr_keep_cmd,
|
|
|
|
"subscriber-keep-in-ram (0|1)",
|
|
|
|
"Keep unused subscribers in RAM.\n"
|
|
|
|
"Delete unused subscribers\n" "Keep unused subscribers\n")
|
|
|
|
{
|
|
|
|
struct gsm_network *gsmnet = gsmnet_from_vty(vty);
|
|
|
|
gsmnet->subscr_group->keep_subscr = atoi(argv[0]);
|
|
|
|
return CMD_SUCCESS;
|
|
|
|
}
|
2016-05-11 16:48:39 +00:00
|
|
|
|
2016-05-14 01:24:41 +00:00
|
|
|
DEFUN(cfg_net_timezone,
|
|
|
|
cfg_net_timezone_cmd,
|
|
|
|
"timezone <-19-19> (0|15|30|45)",
|
|
|
|
"Set the Timezone Offset of the network\n"
|
|
|
|
"Timezone offset (hours)\n"
|
|
|
|
"Timezone offset (00 minutes)\n"
|
|
|
|
"Timezone offset (15 minutes)\n"
|
|
|
|
"Timezone offset (30 minutes)\n"
|
|
|
|
"Timezone offset (45 minutes)\n"
|
|
|
|
)
|
|
|
|
{
|
|
|
|
struct gsm_network *net = vty->index;
|
|
|
|
int tzhr = atoi(argv[0]);
|
|
|
|
int tzmn = atoi(argv[1]);
|
|
|
|
|
|
|
|
net->tz.hr = tzhr;
|
|
|
|
net->tz.mn = tzmn;
|
|
|
|
net->tz.dst = 0;
|
|
|
|
net->tz.override = 1;
|
|
|
|
|
|
|
|
return CMD_SUCCESS;
|
|
|
|
}
|
|
|
|
|
|
|
|
DEFUN(cfg_net_timezone_dst,
|
|
|
|
cfg_net_timezone_dst_cmd,
|
|
|
|
"timezone <-19-19> (0|15|30|45) <0-2>",
|
|
|
|
"Set the Timezone Offset of the network\n"
|
|
|
|
"Timezone offset (hours)\n"
|
|
|
|
"Timezone offset (00 minutes)\n"
|
|
|
|
"Timezone offset (15 minutes)\n"
|
|
|
|
"Timezone offset (30 minutes)\n"
|
|
|
|
"Timezone offset (45 minutes)\n"
|
|
|
|
"DST offset (hours)\n"
|
|
|
|
)
|
|
|
|
{
|
|
|
|
struct gsm_network *net = vty->index;
|
|
|
|
int tzhr = atoi(argv[0]);
|
|
|
|
int tzmn = atoi(argv[1]);
|
|
|
|
int tzdst = atoi(argv[2]);
|
|
|
|
|
|
|
|
net->tz.hr = tzhr;
|
|
|
|
net->tz.mn = tzmn;
|
|
|
|
net->tz.dst = tzdst;
|
|
|
|
net->tz.override = 1;
|
|
|
|
|
|
|
|
return CMD_SUCCESS;
|
|
|
|
}
|
|
|
|
|
|
|
|
DEFUN(cfg_net_no_timezone,
|
|
|
|
cfg_net_no_timezone_cmd,
|
|
|
|
"no timezone",
|
|
|
|
NO_STR
|
|
|
|
"Disable network timezone override, use system tz\n")
|
|
|
|
{
|
|
|
|
struct gsm_network *net = vty->index;
|
|
|
|
|
|
|
|
net->tz.override = 0;
|
|
|
|
|
|
|
|
return CMD_SUCCESS;
|
|
|
|
}
|
|
|
|
|
2016-05-11 16:48:39 +00:00
|
|
|
static struct gsm_network *vty_global_gsm_network = NULL;
|
|
|
|
|
|
|
|
/* initialize VTY elements used in both BSC and MSC */
|
2016-05-11 23:16:58 +00:00
|
|
|
int common_cs_vty_init(struct gsm_network *network,
|
|
|
|
int (* config_write_net )(struct vty *))
|
2016-05-11 16:48:39 +00:00
|
|
|
{
|
|
|
|
OSMO_ASSERT(vty_global_gsm_network == NULL);
|
|
|
|
vty_global_gsm_network = network;
|
2016-05-11 23:16:58 +00:00
|
|
|
|
|
|
|
install_element(CONFIG_NODE, &cfg_net_cmd);
|
|
|
|
install_node(&net_node, config_write_net);
|
|
|
|
vty_install_default(GSMNET_NODE);
|
|
|
|
install_element(GSMNET_NODE, &cfg_net_ncc_cmd);
|
|
|
|
install_element(GSMNET_NODE, &cfg_net_mnc_cmd);
|
|
|
|
install_element(GSMNET_NODE, &cfg_net_name_short_cmd);
|
|
|
|
install_element(GSMNET_NODE, &cfg_net_name_long_cmd);
|
|
|
|
install_element(GSMNET_NODE, &cfg_net_auth_policy_cmd);
|
|
|
|
install_element(GSMNET_NODE, &cfg_net_authorize_regexp_cmd);
|
|
|
|
install_element(GSMNET_NODE, &cfg_net_reject_cause_cmd);
|
|
|
|
install_element(GSMNET_NODE, &cfg_net_encryption_cmd);
|
|
|
|
install_element(GSMNET_NODE, &cfg_net_rrlp_mode_cmd);
|
|
|
|
install_element(GSMNET_NODE, &cfg_net_mm_info_cmd);
|
|
|
|
install_element(GSMNET_NODE, &cfg_net_subscr_keep_cmd);
|
2016-05-14 01:24:41 +00:00
|
|
|
install_element(GSMNET_NODE, &cfg_net_timezone_cmd);
|
|
|
|
install_element(GSMNET_NODE, &cfg_net_timezone_dst_cmd);
|
|
|
|
install_element(GSMNET_NODE, &cfg_net_no_timezone_cmd);
|
2016-05-11 23:16:58 +00:00
|
|
|
|
|
|
|
return CMD_SUCCESS;
|
2016-05-11 16:48:39 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
struct gsm_network *gsmnet_from_vty(struct vty *v)
|
|
|
|
{
|
|
|
|
/* It can't hurt to force callers to continue to pass the vty instance
|
|
|
|
* to this function, in case we'd like to retrieve the global
|
|
|
|
* gsm_network instance from the vty at some point in the future. But
|
|
|
|
* until then, just return the global pointer, which should have been
|
|
|
|
* initialized by common_cs_vty_init().
|
|
|
|
*/
|
|
|
|
OSMO_ASSERT(vty_global_gsm_network);
|
|
|
|
return vty_global_gsm_network;
|
|
|
|
}
|