The FreeRADIUS server $Id: 15bac2a4c627c01d1aa2047687b3418955ac7f00 $
Loading...
Searching...
No Matches
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 */
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
93int 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 */
170int 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
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