Commit Graph

602 Commits

Author SHA1 Message Date
Alexander Couzens 2c962f5de1 osmo_sock_init2: improve support for AF_UNSPEC
osmo_sock_init2 abstract two calls of getaddrinfo into one.
While there aren't problems with AF_INET or AF_INET6. When using
AF_UNSPEC there are corner cases when this fails. E.g. calling
local_host with "" and remote_host with an IPv6 only address results in
setting up a local socket with AF_INET while trying to connect from there towards
AF_INET6 will most likely fail.
To prevent such cases with AF_UNSPEC, search prio calling any syscalls if local and remote site
supports AF_INET or AF_INET6. In case both supported, prefer AF_INET6

Change-Id: I397c633931fd00d4f083955a3c49a40fb002d766
2020-08-06 16:41:20 +00:00
Harald Welte 44964981c2 i460: Fix bit- and subslots ordering of I.460 mux + demux
When I wrote the new I.460 mux + demux code, I failed to realize that
* bit numbers in relevant ITU specs start with 1 as MSB ... 8 as LSB
* sub-slot 0 is bits 1+2, i.e. the two MSBs of a byte
* bit-ordering within each sub-slot is also MSB first

As a result, the code and test data was broken.

Change-Id: I6df7dbf411efbdeaf516e72ac552432bf5a569d0
2020-08-02 21:57:05 +02:00
Harald Welte b3b474d8ad i460: pass more context to call-back functions
When calling a user-provided call-back function for the i460 mux
or demux, always pass a pointer to the osmo_i460_subchan the callback
relates to.  This way, the user can walk the i460 data structures
to obtain information about which mux/demux instances is calling.

Change-Id: Id842c72ce371a67fe5df6694e195c281aaf607ab
2020-08-02 11:57:55 +02:00
Pau Espin a184701108 vty: Don't match negative values on purely positive ranges
Without this patch, for instance having a range 0-ULONG_MAX would match
if someones types value -3, which would be converted to unsigned but
that's clearly what is expected here from user point of view.

Change-Id: Ia95f6314a2dd3f94d21fc219cf69bb8d39b8e7f0
2020-07-30 21:02:03 +00:00
Pau Espin 9fdc871532 vty: Allow 64 bit values in numeric ranges if system supports it
This fixes commands not being matched due to providing a range with more
than 10 digits.

The last case (passing -4000 matching 0-ULONG_MAX) shows a different bug
which will be fixed in next commit.

Change-Id: I0afa0caabffe36083c36b92ba90696ded00bb7be
2020-07-30 21:02:03 +00:00
Pau Espin d92be9ad13 tests: vty: Extend test to do some numeric range validations
As per current status, the numeric tests are expected to fail due to a
couple bugs which will be fixed in next commits.

Change-Id: Id5b17bd96d7af4ed9a77ebbea0e6be4b0fcbde6c
2020-07-30 21:02:03 +00:00
Pau Espin eb028fa1df tests/fsm_test.c: Disable use color in logging output
This should avoid other problems in the future.

Change-Id: I81368578c0830477d381566a54671fdde6067b23
2020-07-30 20:33:24 +00:00
Neels Hofmeyr 30856ca5cb gsm0408_test: allow deprecated API
This test knowingly calls deprecated functions -- allow that to squelch these
warnings:

warning: ‘gsm48_generate_lai’ is deprecated: Use gsm48_generate_lai2() instead, to not lose leading zeros in the MNC [-Wdeprecated-declarations]
warning: ‘gsm48_decode_lai’ is deprecated: Use gsm48_decode_lai2() instead, to not lose leading zeros in the MNC [-Wdeprecated-declarations]

Change-Id: Ifd618c1b9befa9c9ef0a338ab4aae2b0f796f4c2
2020-06-16 15:17:48 +02:00
Neels Hofmeyr 83025bf1a6 add osmo_mobile_identity API
Implement better API around 3GPP TS 24.008 Mobile Identity coding.

struct osmo_mobile_identity is a decoded representation of the raw Mobile
Identity, with a string representation as well as dedicated raw uint32_t TMSI.
The aim is to remove all uncertainty about decoded buffer sizes / data types.

I have patches ready for current osmo CNI programs, replacing the Mobile
Identity coding with this new API. Deprecate the old MI API.
osmo-bsc: I71c3b4c65dbfdfa51409e09d4868aea83225338a
osmo-msc: Ic3f969e739654c1e8c387aedeeba5cce07fe2307
osmo-sgsn: I4cacb10bac419633ca0c14f244f9903f7f517b49
Note that some GPRS and SGs related coding is done here in libosmocore and
hence currently remains using the old implementation (see previous version of
this patch: Ic3f969e739654c1e8c387aedeeba5cce07fe2307).

