In case foreign simcards are used we can not do authentication
and ciphering. In case a TMSI is re-used too early and we do
page using TMSI we can't know which of the two MS is responding
to us. We could change the "secure channel" routine to ask for
the IMSI and only then stop the paging.
As we don't have ciphering there is not much use in using the
TMSI. Add a mode "no assign-tmsi" that will not assign the TMSI
during LU. Now CM Service Request and Paging Response will
work using the IMSI. There can't be a clash with that.
[ciaby fixed the vty write to use the right name]
When we can't find the TMSI then the subscriber is not in our
VLR. We have not consulted with the HLR and it is better to not
use such a severe error code.
in_address is not 'accidently' included by FreeBSD when we include
the osmocom/core/select.h header file. We need to include a bit
more.
In file included from mgcp_protocol.c:38:
../../include/openbsc/mgcp_internal.h:134:21: error: field has incomplete type 'struct sockaddr_in'
struct sockaddr_in forward;
List needs to be executed from within the right configuration
node to see if it is available or not. list on the toplevel
will uncoditionally show "smpp" as part of the logging config.
Struct osmo_msc_data contains int core_ncc, which is actually the
MNC part of the PLMN, not to be confused with the Network Colour
Code.
The following patch renames this field for clarity and consistency
with the standards.
If we have tried SMPP first and it was not routable, and then
tried the local delivery there is no point in trying SMPP with
the same parameters again. Leave early and return unknown sub
to the caller.
default-route would only be looked at after there has been
no subscriber in the local database. Depending on the setup
this is not what one wants. This has been discussed at the
OsmoDevCon and there have been hacks in some branches. Let's
introduce a VTY command to select if SMPP should be consulted
first and then fallback to the current behavior.
Even if it is using BSC/NITB types let's put it in the header
file than just declaring it at a place that could bitrot in a
way that doesn't lead a warning.
The "default-route" for SMPP will be used after a local
subscriber look-up. Sometimes we want to route everything
to SMPP. Make this possible by changing this routine.
We just link to libosmovty and if it requires crypt internally it
needs to link to that (and not us). This looks like a left-over
from when we moved the VTY code out of OpenBSC
We don't need to consume all the entropy of the kernel but can
use libcrypto (OpenSSL) to generate random data. It is not clear
if we need to call RAND_load_file but I think we can assume that
our Unices have a /dev/urandom.
This takes less CPU time, provides good enough entropy (in theory)
and leaves some in the kernel entropy pool.
We are using the token to find the right bsc_config and
then we can use the last_rand of the bsc_connection to
calculate the expected result and try to compare it with
a time constant(???) memcmp.
Check if the NAT has sent 16 bytes of RAND and if a key
has been configured in the system and then generate a
result using milenage. The milenage res will be sent and
noth the four byte GSM SRES derivation.
Generate 16 byte of random data to be used for A3A8 by
the BSC in the response. We can't know which BSC it is
at this point and I don't want to send another message
once the token has been received so always send the data
with an undefined code. The old BSCs don't parse the
message and will happily ignore the RAND.
/dev/urandom can give short reads on Linux so loop
around it until the bytes have been read from the kernel.
Instead of doing open/read/close all the time, open the
FD in the beginning and keep it open. To scare me even
more I have seen /dev/urandom actually providing a short
read and then blocking but it seems to be the best way
to get the random byes we need for authentication.
So one should/could run the cheap random generator on
the system (e.g. haveged) or deal with the NAT process
to block.
Unfortunately the basic structure of the response is broken.
There is a two byte length followed by data. The concept of
a 'tag' happens to be the first byte of the data.
This means we want to write strlen of the token, then we
want to write the NUL and then we need to account for the
tag in front.
Introduce a flag if the new or old format should be used.
This will allow to have new BSCs talk to old NATs without
an additional change. In the long run we can clean that up.
In case the token was not correct, just close the connection.
It is not clear that forcing a new TCP connection is going to
give us any extra security here. But with the upcoming auth
handling it does make sense to have both case look similar.
In the libfilter source code, which is built regardless of --enable-nat,
headers from libosmo-sccp were used, thus causing a build failure (see
below) when building without --enable-nat, and libosmo-sccp not being
installed (or being installed in a prefix not otherwise included in the
build).
The build fails like this:
In file included from ../../../src/libfilter/bsc_msg_filter.c:27:0:
../../../include/openbsc/bsc_nat_sccp.h:27:37: fatal error: osmocom/sccp/sccp_types.h: No such file or directory
As the includes seem not to be actually needed, this change fixes the
issue by just omitting them.
Running "make distcheck" failed trying to generate ".version" into the
read-only unpacked source directory. Actually shipping ".version" in the
tarball fixes that.
There was no context for the SCCP CREF message and this means
that the msc_con was a plain NULL pointer that was dereferenced
and the application would crash.
Use the new API to pass the incoming MSC Connection which sould
be used for the SCCP CREF message as context. The code has not
been fed with an actual SCCP CR message.
The loop was used to print all returned addresses but we can
simply pick the first one. This is fixing a coverity issue that
the loop will be executed eaxactly once (and that was on
purpose).
Simplify the code and just take the first element (which might
be NULL).
Fixes: Coverity CID#1302852
We can't do much in case the fd is failing to be registered.
There should be a timeout that is catching this and it might
be able to repair it self.
Fixes: Coverity CID#1302854
The code to do that doesn't belong to the control interface, so
abstract it out to a separate function gsm_bts_set_system_infos().
[hfreyther: Fix the coding style...]
In case the query for "hostname" will fail c-ares will append the
domain name of /etc/resolv.conf and query again. We don't want that
so claim we provide a list of domain names and then don't provide
any.
I didn't intend to have pushed the c-ares code to master yet.
For real networks we need to check if the requested APN string
is allowed and then resolve the GGSN address through DNS. There
are countries with two or three digit MNCs and one could either
try to keep a list of countries that have two/three digits or
just try both of them. I have opted for the later for the ease
of the implementation.
C-Ares doesn't allow to cancel a request so we will need to
have the MMCTX and the Lookup have different lifetimes. We simply
set ->mmctx to NULL in case the MMCTX dies more early.
The selected and verified apn_str will be copied into the out
parameter. In case no static APN/GGSN config is present and the
dynamic mode is enabled a request will be made.
c-ares is an asynchronous DNS resolver and we need it to
resolve the GGSN address. This is integrating the library
into our infrastructure. We will create and maintain a list
of registered FDs (c-ares is currently only using one of
them) and (re-)schedule the timer after events occurred.
When needing to do an asynchronous DNS query we need
to keep the TLV data around. So create a wrapper that
takes a copy of it and frees it after the call. I can
change the code to add an out parameter to decide if
the msgb should be freed or not.
Pick network failure in case the msgb could not be
cloned in the hope the MS will retry then.
A real SGSN will dynamically resolve the APN name into the
GGSN IP Address. This means that after we have collected all
information we need to start to resolve the GGSN and then
can continue.
This is a left-over from the initial system where no PDP
was provided by the system. For now if there is a subscr
attached and no PDP context provisioned. He is not allowed
to have a data connection.
Update the testcase to create the pdp list entry more
early with a wildcard and then change it to a specific
match.
Include the hlr-Number of the subscriber in the CDR. This is useful
for debugging and understanding which equipment was used during the
test. In contrast to the MSISDN the '+' is emitted as the number
must be in international format already.
Copy the hlr-Number into the sgsn_data and use it during
the purgeMS. There is no unit test that looks at the data
we send so I manually verified this by looking at the output.
Below is the output of the test that purges the subscriber.
<000f> gprs_subscriber.c:170 SUBSCR(123456789012345) Sending GSUP, will send: 0c 01 08 21 43 65 87 09 21 43 f5 09 07 91 83 61 26 31 23 f3
We have verified/selected the APN. Either based on the subscriber
data, a global APN match. But at least this SGSN has looked at
what the MS has asked for and then selected a matching GGSN.
Clear LAC/RAC with pre-defined value in the RAI.
3GPP 29.060 v7.17.0 section 7.3.1 page 23:
"The SGSN may include the Routeing Area Identity (RAI) of the
SGSN where the MS is registered. The MCC and MNC components shall
be populated with the MCC and MNC, respectively, of the SGSN
where the MS is registered. The LAC and RAC components shall be
populated by the SGSN with the value of 'FFFE' and 'FF',
respectively.”
Most SGSNs pass the IMEI(SV). We currently only enquire about
the IMEI and then pad the 'SV' with 1111b (thanks to the encoding
routine). Sadly it insists on always writing the length which
means we have to memmove the data around by a single octet.
Manually verified using the pcu-emu and looking at the trace
using wireshark.
Give the GGSN another opportunity to determine which tarif
to apply for the SGSN/subscriber. This code assumes tha the
RAN is a GERAN system but the assumption has been made in
other places as well.
For PDP context creation we always want to include the RAI
for the current mmctx. This might help commercial GGSNs to
determine which charging to apply.
The charging_id is provided by the GGSN. Copy it into the CDR
part of the data structure so it will remain present until after
the pdp context has been deleted.
Make it possible to set a filename to use for the CDR. By
default no CDR will be generated. Forbid to set the interval
of 0 seconds as this will cause a lot of work. Add a very
basic VTY test.
This is consuming the new signals and allows to install several
different CDR/observing/event/audit modules in the future. For
getting the bytes in/out the code would have had to undo what the
rate counter is doing and at the same time adding a "total" to
the ratecounter didn't look like a good idea, the same went for
making it a plain counter.
Begin writing the values one by one and open/closing a new FILE
for every log messages. This is not efficient but easily deals
with external truncation/rotation of the file (no fstat for and
checking the links and size). As usual we will wait and see if
this is an issue.
Add some new members to our PDP context structure to see what it
is about.
In case there is a subscr attached to the MM context and there
is an encoded MSISDN we will attempt to decode it and in case
of an international number prepend a '+'. Assume that the array
size of gsm_mmcc_called->number is as big as ctx->msisdn for the
strncpy.
If QoS is only three bytes it does not include the allocation/
retention policy. Otherwise it does. Copy it depending on that.
We should have a macro for the clamping to reduce code duplication.
The insanity does come from the MAP data and this seems to be
the easiest in terms of complexity. It is an array of bytes that
is transported from MAPProxy to the SGSN and then simply forwarded.
The case of more than three bytes is neither unit nor manually
tested so far.
sgsn_create_pdp_ctx should use the subscribed QoS. When selecting
the PDP context we inject the QoS to be used into the TLV structure
and use it during the request. Assume a "qos-Subscribed" structure
only with three bytes and prepend the Allocation/Retention policy
to the request.
The MSISDN should be present for "security" reasons in the first
activation of a PDP context. Take the encoded MSISDN, store it for
future use and then put it into the PDP activation request.
The MM Context contains a field for a decoded MSISDN already. As
we need to forward the data to the GGSN I want to avoid having to
store TON and NPI in another place. Simply store the data in the
encoded form.
QoS is a mess. In MAP there is qos-Subscribed which is then extended
using ext-QoS-Subscribed, ext2-QoS-Subscribed, ext3-QoS-Subscribed
and maybe even ext4-QoS-Subscribed by now. The MAP ASN1 files defined
how these need to be "linearized". Instead of copying this I have
decided to include the two semantics with/without the Allocation/Retention
policy using the size of the data.
It is a bit arbitary to decide which one is the global
and which one is the local one. We might change it around.
I don't think we want to introduce it based on BTS.
For the BSC we will have the gsm48_hdr and don't need to
find data within SCCP. For legacy reasons we need to
initialize con_type, imsi, reject causes early on and
need to do the same in the filter method.
This means we need to require a talloc context and
simply operate on the list. I had considered creating
a structure to hold the list head but I didn't find
any other members so omitted it for now.
Move the filter methods to the filter module. This is
still only usable for the NAT and the _dt/_cr filter
routines need to move back to the bsc_nat in the long
run.
For customer requirements we want to be able to do
filtering on the BSC as well. The same messages need
to be scanned and the same access-lists will be looked
at. In the future we might even split traffic based
on the IMSI. Begin with moving the code to a new top
level directory and then renaming and removing the
nat dependency.
ENDPOINT_NUMBER takes the difference of two pointers. On 64bit
builds the difference is a long and the compiler then complains
about the usage of abs. We will never have thousands of endpoints
so silence the warning by casting the ENDPOINT_NUMBER to int.
mgcp_vty.c:1381:34: warning: absolute value function 'abs' given an argument of type 'long' but has parameter of
type 'int' which may cause truncation of value [-Wabsolute-value]
rtp_port = rtp_calculate_port(ENDPOINT_NUMBER(endp),
^
../../include/openbsc/mgcp_internal.h:206:31: note: expanded from macro 'ENDPOINT_NUMBER'
#define ENDPOINT_NUMBER(endp) abs(endp - endp->tcfg->endpoints)
^
mgcp_vty.c:1381:34: note: use function 'labs' instead
The idea of "subscriber_get_channel" was that different
requests would be coordinated. At the same time we have
seen that the "queue" can get stuck at both 31C3 and the
rhizomatica installations.
Voice calls and SMS do not need coordination. We should
be able to send SMS on a voice channel and switch the MS
from a SDCCH to a TCH in case we establish a voice call.
The SMS code itself needs to coordinate to obey the limit
of one SMS per direction but this should be enforced in
the sms layer and not on the subscriber.
Modify the code to have a simple paging coordination. The
subscriber code will schedule the paging and register who
would like to know about success/failure.
This allowed to greatly simplify the paging response
handling for the transaction code (and in fact we could
move the transaction list into the subscriber structure
now). The code gained to support to cancel the notification
of a request (but not the paging itself yet).
TODO: Cancel paging request in case no one cares about it
anymore.
In case the default TCH/F codec is "EFR" and we do an early
assignment from SDCCH to a TCH we would assign the TCH/H
codec. This is because the lchan_type will be neither a
TCH/H nor a TCH/F.
At the same time the _gsm48_lchan_modify code to check for
half vs. full-rate is the other way around. Align both.
It is full-rate if it is not a TCH_H. This will have some
other complications down the way (early assignment on
cells with only TCH/H). So the mode should not depend on
the _current_ channel but the kind of channel we want.
In test_rtp_seq_state an assignment is accidently done within an
assertion.
This commit changes that into a comparison as it was intended.
Fixes: Coverity CID 1295457, 1295458
Sponsored-by: On-Waves ehf
Currently the src_codec const variable is set to &src_end->codec
before src_end is checked against NULL. Since the assigment is just
an address operation and the memory where it points to is only
accessed after the NULL check, this does not harm technically.
Nevertheless this is potential source for errors if that code is
changed.
This commit moves the definition below the NULL check. This does not
comply with the coding style, but it cannot be split into definition
and a later assignment due to the const qualifier.
Sponsored-by: On-Waves ehf
We might have compiled transcoding into the MGW but
we don't want to enable it for a given user. Add a new
switch that should allow that.
I had manually tested the allow-transcoding/no allow
VTY interface for the primary interface and a new trunk
using show running-config.
It is unlikely that GSM, gsm and GsM refer to different codecs.
The mera mvts does send the audio codecs in lower case even if
RFC 3551 has them in upper case (but copy and paste is sometimes
too hard).
Currently the handling of the buffers is not done consistently. Some
code assumes that the whole buffer may be used to store the string
while at other places, the last buffer byte is left untouched in the
assumption that it contains a terminating NUL-character. The latter
is the correct behaviour.
This commit changes to code to not touch the last byte in the buffers
and to rely on the last byte being NUL. So the maximum IMSI/IMEI
length is GSM_IMSI_LENGTH-1/GSM_IMEI_LENGTH-1.
For information: We assume that we allocate the structure with
talloc_zero. This means we have NULed the entire imsi array and then
only write sizeof - 1 characters to it. So the last byte remains NUL.
Fixes: Coverity CID 1206568, 1206567
Sponsored-by: On-Waves ehf