The FreeRADIUS server  $Id: 15bac2a4c627c01d1aa2047687b3418955ac7f00 $
sigtran.c
Go to the documentation of this file.
1 /*
2  * @copyright (c) 2016, Network RADIUS SAS (license@networkradius.com)
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions are met:
7  * * Redistributions of source code must retain the above copyright
8  * notice, this list of conditions and the following disclaimer.
9  * * Redistributions in binary form must reproduce the above copyright
10  * notice, this list of conditions and the following disclaimer in the
11  * documentation and/or other materials provided with the distribution.
12  * * Neither the name of Network RADIUS SAS nor the
13  * names of its contributors may be used to endorse or promote products
14  * derived from this software without specific prior written permission.
15  *
16  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
17  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19  * DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
20  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26  */
27 
28 /**
29  * $Id: cafc8afafc248b905f541381f8f3d8f34df54597 $
30  * @file rlm_sigtran/sigtran.c
31  * @brief Miscellaneous functions.
32  */
33 #define LOG_PREFIX "sigtran"
34 
35 #include <osmocom/core/linuxlist.h>
36 #include <osmocom/core/talloc.h>
37 #include <osmocom/core/utils.h>
38 #include <osmocom/sccp/sccp.h>
39 
40 #include <freeradius-devel/server/base.h>
41 #include <freeradius-devel/util/debug.h>
42 
43 #include "sigtran.h"
44 
45 /** Conversion table to transform ASCII to Telephony Binary Coded Decimal
46  *
47  * Should be safe to use without validation, invalid digits will be replaced
48  * with zeroes.
49  */
51  [0] = 0,
52  ['0'] = 0x00,
53  ['1'] = 0x01,
54  ['2'] = 0x02,
55  ['3'] = 0x03,
56  ['4'] = 0x04,
57  ['5'] = 0x05,
58  ['6'] = 0x06,
59  ['7'] = 0x07,
60  ['8'] = 0x08,
61  ['9'] = 0x09,
62  ['*'] = 0x0a,
63  ['#'] = 0x0b,
64  ['a'] = 0x0c,
65  ['b'] = 0x0d,
66  ['c'] = 0x0e,
67  [255] = 0
68 };
69 
70 /** Check is a char is valid Telephony Binary Coded Decimal
71  *
72  */
73 uint8_t const is_char_tbcd[] = {
74  [0] = 0,
75  ['0'] = 1,
76  ['1'] = 1,
77  ['2'] = 1,
78  ['3'] = 1,
79  ['4'] = 1,
80  ['5'] = 1,
81  ['6'] = 1,
82  ['7'] = 1,
83  ['8'] = 1,
84  ['9'] = 1,
85  ['*'] = 1,
86  ['#'] = 1,
87  ['a'] = 1,
88  ['b'] = 1,
89  ['c'] = 1,
90  [255] = 0
91 };
92 
93 int sigtran_ascii_to_tbcd(TALLOC_CTX *ctx, uint8_t **out, char const *digits)
94 {
95  size_t len = talloc_array_length(digits) - 1;
96  size_t outlen = (len / 2) + (len & 0x01);
97  uint8_t *p;
98  size_t i;
99 
100  if (len == 0) return -1;
101 
102  *out = p = talloc_array(ctx, uint8_t, outlen);
103 
104  /*
105  * Encode each digit as BCD
106  * Digit 0 goes in low nibble.
107  * Digit 1 goes in high nibble.
108  * Digit 3 goes in low nibble.
109  * Digit 4 goes in high nibble and so on...
110  */
111  for (i = 0; i < (len - 1); i += 2) {
112  (*p++) = ascii_to_tbcd[(uint8_t) digits[i]] | (ascii_to_tbcd[(uint8_t) digits[i + 1]] << 4);
113  }
114 
115  /*
116  * If the number of digits is odd, then the last nibble
117  * (which will be high) is set to 0xf0.
118  */
119  if (len & 0x01) {
120  *p = ascii_to_tbcd[(uint8_t) digits[i]];
121  *p |= 0xf0;
122  }
123 
124  return 0;
125 }
126 
127 /** Convert a global title to wire format for SCCP
128  *
129  * @param[in] ctx To allocate the buffer in.
130  * @param[out] out Where to write the SCCP global title value.
131  * @param[in] gt_ind One of the SCCP_TITLE_IND_* macros.
132  * - SCCP_TITLE_IND_NONE - Don't call this function...
133  * - SCCP_TITLE_IND_NATURE_ONLY - Nature of address indicator only.
134  * - SCCP_TITLE_IND_TRANSLATION_ONLY - Translation type indicator only.
135  * - SCCP_TITLE_IND_TRANS_NUM_ENC - Translation type, numbering plan, encoding scheme.
136  * - SCCP_TITLE_IND_TRANS_NUM_ENC_NATURE - Translation type, numbering plan, encoding scheme,
137  * nature of address indicator.
138  * @param[in] digits To convert to BCD (with nibbles reversed).
139  * @param[in] tt Title translation.
140  * @param[in] es Encoding scheme (specify in lower nibble).
141  * - 0x00 - Unknown
142  * - 0x01 - BCD odd number of digits.
143  * - 0x02 - BCD even number of digits.
144  * - 0x04 - National specific.
145  * - 0x05 to 0x0e - Spare.
146  * - 0x0f - Reserved.
147  * @param[in] np Numbering plan (specify in lower nibble, will shift).
148  * - 0x00 - Unknown.
149  * - 0x01 - ISDN.
150  * - 0x02 - Generic numbering plan.
151  * - 0x03 - Data number plan.
152  * - 0x04 - Telex number plan.
153  * - 0x05 - Maritime mobile number plan.
154  * - 0x06 - Land mobile numbering plan.
155  * - 0x07 - ISDN/mobile numbering plan.
156  * - 0x08 to 0x0d - spare.
157  * - 0x0e - Private or network specific numbering plan.
158  * - 0x0f - Reserved.
159  * @param[in] nai Nature of address indicator.
160  * - 0x00 - Unknown
161  * - 0x01 - Subscriber number.
162  * - 0x02 - Reserved for national use.
163  * - 0x03 - National significant number.
164  * - 0x04 - International number.
165  * - Bit 8 (0xf0) 0 - even number of address signals, 1 - odd number of address signals.
166  * @return
167  * - 0 on success.
168  * - -1 on failure.
169  */
170 int sigtran_sccp_global_title(TALLOC_CTX *ctx, uint8_t **out, int gt_ind, char const *digits,
171  uint8_t tt, uint8_t np, uint8_t es, uint8_t nai)
172 {
173  size_t len = talloc_array_length(digits) - 1;
174  size_t outlen = (len / 2) + (len & 0x01);
175  uint8_t *p;
176  size_t i;
177 
178  if (len == 0) return -1;
179 
180  /*
181  * Nature of address indicator bit 8
182  * gets set high on odd number of digits.
183  */
184  if (len & 0x01) nai |= 0xf0;
185 
186  switch (gt_ind) {
187  default:
188  case SCCP_TITLE_IND_NONE:
189  *out = p = talloc_array(ctx, uint8_t, outlen);
190  break;
191 
192  case SCCP_TITLE_IND_NATURE_ONLY:
193  *out = p = talloc_array(ctx, uint8_t, (outlen + 1));
194  (*p++) = nai;
195  break;
196 
197  case SCCP_TITLE_IND_TRANSLATION_ONLY:
198  *out = p = talloc_array(ctx, uint8_t, (outlen + 1));
199  (*p++) = tt;
200  break;
201 
202  case SCCP_TITLE_IND_TRANS_NUM_ENC:
203  *out = p = talloc_array(ctx, uint8_t, (outlen + 3));
204  (*p++) = tt;
205  (*p++) = ((np & 0x0f) << 4) | (es & 0x0f);
206  break;
207 
208  case SCCP_TITLE_IND_TRANS_NUM_ENC_NATURE:
209  *out = p = talloc_array(ctx, uint8_t, (outlen + 4));
210  (*p++) = tt;
211  (*p++) = ((np & 0x0f) << 4) | (es & 0x0f);
212  (*p++) = nai;
213  break;
214  }
215 
216  /*
217  * Encode each digit as BCD
218  * Digit 0 goes in low nibble.
219  * Digit 1 goes in high nibble.
220  * Digit 3 goes in low nibble.
221  * Digit 4 goes in high nibble and so on...
222  */
223  for (i = 0; i < (len - 1); i += 2) {
224  (*p++) = ascii_to_tbcd[(uint8_t) digits[i]] | (ascii_to_tbcd[(uint8_t) digits[i + 1]] << 4);
225  }
226 
227  /*
228  * If the number of digits is odd, then the last nibble
229  * (which will be high) is set to 0x00.
230  */
231  if (len & 0x01) *p = ascii_to_tbcd[(uint8_t) digits[i]];
232 
233  return 0;
234 }
235 
unsigned char uint8_t
Definition: merged_model.c:30
int sigtran_sccp_global_title(TALLOC_CTX *ctx, uint8_t **out, int gt_ind, char const *digits, uint8_t tt, uint8_t np, uint8_t es, uint8_t nai)
Convert a global title to wire format for SCCP.
Definition: sigtran.c:170
uint8_t const is_char_tbcd[]
Check is a char is valid Telephony Binary Coded Decimal.
Definition: sigtran.c:73
int sigtran_ascii_to_tbcd(TALLOC_CTX *ctx, uint8_t **out, char const *digits)
Definition: sigtran.c:93
uint8_t const ascii_to_tbcd[]
Conversion table to transform ASCII to Telephony Binary Coded Decimal.
Definition: sigtran.c:50
Declarations for various sigtran functions.
static size_t char ** out
Definition: value.h:997