New API functions provide properly size-checking implementations of:
- decoding a raw MI from a bunch of MI octets;
- locating and decoding MI from a full 3GPP TS 24.008 Complete Layer 3 msgb;
- encoding to a buffer;
- encoding to the end of a msgb.

Other than the old gsm48_generate_mid(), omit a TLV tag and length from
encoding. Many callers manually stripped the tag and value after calling
gsm48_generate_mid(). The aim is to leave writing a TL to the caller entirely,
especially since some callers need to use a TvL, i.e. support a variable-size
length of 8 or 16 bit.

New validity checks so far not implemented anywhere else:
- stricter validation of number of digits of IMSI, IMEI, IMEI-SV MI.
- stricter on filler nibbles to be 0xf.
As a result, applications using osmo_mobile_identity will be stricter in
rejecting coding mistakes (some of which we currently have in our test suites,
and which we'll need to fix).

Rationale:

While implementing osmo-bsc's MSC pooling feature in osmo-bsc, this API will be
used to reduce the number of times a Mobile Identity is extracted from a raw
RSL message.

Extracting the Mobile Identity from messages has numerous duplicate
implementations across our code with various levels of specialization.
https://xkcd.com/927/

To name a few:
- libosmocore: gsm48_mi_to_string(), osmo_mi_name_buf()
- osmo-bsc: extract_sub()
- osmo-msc: mm_rx_loc_upd_req(), cm_serv_reuse_conn(), gsm48_rx_mm_serv_req(),
  vlr_proc_acc_req()

We have existing functions to produce a human readable string from a Mobile
Identity, more or less awkward:
- gsm48_mi_to_string() decodes a TMSI as a decimal number. These days we use
  hexadecimal TMSI everywhere.
- osmo_mi_name_buf() decodes the BCD digits from a raw MI every time, so we'd
  need to pass around the raw message bytes. Also, osmo_mi_name_buf() has the
  wrong signature, it should return a length like snprintf().
- osmo-bsc's extract_sub() first uses gsm48_mi_to_string() which encodes the
  raw uint32_t TMSI to a string, and then calls strtoul() via
  tmsi_from_string() to code those back to a raw uint32_t.

Each of the above implementations employ their own size overflow checks, each
invoke osmo_bcd2str() and implement their own TMSI osmo_load32be() handling.
Too much code dup, let's hope that each and every one is correct.

In osmo-bsc, I am now implementing MSC pooling, and need to extract NRI bits
from a TMSI Mobile Identity. Since none of the above functions are general
enough to be re-used, I found myself again copy-pasting Mobile Identity code:
locating the MI in a 24.008 message with proper size checks, decoding MI
octets.

This time I would like it to become a generally re-usable API.

This patch was first merged as Ic3f969e739654c1e8c387aedeeba5cce07fe2307 and
caused test fallout, because it re-implemented old API with the new stricter
decoding. In this patch version, old API remains 1:1 unchanged to avoid such
fallout. Applications will soon switch to the new osmo_mobile_identity API and
become stricter on MI coding when that happens, not implicitly by a new
libosmocore version.

Change-Id: If4f7be606e54cfa1c59084cf169785b1cbda5cf5
2020-06-16 15:17:48 +02:00
Harald Welte a13fb75030 Revert "add osmo_mobile_identity API"
This reverts commit d1ceca9d48, as it
introduces regressions in both osmo-msc and osmo-nitb which have been
causing failing builds for several days now.

Change-Id: I4bd958d0cd2ab4b0c4725e6d114f4404d725fcf7
2020-06-16 09:21:08 +02:00
Neels Hofmeyr d1ceca9d48 add osmo_mobile_identity API
Implement better API around 3GPP TS 24.008 Mobile Identity coding.

struct osmo_mobile_identity is a decoded representation of the raw Mobile
Identity, with a string representation as well as dedicated raw uint32_t TMSI.
The aim is to remove all uncertainty about decoded buffer sizes / data types.

I have patches ready for all osmo programs, completely replacing the Mobile
Identity coding with this new API. Hence deprecate the old MI API.

New API functions provide properly size-checking implementations of:
- decoding a raw MI from a bunch of MI octets;
- locating and decoding MI from a full 3GPP TS 24.008 Complete Layer 3 msgb;
- encoding to a buffer;
- encoding to the end of a msgb.

Other than the old gsm48_generate_mid(), omit a TLV tag and length from
encoding. Many callers manually stripped the tag and value after calling
gsm48_generate_mid(). The aim is to leave writing a TL to the caller entirely,
especially since some callers need to use a TvL, i.e. support a variable-size
length of 8 or 16 bit.

New validity checks so far not implemented anywhere else:
- stricter validation of number of digits of IMSI, IMEI, IMEI-SV MI.
- stricter on filler nibbles to be 0xf.

Rationale:

While implementing osmo-bsc's MSC pooling feature in osmo-bsc, this API will be
used to reduce the number of times a Mobile Identity is extracted from a raw
RSL message.

Extracting the Mobile Identity from messages has numerous duplicate
implementations across our code with various levels of specialization.
https://xkcd.com/927/

To name a few:
- libosmocore: gsm48_mi_to_string(), osmo_mi_name_buf()
- osmo-bsc: extract_sub()
- osmo-msc: mm_rx_loc_upd_req(), cm_serv_reuse_conn(), gsm48_rx_mm_serv_req(),
  vlr_proc_acc_req()

We have existing functions to produce a human readable string from a Mobile
Identity, more or less awkward:
- gsm48_mi_to_string() decodes a TMSI as a decimal number. These days we use
  hexadecimal TMSI everywhere.
- osmo_mi_name_buf() decodes the BCD digits from a raw MI every time, so we'd
  need to pass around the raw message bytes. Also, osmo_mi_name_buf() has the
  wrong signature, it should return a length like snprintf().
- osmo-bsc's extract_sub() first uses gsm48_mi_to_string() which encodes the
  raw uint32_t TMSI to a string, and then calls strtoul() via
  tmsi_from_string() to code those back to a raw uint32_t.

Each of the above implementations employ their own size overflow checks, each
invoke osmo_bcd2str() and implement their own TMSI osmo_load32be() handling.
Too much code dup, let's hope that each and every one is correct.

In osmo-bsc, I am now implementing MSC pooling, and need to extract NRI bits
from a TMSI Mobile Identity. Since none of the above functions are general
enough to be re-used, I found myself again copy-pasting Mobile Identity code:
locating the MI in a 24.008 message with proper size checks, decoding MI
octets.

This time I would like it to become a generally re-usable API.

Change-Id: Ic3f969e739654c1e8c387aedeeba5cce07fe2307
2020-06-12 16:35:26 +02:00
Neels Hofmeyr 7dde1f40a2 add gsm23236: MSC pooling: TMSI and NRI utility functions
These utilities will be used by osmo-bsc to determine the Network Resource
Indicator seen in the TMSI, and (potentially) by osmo-msc to compose a TMSI
with a specific NRI, for osmo-bsc's load balancing between several MSCs.

Add utility functions to:
- extract an NRI value from a TMSI.
- overwrite the NRI value in a TMSI.
- limit an NRI in a (random) TMSI to a given list of ranges.
- add NRI value ranges to a list.
- remove them from a list.
- match NRI value (range) to a list.
- parse NRI values from string, for VTY.
- common VTY functionality of adding/removing NRI values from argv.

Add C tests for the above.

Why we need public API for NRI ranges: In osmo-bsc alone, we need the same NRI
API twice, 1: to manage/list NRI value ranges per-MSC, and 2: to manage/list
NULL-NRI values. If we also consider (potentially) adding NRI support to
osmo-msc, we need the same API twice again there. Hence it is useful to define
re-used API up here in libosmocore.

Related: OS#3682
Change-Id: Icb57a2dd9323c7ea11b34003eccc7e68a0247bf5
2020-06-10 14:20:49 +02:00
Philipp Maier 2908dbfddd gsm0808: fix endieness of call identifier
The call identifier in the ASSIGNMENT COMMAND is encoded in the wrong
endieness. 3GPP TS 48.008, section 3.2.2.105 specifies that the least
significant byte should be transmitted first, which means that the
endieness here is little endian. Lets make sure that the endieness is
correctly transmitted, regardless of the host byte order.

Change-Id: I6468e502f552f99ab54aec9d4b1c169fdc0adfb8
Related: OS#4582
2020-06-09 12:36:38 +02:00
Harald Welte b795f03faf Implement ITU-T I.460 multiplex / demultiplex
This implements a multiplexer and de-multiplexer for the ITU-T I.460
standard.  The latter covers the transmission of sub-slots of 32/16/8k
inside 64k timeslots.

Change-Id: Id522f06e73b77332b437b7a27e4966872da70eda
2020-05-28 13:08:52 +00:00
Alexander Chemeris 22630e6827 gsm0808: Implement helper functions for CONFUSION BSSMAP message decoding.
Also add a test for an actual CONFUSION message parsing.

Change-Id: If8afd2d096fb66c6c2f255a08fc1129de3d09cec
2020-05-17 07:32:32 +00:00
Harald Welte 5785a4a8fc codec: Add functions for AMR s->d bits and d->s bits
These functions implement re-ordering of bits as per TS 06.90 / 26.101
based on the already existing tables we've had in libosmocoding.

Change-Id: Ia4ac2aea2e96f9185f082a07ca64dfc5276efb46
2020-05-14 14:51:22 +02:00
Alexander Chemeris fdfe25b105 gsm0808: Make a function to extract Cause IE publicly available.
Function gsm0808_get_cipher_reject_cause() was previously available
in private gsm0808_utils.h. In practice, the exact same code is useful
to extract Cause IE value from any of the many other BSSMAP messages
which use it.

So let's rename it to gsm0808_get_cause() and make it avilable
to everyone to use.

Change-Id: Idf2b99e9ef014eba26e3d4f0f38c2714d3a0520a
2020-05-13 00:46:00 +03:00
Philipp Maier 3c0a87ca4b gsm0505_amr_dtx: add missing value strings
The value string array that explain the type of the AMR DTX / SID
frames is incomplete, lets add the missing strings.

Change-Id: If9e80b4bd8bdc31323c7c276155b2538e20a99be
Related: OS#2978
2020-05-12 18:13:30 +00:00
Alexander Chemeris a5b1b86a33 gsm0808: Fix encoding of the SAPI_N_REJECT BSSMAP message.
See TS 08.08 section 3.2.1.34 SAPI "n" REJECT:
1) DLCI is a TV element, not V.
2) Cause is a TLV element and we have a special function to encode it.

