The FreeRADIUS server $Id: 15bac2a4c627c01d1aa2047687b3418955ac7f00 $
Loading...
Searching...
No Matches
rlm_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: cc7a2364153f04eea534310f935350ff286f3888 $
30 * @file rlm_sigtran/rlm_sigtran.c
31 * @brief Implement a SCTP/M3UA/SCCP/TCAP/MAP stack
32 *
33 * @copyright 2016 Network RADIUS SAS (license@networkradius.com)
34 */
35RCSID("$Id: cc7a2364153f04eea534310f935350ff286f3888 $")
36
37#define LOG_PREFIX_ARGS mctx->mi->name
38
39#include <osmocom/core/linuxlist.h>
40
41#include "libosmo-m3ua/include/bsc_data.h"
42#include "libosmo-m3ua/include/sctp_m3ua.h"
43
44#include <freeradius-devel/server/base.h>
45#include <freeradius-devel/server/module_rlm.h>
46#include <freeradius-devel/util/debug.h>
47
48#include "sigtran.h"
49#include "attrs.h"
50
51#include <limits.h>
52
53#if !defined(PIPE_BUF) && defined(_POSIX_PIPE_BUF)
54# define PIPE_BUF _POSIX_PIPE_BUF
55#endif
56
57#ifdef PIPE_BUF
58static_assert(sizeof(void *) < PIPE_BUF, "PIPE_BUF must be large enough to accommodate a pointer");
59#endif
60
62
63unsigned int __hack_opc, __hack_dpc;
64
66 { L("broadcast"), 3 },
67 { L("loadshare"), 2 },
68 { L("override"), 1 }
69};
71
72static const conf_parser_t sctp_config[] = {
73 { FR_CONF_OFFSET_TYPE_FLAGS("server", FR_TYPE_COMBO_IP_ADDR, 0, rlm_sigtran_t, conn_conf.sctp_dst_ipaddr) },
74 { FR_CONF_OFFSET("port", rlm_sigtran_t, conn_conf.sctp_dst_port), .dflt = "2905" },
75
76 { FR_CONF_OFFSET_TYPE_FLAGS("src_ipaddr", FR_TYPE_COMBO_IP_ADDR, 0, rlm_sigtran_t, conn_conf.sctp_src_ipaddr ) },
77 { FR_CONF_OFFSET("src_port", rlm_sigtran_t, conn_conf.sctp_src_port), .dflt = "0" },
78
79 { FR_CONF_OFFSET("timeout", rlm_sigtran_t, conn_conf.sctp_timeout), .dflt = "5" },
80
82};
83
91
92static const conf_parser_t m3ua_config[] = {
93 { FR_CONF_OFFSET("link_index", rlm_sigtran_t, conn_conf.m3ua_link_index) },
94 { FR_CONF_OFFSET("routing_ctx", rlm_sigtran_t, conn_conf.m3ua_routing_context) },
95 { FR_CONF_OFFSET("traffic_mode", rlm_sigtran_t, conn_conf.m3ua_traffic_mode_str), .dflt = "loadshare" },
96 { FR_CONF_OFFSET("ack_timeout", rlm_sigtran_t, conn_conf.m3ua_ack_timeout), .dflt = "2" },
97 { FR_CONF_OFFSET("beat_interval", rlm_sigtran_t, conn_conf.m3ua_beat_interval), .dflt = "0" },
98
99 { FR_CONF_OFFSET_IS_SET("route", 0, CONF_FLAG_SUBSECTION, rlm_sigtran_t, conn_conf.m3ua_routes), .subcs = (void const *) m3ua_route },
100
102};
103
104static const conf_parser_t mtp3_config[] = {
105 { FR_CONF_OFFSET_FLAGS("dpc", CONF_FLAG_REQUIRED, rlm_sigtran_t, conn_conf.mtp3_dpc) },
106 { FR_CONF_OFFSET_FLAGS("opc", CONF_FLAG_REQUIRED, rlm_sigtran_t, conn_conf.mtp3_opc) },
107
109};
110
120
128
129static const conf_parser_t sccp_config[] = {
130 { FR_CONF_OFFSET("ai8", rlm_sigtran_t, conn_conf.sccp_ai8) },
131 { FR_CONF_OFFSET("route_on_ssn", rlm_sigtran_t, conn_conf.sccp_route_on_ssn) },
132
133 { FR_CONF_OFFSET_SUBSECTION("called", 0, rlm_sigtran_t, conn_conf.sccp_called, sccp_address) },
134 { FR_CONF_OFFSET_SUBSECTION("calling", 0, rlm_sigtran_t, conn_conf.sccp_calling, sccp_address) },
135
137};
138
139static const conf_parser_t map_config[] = {
140 { FR_CONF_OFFSET("version", rlm_sigtran_t, conn_conf.map_version), .dflt = "2", .quote = T_BARE_WORD},
141
143};
144
145static const conf_parser_t module_config[] = {
146 { FR_CONF_POINTER("sctp", 0, CONF_FLAG_SUBSECTION, NULL), .subcs = (void const *) sctp_config },
147 { FR_CONF_POINTER("m3ua", 0, CONF_FLAG_SUBSECTION, NULL), .subcs = (void const *) m3ua_config },
148 { FR_CONF_POINTER("mtp3", 0, CONF_FLAG_SUBSECTION, NULL), .subcs = (void const *) mtp3_config },
149 { FR_CONF_POINTER("sccp", 0, CONF_FLAG_SUBSECTION, NULL), .subcs = (void const *) sccp_config },
150 { FR_CONF_POINTER("map", 0, CONF_FLAG_SUBSECTION, NULL), .subcs = (void const *) map_config },
151
153
155};
156
158
159/*
160 * UMTS vector
161 */
166
167/*
168 * GSM vector
169 */
172
173/*
174 * Shared
175 */
177
180 { .out = &dict_eap_aka_sim, .base_dir = "eap/aka-sim", .proto = "eap-aka-sim" },
182};
183
185
188 { .out = &attr_eap_aka_sim_autn, .name = "AUTN", .type = FR_TYPE_OCTETS, .dict = &dict_eap_aka_sim },
189 { .out = &attr_eap_aka_sim_ck, .name = "CK", .type = FR_TYPE_OCTETS, .dict = &dict_eap_aka_sim },
190 { .out = &attr_eap_aka_sim_ik, .name = "IK", .type = FR_TYPE_OCTETS, .dict = &dict_eap_aka_sim },
191 { .out = &attr_eap_aka_sim_kc, .name = "KC", .type = FR_TYPE_OCTETS, .dict = &dict_eap_aka_sim },
192 { .out = &attr_eap_aka_sim_rand, .name = "RAND", .type = FR_TYPE_OCTETS, .dict = &dict_eap_aka_sim },
193 { .out = &attr_eap_aka_sim_sres, .name = "SRES", .type = FR_TYPE_OCTETS, .dict = &dict_eap_aka_sim },
194 { .out = &attr_eap_aka_sim_xres, .name = "XRES", .type = FR_TYPE_OCTETS, .dict = &dict_eap_aka_sim },
195
197};
198
199static unlang_action_t CC_HINT(nonnull) mod_authorize(unlang_result_t *p_result, module_ctx_t const *mctx, request_t *request)
200{
203
204 return sigtran_client_map_send_auth_info(p_result, inst, request, inst->conn, t->fd);
205}
206
207/** Convert our sccp address config structure into sockaddr_sccp
208 *
209 * @param ctx to allocated address in.
210 * @param out Where to write the parsed data.
211 * @param conf to parse.
212 * @param cs specifying sccp address.
213 * @return
214 * - 0 on success.
215 * - -1 on failure.
216 */
217static int sigtran_sccp_sockaddr_from_conf(TALLOC_CTX *ctx,
218 struct sockaddr_sccp *out,
220{
221 /*
222 * Fixme should be conf->gt_is_set
223 */
224 if (!conf->ssn_is_set && !conf->pc_is_set && !conf->gt.address) {
225 cf_log_err(cs, "At least one of 'pc', 'ssn', or 'gt', must be set");
226 return -1;
227 }
228
229 if (conf->ssn_is_set) out->ssn = conf->ssn;
230 if (conf->pc_is_set) {
231 if (conf->pc > 16777215) {
232 cf_log_err(cs, "Invalid value \"%d\" for 'pc', must be between 0-"
233 STRINGIFY(16777215), conf->pc);
234 return -1;
235 }
236 out->use_poi = 1;
237
238 memcpy(&out->poi, &conf->pc, sizeof(out->poi));
239 }
240
241 /*
242 * Fixme should be conf->gt_is_set && conf->gt.address
243 * But we don't have subsection presence checks yet.
244 */
245 if (conf->gt_is_set || conf->gt.address) {
246 int gti_ind = SCCP_TITLE_IND_NONE;
247 size_t i;
248 size_t len = talloc_strlen(conf->gt.address);
249
250 if (conf->gt.nai_is_set && (conf->gt.nai & 0x80)) {
251 cf_log_err(cs, "Global title 'nai' must be between 0-127");
252 return -1;
253 }
254
255 if (conf->gt.tt_is_set) {
256 if ((conf->gt.np_is_set && !conf->gt.es_is_set) ||
257 (!conf->gt.np_is_set && conf->gt.np_is_set)) {
258 cf_log_err(cs, "Global title 'np' and 'es' must be "
259 "specified together");
260 return -1;
261 }
262
263 if (conf->gt.np) {
264 cf_log_err(cs, "Global title 'np' must be between 0-15");
265 return -1;
266 }
267
268 if (conf->gt.es > 0x0f) {
269 cf_log_err(cs, "Global title 'es' must be between 0-15");
270 return -1;
271 }
272
273 if (conf->gt.np_is_set) {
274 gti_ind = conf->gt.nai_is_set ? SCCP_TITLE_IND_TRANS_NUM_ENC_NATURE :
275 SCCP_TITLE_IND_TRANS_NUM_ENC;
276 } else {
277 gti_ind = SCCP_TITLE_IND_TRANSLATION_ONLY;
278 }
279 } else if (conf->gt.nai_is_set) {
280 gti_ind = SCCP_TITLE_IND_NATURE_ONLY;
281 }
282
283 for (i = 0; i < len; i++) {
284 if (!is_char_tbcd[(uint8_t)conf->gt.address[i]]) {
285 cf_log_err(cs, "Global title address contains invalid digit \"%c\". "
286 "Valid digits are [0-9#*a-c]", conf->gt.address[i]);
287 return -1;
288 }
289 }
290
291 if (sigtran_sccp_global_title(ctx, &out->gti_data, gti_ind, conf->gt.address,
292 conf->gt.tt, conf->gt.np, conf->gt.es, conf->gt.nai) < 0) return -1;
293 out->gti_len = talloc_array_length(out->gti_data);
294 out->gti_ind = gti_ind;
295 out->national = 1;
296
297 /*
298 * Print out the constructed global title blob.
299 */
300 DEBUG4("gt_ind: 0x%x", out->gti_ind);
301 DEBUG4("digits: 0x%pH (%i)", fr_box_octets(out->gti_data, out->gti_len), out->gti_len);
302 }
303 return 0;
304}
305
307{
308 rlm_sigtran_thread_t *t = talloc_get_type_abort(mctx->thread, rlm_sigtran_thread_t);
309 int fd;
310
312 if (fd < 0) {
313 ERROR("Failed registering thread with multiplexer");
314 return -1;
315 }
316
317 t->fd = fd;
318
319 return 0;
320}
321
323{
324 rlm_sigtran_thread_t *t = talloc_get_type_abort(mctx->thread, rlm_sigtran_thread_t);
325
326 sigtran_client_thread_unregister(mctx->el, t->fd); /* Also closes our side */
327
328 return 0;
329}
330
331static int mod_instantiate(module_inst_ctx_t const *mctx)
332{
333 rlm_sigtran_t *inst = talloc_get_type_abort(mctx->mi->data, rlm_sigtran_t);
334 CONF_SECTION const *conf = mctx->mi->conf;
335
336 /*
337 * Translate traffic mode string to integer
338 */
339 inst->conn_conf.m3ua_traffic_mode = fr_table_value_by_str(m3ua_traffic_mode_table,
340 inst->conn_conf.m3ua_traffic_mode_str, -1);
341 if (inst->conn_conf.m3ua_traffic_mode < 0) {
342 cf_log_err(conf, "Invalid 'm3ua_traffic_mode' value \"%s\", expected 'override', "
343 "'loadshare' or 'broadcast'", inst->conn_conf.m3ua_traffic_mode_str);
344 return -1;
345 }
346
347#define MTP3_PC_CHECK(_x) \
348 do { \
349 if (inst->conn_conf.mtp3_##_x > 16777215) { \
350 cf_log_err(conf, "Invalid value \"%d\" for '#_x', must be between 0-16777215", \
351 inst->conn_conf.mtp3_##_x); \
352 return -1; \
353 } \
354 __hack_##_x = inst->conn_conf.mtp3_##_x; \
355 } while (0)
356
357 MTP3_PC_CHECK(dpc);
358 MTP3_PC_CHECK(opc);
359
360 if (sigtran_sccp_sockaddr_from_conf(inst, &inst->conn_conf.sccp_called_sockaddr,
361 &inst->conn_conf.sccp_called, conf) < 0) return -1;
362 if (sigtran_sccp_sockaddr_from_conf(inst, &inst->conn_conf.sccp_calling_sockaddr,
363 &inst->conn_conf.sccp_calling, conf) < 0) return -1;
364
365 /*
366 * Don't bother starting the sigtran thread if we're
367 * just checking the config.
368 */
369 if (check_config) return 0;
370
371 /*
372 * If this is the first instance of rlm_sigtran
373 * We spawn a new thread to run all the libosmo-* I/O
374 * and events.
375 *
376 * We talk to the thread using the ctrl_pipe, with
377 * each thread registering its own pipe via the ctrl_pipe.
378 *
379 * This makes it really easy to collect and distribute
380 * requests/responses, whilst using libosmo in a
381 * threadsafe way.
382 */
385
386 /*
387 * Should bring the SCTP/M3UA/MTP3/SCCP link up.
388 */
389 if (sigtran_client_link_up(&inst->conn, &inst->conn_conf) < 0) return -1;
390
391 return 0;
392}
393
394/**
395 * Cleanup internal state.
396 */
397static int mod_detach(module_detach_ctx_t const *mctx)
398{
399 rlm_sigtran_t *inst = talloc_get_type_abort(mctx->mi->data, rlm_sigtran_t);
400
401 /*
402 * If we're just checking the config we didn't start the
403 * thread.
404 */
405 if (check_config) return 0;
406
408
410
411 return 0;
412}
413
414/*
415 * The module name should be the only globally exported symbol.
416 * That is, everything else should be 'static'.
417 *
418 * If the module needs to temporarily modify it's instantiation
419 * data, the type should be changed to MODULE_TYPE_THREAD_UNSAFE.
420 * The server will then take care of ensuring that the module
421 * is single-threaded.
422 */
425 .common = {
426 .magic = MODULE_MAGIC_INIT,
427 .name = "sigtran",
428 .inst_size = sizeof(rlm_sigtran_t),
429 .thread_inst_size = sizeof(rlm_sigtran_thread_t),
430 .config = module_config,
431 .instantiate = mod_instantiate,
432 .detach = mod_detach,
433 .thread_instantiate = mod_thread_instantiate,
434 .thread_detach = mod_thread_detach
435 },
436 .method_group = {
437 .bindings = (module_method_binding_t[]){
438 { .section = SECTION_NAME(CF_IDENT_ANY, CF_IDENT_ANY), .method = mod_authorize },
440 }
441 }
442};
unlang_action_t
Returned by unlang_op_t calls, determine the next action of the interpreter.
Definition action.h:35
#define RCSID(id)
Definition build.h:488
#define L(_str)
Helper for initialising arrays of string literals.
Definition build.h:210
#define STRINGIFY(x)
Definition build.h:198
#define NUM_ELEMENTS(_t)
Definition build.h:340
bool check_config
Definition cf_file.c:61
#define CONF_PARSER_TERMINATOR
Definition cf_parse.h:657
#define FR_CONF_OFFSET(_name, _struct, _field)
conf_parser_t which parses a single CONF_PAIR, writing the result to a field in a struct
Definition cf_parse.h:280
fr_token_t quote
Quoting around the default value. Only used for templates.
Definition cf_parse.h:649
#define FR_CONF_POINTER(_name, _type, _flags, _res_p)
conf_parser_t which parses a single CONF_PAIR producing a single global result
Definition cf_parse.h:334
#define FR_CONF_OFFSET_IS_SET(_name, _type, _flags, _struct, _field)
conf_parser_t which parses a single CONF_PAIR, writing the result to a field in a struct,...
Definition cf_parse.h:294
#define FR_CONF_OFFSET_FLAGS(_name, _flags, _struct, _field)
conf_parser_t which parses a single CONF_PAIR, writing the result to a field in a struct
Definition cf_parse.h:268
#define FR_CONF_OFFSET_SUBSECTION(_name, _flags, _struct, _field, _subcs)
conf_parser_t which populates a sub-struct using a CONF_SECTION
Definition cf_parse.h:309
@ CONF_FLAG_REQUIRED
Error out if no matching CONF_PAIR is found, and no dflt value is set.
Definition cf_parse.h:429
@ CONF_FLAG_MULTI
CONF_PAIR can have multiple copies.
Definition cf_parse.h:446
@ CONF_FLAG_SUBSECTION
Instead of putting the information into a configuration structure, the configuration file routines MA...
Definition cf_parse.h:423
#define FR_CONF_OFFSET_TYPE_FLAGS(_name, _type, _flags, _struct, _field)
conf_parser_t which parses a single CONF_PAIR, writing the result to a field in a struct
Definition cf_parse.h:238
Defines a CONF_PAIR to C data type mapping.
Definition cf_parse.h:594
A section grouping multiple CONF_PAIR.
Definition cf_priv.h:101
#define cf_log_err(_cf, _fmt,...)
Definition cf_util.h:285
#define CF_IDENT_ANY
Definition cf_util.h:75
#define ERROR(fmt,...)
Definition dhcpclient.c:40
fr_dict_attr_t const ** out
Where to write a pointer to the resolved fr_dict_attr_t.
Definition dict.h:292
fr_dict_t const ** out
Where to write a pointer to the loaded/resolved fr_dict_t.
Definition dict.h:305
#define DICT_AUTOLOAD_TERMINATOR
Definition dict.h:311
Specifies an attribute which must be present for the module to function.
Definition dict.h:291
Specifies a dictionary which must be loaded/loadable for the module to function.
Definition dict.h:304
#define MODULE_MAGIC_INIT
Stop people using different module/library/server versions together.
Definition dl_module.h:63
#define DEBUG4(_fmt,...)
Definition log.h:267
@ FR_TYPE_UINT8
8 Bit unsigned integer.
@ FR_TYPE_UINT32
32 Bit unsigned integer.
@ FR_TYPE_COMBO_IP_ADDR
IPv4 or IPv6 address depending on length.
@ FR_TYPE_OCTETS
Raw octets.
unsigned int uint32_t
unsigned char uint8_t
module_instance_t const * mi
Instance of the module being instantiated.
Definition module_ctx.h:42
void * thread
Thread specific instance data.
Definition module_ctx.h:43
fr_event_list_t * el
Event list to register any IO handlers and timers against.
Definition module_ctx.h:68
module_instance_t * mi
Module instance to detach.
Definition module_ctx.h:57
void * thread
Thread instance data.
Definition module_ctx.h:67
module_instance_t * mi
Instance of the module being instantiated.
Definition module_ctx.h:51
Temporary structure to hold arguments for module calls.
Definition module_ctx.h:41
Temporary structure to hold arguments for detach calls.
Definition module_ctx.h:56
Temporary structure to hold arguments for instantiation calls.
Definition module_ctx.h:50
Temporary structure to hold arguments for thread_instantiation calls.
Definition module_ctx.h:63
int sigtran_event_start(void)
Start the libosmo event loop.
Definition event.c:523
int sigtran_event_exit(void)
Signal that libosmo should exit.
Definition event.c:579
VQP attributes.
static rs_t * conf
Definition radsniff.c:52
static const conf_parser_t m3ua_route[]
Definition rlm_sigtran.c:84
static int mod_detach(module_detach_ctx_t const *mctx)
Cleanup internal state.
static const conf_parser_t sccp_config[]
fr_dict_attr_t const * attr_eap_aka_sim_ik
fr_dict_attr_t const * attr_eap_aka_sim_xres
fr_dict_attr_t const * attr_eap_aka_sim_ck
static fr_table_num_sorted_t const m3ua_traffic_mode_table[]
Definition rlm_sigtran.c:65
static const conf_parser_t map_config[]
static const conf_parser_t sccp_global_title[]
fr_dict_attr_t const * attr_eap_aka_sim_sres
fr_dict_attr_autoload_t rlm_sigtran_dict_attr[]
fr_dict_attr_t const * attr_eap_aka_sim_kc
static uint32_t sigtran_instances
Definition rlm_sigtran.c:61
fr_dict_attr_t const * attr_auth_type
fr_dict_autoload_t rlm_sigtran_dict[]
static unlang_action_t mod_authorize(unlang_result_t *p_result, module_ctx_t const *mctx, request_t *request)
static const conf_parser_t sccp_address[]
fr_dict_attr_t const * attr_eap_aka_sim_autn
fr_dict_t const * dict_eap_aka_sim
static const conf_parser_t sctp_config[]
Definition rlm_sigtran.c:72
static int sigtran_sccp_sockaddr_from_conf(TALLOC_CTX *ctx, struct sockaddr_sccp *out, sigtran_sccp_address_t *conf, CONF_SECTION *cs)
Convert our sccp address config structure into sockaddr_sccp.
static int mod_thread_instantiate(module_thread_inst_ctx_t const *mctx)
static size_t m3ua_traffic_mode_table_len
Definition rlm_sigtran.c:70
unsigned int __hack_dpc
Definition rlm_sigtran.c:63
module_rlm_t rlm_sigtran
static const conf_parser_t m3ua_config[]
Definition rlm_sigtran.c:92
static const conf_parser_t mtp3_config[]
static const conf_parser_t module_config[]
#define MTP3_PC_CHECK(_x)
static int mod_thread_detach(module_thread_inst_ctx_t const *mctx)
static int mod_instantiate(module_inst_ctx_t const *mctx)
unsigned int __hack_opc
Definition rlm_sigtran.c:63
fr_dict_attr_t const * attr_eap_aka_sim_rand
#define SECTION_NAME(_name1, _name2)
Define a section name consisting of a verb and a noun.
Definition section.h:39
CONF_SECTION * conf
Module's instance configuration.
Definition module.h:349
void * data
Module's instance data.
Definition module.h:291
#define MODULE_BINDING_TERMINATOR
Terminate a module binding list.
Definition module.h:152
Named methods exported by a module.
Definition module.h:174
uint8_t const is_char_tbcd[]
Check is a char is valid Telephony Binary Coded Decimal.
Definition sigtran.c:73
Declarations for various sigtran functions.
struct rlm_sigtran rlm_sigtran_t
int fd
File descriptor.
Definition sigtran.h:240
Structure representing a complete Q.173 SCCP address.
Definition sigtran.h:120
int sigtran_client_thread_register(fr_event_list_t *el)
Called by a new thread to register a new req_pipe.
Definition client.c:144
int sigtran_client_link_up(sigtran_conn_t const **out, sigtran_conn_conf_t const *conn_conf)
Create a new connection.
Definition client.c:225
int sigtran_client_thread_unregister(fr_event_list_t *el, int req_pipe_fd)
Signal that libosmo should unregister the other side of the pipe.
Definition client.c:193
int sigtran_client_link_down(sigtran_conn_t const **conn)
Destroy a connection.
Definition client.c:250
unlang_action_t sigtran_client_map_send_auth_info(unlang_result_t *p_result, rlm_sigtran_t const *inst, request_t *request, sigtran_conn_t const *conn, int fd)
Create a MAP_SEND_AUTH_INFO request.
Definition client.c:406
eap_aka_sim_process_conf_t * inst
#define fr_table_value_by_str(_table, _name, _def)
Convert a string to a value using a sorted or ordered table.
Definition table.h:653
An element in a lexicographically sorted array of name to num mappings.
Definition table.h:49
#define talloc_get_type_abort_const
Definition talloc.h:110
static size_t talloc_strlen(char const *s)
Returns the length of a talloc array containing a string.
Definition talloc.h:136
@ T_BARE_WORD
Definition token.h:118
int nonnull(2, 5))
static size_t char ** out
Definition value.h:1030
#define fr_box_octets(_val, _len)
Definition value.h:311