Change-Id: I033afe556c06427d06ac55c4f78854a45e41aae6
2020-05-12 01:14:03 +03:00
Pau Espin e7d0d70ce7 tests/coding_test: Fix test_pdtch() results
When switching the l2 structures passes to test_pdtch() to be constant,
it was noted that output of the test changes. This happens because same
array is tested several times with different length, incrementing each
time. Since the test was modifying the input array directly, it means
each new run of test_pdtch() the array was further modified.
Upon constifying the structures, we copy the array and hence only modify
the required bits each time.

Change-Id: Iffd0ca3669eb8d0d2e80d754fc8acbf72f1bebe8
2020-04-17 10:15:05 +00:00
Pau Espin ce28d2ebba tests/coding: Test decoding of DL EGPRS data packet
Change-Id: Ide23a484b980995f24092d1cfbf062aed58fdf61
2020-04-17 10:15:05 +00:00
Philipp Maier 898c9c6af8 dtx: add decoding for AMR-DTX frames
gsm0503_coding contains AMR decoder functions for HR and FR. Those can
only decode AMR payload frames but not amr DTX frames. Lets add
functionality to detect DTX frames. Also lets add decoding for SID_UPDATE
frames as well as error checking for the SID frame recognition patterns.

Related: OS#2978
Change-Id: I2bbdb39ea20461ca08b2e6f1a33532cb55cd5195
2020-04-14 13:22:44 +00:00
Vadim Yanitskiy 9e713f3828 coding: fix bit ordering in 11-bit RACH coding functions
According to 3GPP TS 44.004, figure 7.4a.b, the format of 11-bit
RACH uplink / Uplink access burst block is as defined follows:

  <---------------------------------------------------

      8     7     6     5     4     3     2     1
  +--------------------------------------------------+
  |  11 bit RACH uplink / Uplink access burst block  | OCT1
  +--------------------------------------------------+
                                 |                   | OCT2
                                 +-------------------+

As was (correctly) assumed in [1], the bit ordering in 11-bit RACH
coding functions is wrong. The problem is that neither of generic
functions from bit16gen.h can be used to load / store the RA11
value (regardless of the endianness), because they assume that
the payload is 16 bit long.

With this patch applied, RA11 values from [1] look correct:

  < EGPRS Packet channel request message content > ::=
    < Signalling : 110011  < RandomBits : 00111 > > |
    < Signalling : 110011  < RandomBits : 00110 > > |
    < Signalling : 110011  < RandomBits : 01111 > > |
    < Signalling : 110011  < RandomBits : 01100 > > |
    < Signalling : 110011  < RandomBits : 00111 > > |
    < Signalling : 110011  < RandomBits : 10110 > > ;

[1] Id80e471d252b9416217b56f4c8c0a8f5f1289fee

Change-Id: I43d30611dd69f77f2b3b46f4b56056a8891d3c24
Related: OS#1548
2020-04-01 01:09:31 +07:00
Vadim Yanitskiy 41ce6753bc tests/coding: add 11-bit Access Burst samples from a real phone
This change adds several soft-bit (-127 .. 127) sequences containing
EGPRS Packet Channel Request message (11-bit, payload only) sent by
an EGPRS capable phone, and captured on the BTS/PCU side using a
tool from the TRX Toolkit - trx_sniff.py.

As can be seen from the test output, none of decoded RA11 values
looks like a valid EGPRS Packet Channel Request message (see
table 11.2.5a.2 of 3GPP TS 44.060). All test sequences contain
the same message with several random bits:

  < EGPRS Packet channel request message content > ::=
      < Signalling : 110011  < RandomBits : bit (5) > >;

since the phone was trying to perform Attach Request. It seems
the bit order of decoded messages is somehow wrong.

Change-Id: Id80e471d252b9416217b56f4c8c0a8f5f1289fee
Related: OS#1548
2020-03-31 19:26:44 +07:00
Vadim Yanitskiy 88c61c3822 tests/coding: cosmetic: use ARRAY_SIZE() macro from utils.h
Change-Id: Ie6278d84d405f073669e607f978ca5b187bcf78e
2020-03-31 15:37:27 +07:00
Vadim Yanitskiy 0f4919e915 tests/coding: reduce verbosity of 8-bit / 11-bit RACH coding tests
We don't really need additional 1.4M of debug output, given that
we test every possible 8-bit and 11-bit RA value. It's enough
to print error message if the resulting value does not match.

Otherwise it's hard to read the expected output without commenting
the related log statements out. Note that it's still possible to
re-enable verbose debug output by defining DEBUG.

Change-Id: I0d5ed90cb0a2b3007d665520a73b0fa0b86a4099
2020-03-31 15:37:23 +07:00
Vadim Yanitskiy ca466cf5f6 tests/coding: check return value of encoding / decoding functions
Change-Id: I78850a4ab2fb7cd63bb4a3789f934634b6fb2cb7
2020-03-31 15:34:07 +07:00
Philipp Maier 3a5917bd50 gsm690: Fix amr speech bit length table
The table amr_len_by_ft represents the length of the raw AMR speech bits
in bytes. The table is based on the Table found in RFC 4867 §3.6, Table 1,
Column "Total speech bits". The number of bits is divided by 8 and then
rounded up to get the number of consumed octets.

An AMR SID frame (including STI and MI) takes up 39 bits, this will
result in 5 octets, not in 7. Lets correct this.

Related: OS#2978
Change-Id: Icf330450981b32be5d1cee5b10aa92bac4cb72f5
2020-03-13 10:52:22 +01:00
Philipp Maier 31c29ea051 conv: add convolutional coder for AMR SID UPDATE frames
AMR SID update frames are protected using an 1/4 convolutional coder,
wich is similar to the one used with 6,7 kbit voice frames. Except that
there is no puncturing and the length is different.

Change-Id: Ia35ed4178a7f0d816052b7e5d6478b93a1d9744f
Related: OS#2978
2020-03-09 13:40:27 +01:00
Vadim Yanitskiy 832d8b8633 bitvec: fix bitvec_unhex(): do not return 1 on success
This function is supposed to return 0 on success or 1 in case of
error. However, it used to return 1 even in case of success. The
reason is that length of the input string was not taken into
account and sscanf() was failing on '\0'.

Let's use osmo_hexparse() and rely on its return value.

P.S. Funny that the unit test expectations were wrong too.

Change-Id: I441a22c7964bb31688071d8bcf6a282d8c0187ff
2020-02-19 18:23:40 +07:00
Vadim Yanitskiy 6e270e2530 tests/bitvec: add a unit test for bitvec_read_field()
The aim of this unit test is to demonstrate the problem described
in OS#4388: bitvec_read_field() can never return negative value
on error (e.g. out of bounds access).

Change-Id: I340ab5799fa53d5345edb02f3e2a3655527705c0
Related: OS#4388
2020-02-19 18:23:40 +07:00
Harald Welte c6a8697800 Introduce helper functions for safe fork+exec of processes
In some situations, we want to execute an external shell command
in a non-blocking way.  Similar to 'system', but without waiting for
the child to complete.  We also want to close all file descriptors
ahead of the exec() and filter + modify the environment.

Change-Id: Ib24ac8a083db32e55402ce496a5eabd8749cc888
Related: OS#4332
2019-12-17 13:49:28 +01:00
Oliver Smith a47d37c946 debian, utils: switch to python 3
Make build and external tests work with python3, so we can drop
the python2 dependency.

This should be merged shortly after osmo-python-tests was migrated to
python3, and the jenkins build slaves were (automatically) updated to
have the new osmo-python-tests installed.

Related: OS#2819
Depends: osmo-python-tests I3ffc3519bf6c22536a49dad7a966188ddad351a7
Change-Id: I84ef43f700e125c7a65f92347f12844e07e65655
2019-12-12 09:24:04 +00:00
Harald Welte 49ddef610a gsup: Introduce OSMO_GSUP_NUM_VECTORS_REQ_IE
This is a bit of a hack, as we want to maintain binary compatibility
without breaking existing users of libosmocore.  To do so, we use the
'num_auth_vectors' field in two ways now:

* In the existing use case as part of SEND_AUTH_INFO_RESPONSE, it
  indicates the number of vectors stored in the 'auth_vectors' field

* In the new use case as part of SEND_AUTH_INFO_REQUEST, it indicates
  the number of vectors actually requested by the MSC/SGSN/MME.

Change-Id: Iaecc47280f8ce54f3e3a888c1cfc160735483d0f
2019-12-09 10:54:30 +00:00
Harald Welte ae5016f193 Check for osmo_fsm_register() error return value
Change-Id: Idbc1557739b2a253b73914e6f1f18a6d169d882e
2019-12-01 13:45:03 +01:00
Neels Hofmeyr 8a7eed50db add osmo_escape_cstr and osmo_quote_cstr
Provide string escaping that
- returns the required buffer size, so it can be used with OSMO_STRBUF_APPEND().
- uses C compatible string constant escaping sequences.

This is intended as a replacement for all previous osmo_escape_str* and
osmo_quote_str* API. It pains me that I didn't get them right the first nor the
second time:
- The buffer functions do not return the chars needed, which is required for
  allocating sufficient memory in the *_c versions of the functions.
- Because of that, these functions are accurately usable for
  OSMO_STRBUF_APPEND(), producing truncated strings, for example when dumping a
  GSUP message.
- They do not use the C equivalent string constant escaping: for some reason I
  thought "\15" would be valid, but it should be "\x0f".
If I could, I would completely drop those mislead implementations ... but
backwards compat prohibits that.

A previous patch already provided internal static functions that accurately
return the required buffer size. Enhance these to also support C compatible
string escaping, and use them as implementation of the new functions:

osmo_escape_cstr_buf()
osmo_escape_cstr_c()
osmo_quote_cstr_buf()
osmo_quote_cstr_c()

In the tests for these, also test C string equivalence.

Naming: from API versions, it would be kind of logical to call them
osmo_escape_str_buf3() and osmo_escape_str_c2(). Since these anyway return a
different escaping, it makes sense to me to have distinct names instead.

Quasi missing are variants of the non-C-compatible weird legacy escaping that
return the required buffer size, but I refrain from adding those, because we
have enough API cruft as it is. Just always use these new cstr variants.

Change-Id: I3dfb892036e01000033dd8e7e4a6a0c32a3caa9b
2019-11-24 19:59:35 +01:00
Neels Hofmeyr d31de23758 vty: track parent nodes also for telnet sessions
Keep track of parent nodes and go back hierarchically, not only for .cfg file
reading, but also for telnet VTY sessions.

A long time ago cfg file parsing was made strictly hierarchical: node exits go
back to parent nodes exactly as they were entered. However, live telnet VTY
sessions still lacked this and depended on the go_parent_cb().

From this commit on, implementing a go_parent_cb() is completely optional. The
go_parent_cb() no longer has the task to determine the correct parent node,
neither for cfg files (as already the case before this patch) nor for telnet
VTY sessions (added by this patch). Instead, a go_parent_cb() implementation
can merely take actions it requires on node exits, for example applying some
config when leaving a specific node.

The node value that is returned by the go_parent_cb() and the vty->node and
vty->index values that might be set are completely ignored; instead the
implicit parent node tracking determines the parent and node object.

As a side effect, the is_config_node() callback is no longer needed, since the
VTY now always implicitly knows when to exit back to the CONFIG_NODE.

For example, osmo_ss7_is_config_node() could now be dropped, and the
osmo_ss7_vty_go_parent() could be shortened by five switch cases, does no
longer need to set vty->node nor vty->index and could thus be shortened to:

int osmo_ss7_vty_go_parent(struct vty *vty)
{
        struct osmo_ss7_asp *asp;
        struct osmo_xua_server *oxs;

        switch (vty->node) {
        case L_CS7_ASP_NODE:
                asp = vty->index;
                /* If no local addr was set */
                if (!asp->cfg.local.host_cnt) {
                        asp->cfg.local.host[0] = NULL;
                        asp->cfg.local.host_cnt = 1;
                }
                osmo_ss7_asp_restart(asp);
                break;
        case L_CS7_XUA_NODE:
                oxs = vty->index;
                /* If no local addr was set, or erased after _create(): */
                if (!oxs->cfg.local.host_cnt)
                        osmo_ss7_xua_server_set_local_host(oxs, NULL);
                if (osmo_ss7_xua_server_bind(oxs) < 0)
                        vty_out(vty, "%% Unable to bind xUA server to IP(s)%s", VTY_NEWLINE);
                break;
        }
        return 0;
}

Before parent tracking, every program was required to write a go_parent_cb()
which has to return every node's parent node, basically a switch() statement
that manually traces the way back out of child nodes. If the go_parent_cb() has
errors, we may wildly jump around the node tree: a common error is to jump
right out to the top config node with one exit, even though we were N levels
deep. This kind of error has been eliminated for cfg files long ago, but still
exists for telnet VTY sessions, which this patch fixes.

This came up when I was adding multi-level config nodes to osmo-hlr to support
Distributed GSM / remote MS lookup: the config file worked fine, while vty node
tests failed to exit to the correct nodes.

Change-Id: I2b32b4fe20732728db6e9cdac7e484d96ab86dc5
2019-11-24 19:59:35 +01:00
Neels Hofmeyr 951d32b817 osmo_sockaddr_str: deprecate osmo_sockaddr_str_*_32n()
Follow up for patch I3cf150cc0cc06dd36039fbde091bc71b01697322

osmo_sockaddr_str_{from,to}_32n actually use host byte order. Deprecate these
and introduce a more accurately named version ending in h.

Change-Id: Ic7fc279bf3c741811cfc002538e28e8f8560e338
2019-11-24 19:59:35 +01:00
Neels Hofmeyr 06356fd9c3 utils: add osmo_strnchr()
When finding a char in a string, I want to be able to limit the search area by
size, not only by nul terminator.

Change-Id: I48f8ace9f51f8a06796648883afcabe3b4e8b537
2019-11-24 19:59:35 +01:00
Neels Hofmeyr ff65d24ec4 utils_test: add osmo_print_n_test()
A couple of times recently I've needed to copy out a substring to a buffer with
limited size. Use of strncpy() or osmo_strlcpy() are nontrivial here.
I wanted to have a dedicated function.

After I wrote that function with a test, I noticed that I had already
implemented the same thing a while ago, as osmo_print_n() :P
So here is just the test.

Change-Id: Ia716abdc1f58af6065b84f4f567388a32a7b39fc
2019-11-24 19:59:35 +01:00
Neels Hofmeyr 823073aa91 utils.h: add OSMO_NAME_C_IMPL() macro
Provide a common implementation for foo_name_c() functions that base on
foo_name_buf() functions.

  char *foo_name_c(void *ctx, example_t arg)
  {
          OSMO_NAME_C_IMPL(ctx, 64, "ERROR", foo_name_buf, arg)
  }

Rationale: the most efficient way of composing strings that have optional parts
or require loops for composition is by writing to a ready char[], and this in
turn is easiest done by using OSMO_STRBUF_* API. Using such a basic name string
implementation which typically returns a length, I often want a more convenient
version that returns a char*, which can just be inlined in a "%s" string format
-- crucially: skipping string composition when inlined in a LOGP(). This common
implementation allows saving code dup, only the function signature is needed.

Why not include the function signature in the macro? The two sets of varargs
(1: signature args, 2: function call args) are hard to do. Also, having an
explicit signature is good for readability and code grepping / ctags.

Upcoming uses: in libosmocore in the mslookup (D-GSM) implementation
(osmo_mslookup_result_name_c()), and in osmo_msc's codec negotiation
implementation (sdp_audio_codecs_name_c(), sdp_msg_name_c(), ...).
I54b6c0810f181259da307078977d9ef3d90458c9 (libosmocore)
If3ce23cd5bab15e2ab4c52ef3e4c75979dffe931 (osmo-msc)

Change-Id: Ida5ba8d9640ea641aafef0236800f6d489d3d322
2019-11-23 07:58:47 +00:00
Neels Hofmeyr df22b00633 osmo_sockaddr_str: API doc: fix 32bit addr mixup of host/network byte order
Of course both v4 and v6 addresses are kept in network byte order when
represented in bytes, but when writing, I somehow must have assumed that
inet_pton() returns host byte order. Fix that mixup in the API docs:

osmo_sockaddr_str_from_32() and osmo_sockaddr_str_to_32() actually use network
byte order.

osmo_sockaddr_str_from_32n() and osmo_sockaddr_str_to_32n() actually use host
byte order, though reflecting 'n' in their name.

sockaddr_str_test: use hexdump instead of %x to show the
osmo_sockaddr_str_to_32*() conversions so that the error becomes obvious.
(Printing %x reverses the bytes again and made it look correct.)

Change-Id: I3cf150cc0cc06dd36039fbde091bc71b01697322
2019-11-23 07:58:47 +00:00
Neels Hofmeyr f2644aee55 logging.h: define ansi color constants
It's hard to figure out what color logging categories have with those ANSI
color code strings. Instead, define these OSMO_LOGCOLOR_* constants.

Naming: commonly, the logging.h header has the "LOG" prefix in the name, but it
seems saner to include the OSMO_ prefix: it seems too likely that some
libosmocore user somewhere already has defined "LOGCOLOR_RED" somewhere.

Change-Id: I03b6b1f73ae7ee61d37ff921e071a3d0881d3e9a
2019-11-23 07:58:47 +00:00
Neels Hofmeyr 002a51d731 add osmo_sockaddr_str_cmp()
Currently planned user: for Distributed GSM in osmo-hlr: setting per-MSC
service addresses in VTY: replace/remove existing entries.

osmo_sockaddr_str_cmp() is useful to catch identical resulting IP addresses,
regardless of differing strings (e.g. '0::' and '::' are equal but differ in
strings).

Change-Id: I0dbc1cf707098dcda75f8e07c1b936951f9f9501
2019-11-21 21:17:12 +01:00
Vadim Yanitskiy b639b4d4f7 logging/vty: fix vty_read_file(): do not write warnings to stdin
Setting vty->fd to 0 is a bad idea, which may cause the process
to write() warnings to its own _stdin_ (yes, it's possible).
For example, when a configuration file contains deprecated
logging commands. Let's use stderr by default.

Change-Id: Icdeaea67a06da3a2f07b252e455629559ecc1829
2019-11-21 10:48:30 +07:00
Vadim Yanitskiy 4abda9ea26 logging/vty: fix: actually ignore deprecated logging commands
We shall not prevent programs from starting if their configuration
files contain deprecated 'logging level ...' commands. Just print
a warning and return CMD_SUCCESS instead of CMD_WARNING.

While writing a unit test, another funny bug has been uncovered.
Parsing of a deprecated command indeed triggers a deprecation
warning, originated from libosmovty's log_deprecated_func().
This function simply calls vty_out(), but...

Since the invocation of the vty_out() happens _before_ the VTY
is initialized, the process is actually writing that warning
to its own stdin! Most likely, because we use talloc_zero()
to allocate a new instance of struct 'vty'.

As a side effect, the evil warning magically appears in the output
of 'make check', breaking the test statistics. Let's work around
this bug for now by redirecting stdin to /dev/null.

Change-Id: Ia934581410cd41594791d4e14ee74c16abe1009a
Fixes: Ic9c1b566ec4a459f03e6319cf369691903cf9d00
2019-11-21 10:48:02 +07:00
Neels Hofmeyr d0e8d6b9b5 fix OSMO_SOCKADDR_STR_FMT for IPv6
The format prints IP:port separated by a colon, which of course is confusing
when the IPv6 address itself contains mostly colons. The new format adds square
braces.

  cafe:face::1:42 -> [cafe:face::1]:42

The IPv4 format remains unchanged:
  1.2.3.4:42

Change-Id: I161f8427729ae31be0eac719b7a4a9290715e37f
2019-11-11 20:14:01 +01:00
Neels Hofmeyr 83d691048b test: add OSMO_SOCKADDR_STR_FMT to sockaddr_str_test.c
This shows the weird format choice for showing IPv6 addresses' port, fixed in
subsequent patch.

Change-Id: I8e5ebfbbc3a2b88aed820e8f845d9f6ededb29de
2019-11-11 20:14:01 +01:00
Pau Espin e40b9637ea gsm: gsm_utils: Fix return type of API ms_class_gmsk_dbm() and add unit tests
Only known user of API is in osmocom-bb and it compiles fine after the
change.

Related: OS#4244
Change-Id: Ia10345008b3aca50b30482ef3b852b03eca71995
2019-11-04 12:41:22 +01:00
Pau Espin b99f4ca2d8 gsm_04_08.h: Introduce API osmo_gsm48_rfpowercap2powerclass()
Related: OS#4244
Change-Id: I32e9cc1c2397b44f0d48db2acdf782a821365b63
2019-11-03 23:21:06 +00:00