37 #define LOG_PREFIX "sigtran - osmocom thread"
39 #include <osmocom/core/talloc.h>
41 #include <freeradius-devel/server/base.h>
42 #include <freeradius-devel/util/debug.h>
43 #include <osmocom/core/msgb.h>
44 #include <osmocom/core/utils.h>
50 #include "libosmo-m3ua/include/cellmgr_debug.h"
51 #include "libosmo-m3ua/include/mtp_data.h"
52 #include "libosmo-m3ua/include/sctp_m3ua.h"
68 return CMP(a->
ctx.invoke_id, b->
ctx.invoke_id);
75 ERROR(
"OTID %u Invoke ID %u timeout", txn->
ctx.otid, txn->
ctx.invoke_id);
100 static uint8_t tcap_map_raw_v2[] = {
101 0x62, 0x43, 0x48, 0x01, 0x01, 0x6b, 0x80, 0x28,
102 0x80, 0x06, 0x07, 0x00, 0x11, 0x86, 0x05, 0x01,
103 0x01, 0x01, 0xa0, 0x80, 0x60, 0x80, 0x80, 0x02,
104 0x07, 0x80, 0xa1, 0x80, 0x06, 0x07, 0x04, 0x00,
105 0x00, 0x01, 0x00, 0x0e, 0x02, 0x00, 0x00, 0x00,
106 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x6c,
107 0x14, 0xa1, 0x80, 0x02, 0x01, 0x03, 0x02, 0x01,
108 0x38, 0x04, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
109 0xff, 0xff, 0xff, 0x00, 0x00 };
111 static uint8_t tcap_map_raw_v3[] = {
112 0x62, 0x48, 0x48, 0x01, 0x01, 0x6b, 0x80, 0x28,
113 0x80, 0x06, 0x07, 0x00, 0x11, 0x86, 0x05, 0x01,
114 0x01, 0x01, 0xa0, 0x80, 0x60, 0x80, 0x80, 0x02,
115 0x07, 0x80, 0xa1, 0x80, 0x06, 0x07, 0x04, 0x00,
116 0x00, 0x01, 0x00, 0x0e, 0x03, 0x00, 0x00, 0x00,
117 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x6c,
118 0x19, 0xa1, 0x80, 0x02, 0x01, 0x01, 0x02, 0x01,
119 0x38, 0x30, 0x0d, 0x80, 0x00, 0x00, 0x00, 0x00,
120 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x01, 0x01,
129 struct mtp_m3ua_client_link *m3ua_client = talloc_get_type_abort(conn->
mtp3_link->data,
130 struct mtp_m3ua_client_link);
134 if (!mtp_m3ua_link_is_up(m3ua_client)) {
135 ERROR(
"Link not yet active, dropping the request");
141 ERROR(
"Too many outstanding requests, dropping the request");
148 DEBUG4(
"Allocating buffer for MAP v2, %zu bytes",
sizeof(tcap_map_raw_v2));
149 msg = msgb_alloc(
sizeof(tcap_map_raw_v2),
"sccp: tcap_map");
150 msg->l3h = msgb_put(
msg,
sizeof(tcap_map_raw_v2));
151 memcpy(
msg->l3h, tcap_map_raw_v2,
sizeof(tcap_map_raw_v2));
153 *(
msg->l3h + 0x3a) = talloc_array_length(req->
imsi);
154 memcpy(
msg->l3h + 0x3b, req->
imsi, talloc_array_length(req->
imsi));
160 DEBUG4(
"Allocating buffer for MAP v3, %zu bytes",
sizeof(tcap_map_raw_v3));
161 msg = msgb_alloc(
sizeof(tcap_map_raw_v3),
"sccp: tcap_map");
162 msg->l3h = msgb_put(
msg,
sizeof(tcap_map_raw_v3));
163 memcpy(
msg->l3h, tcap_map_raw_v3,
sizeof(tcap_map_raw_v3));
165 *(
msg->l3h + 0x3c) = talloc_array_length(req->
imsi);
166 memcpy(
msg->l3h + 0x3d, req->
imsi, talloc_array_length(req->
imsi));
181 txn->
ctx.invoke_id++;
182 txn->
ctx.invoke_id &= 0x7f;
183 DEBUG2(
"Sending request with OTID %u Invoke ID %u", txn->
ctx.otid, txn->
ctx.invoke_id);
186 ERROR(
"Failed inserting transaction, maybe at txn limit?");
195 *(
msg->l3h + 0x04) = txn->
ctx.otid;
196 *(
msg->l3h + 0x35) = txn->
ctx.invoke_id;
199 SCCP_PROTOCOL_RETURN_MESSAGE << 4 | SCCP_PROTOCOL_CLASS_0, ctx);
203 txn->
ctx.timer.data = txn;
206 osmo_timer_schedule(&txn->
ctx.timer, 1, 0);
231 memset(&find, 0,
sizeof(find));
235 DEBUG3(
"Got %zu bytes of L4 data", (
size_t)msgb_l3len(
msg));
238 find.
ctx.otid = *(
msg->l3h + 0x5);
241 find.
ctx.invoke_id = 1;
242 DEBUG2(
"Received response with DTID %u Invoke ID %u", find.
ctx.otid, find.
ctx.invoke_id);
252 ERROR(
"No outstanding transaction with DTID %u Invoke ID %u", find.
ctx.otid, find.
ctx.invoke_id);
256 ERROR(
"Failed removing transaction");
263 osmo_timer_del(&txn->
ctx.timer);
270 #define sigtran_memdup(_x) \
273 DEBUG4("Start 0x%02x len %u", (unsigned int)(tcap - p), p[0]); \
274 if (p[0] >= (len - (p - tcap))) { \
275 ERROR("Invalid length %u specified for vector component", p[0]); \
278 vec->_x = talloc_memdup(vec, p + 1, p[0]); \
279 talloc_set_type(vec->_x, uint8_t); \
283 end = tcap + msgb_l3len(
msg);
294 if ((p[0] != 0x30) || (p[1] != 0x22)) {
295 DEBUG4(
"Breaking out of parsing loop at %x", (
uint32_t)(p - tcap));
310 }
else if (req->
version == 3) {
337 struct msgb *
msg,
UNUSED void *write_ctx,
void *ctx)
354 sccp_system_incoming(
msg);
362 sccp_set_log_area(DSCCP);
365 sccp_set_variant(SCCP_VARIANT_ANSI);
#define CMP_RETURN(_a, _b, _field)
Return if the comparison is not 0 (is unequal)
#define CMP(_a, _b)
Same as CMP_PREFER_SMALLER use when you don't really care about ordering, you just want an ordering.
#define fr_assert_fail(_msg,...)
Calls panic_action ifndef NDEBUG, else logs error.
int sigtran_event_submit(struct osmo_fd *ofd, sigtran_transaction_t *txn)
Send response.
uint32_t fr_rb_num_elements(fr_rb_tree_t *tree)
#define fr_rb_inline_talloc_alloc(_ctx, _type, _field, _data_cmp, _data_free)
Allocs a red black that verifies elements are of a specific talloc type.
bool fr_rb_insert(fr_rb_tree_t *tree, void const *data)
bool fr_rb_delete(fr_rb_tree_t *tree, void const *data)
void * fr_rb_find(fr_rb_tree_t const *tree, void const *data)
The main red black tree structure.
static uint32_t txn_tree_inst
void sigtran_sccp_incoming(UNUSED struct mtp_link_set *set, struct msgb *msg, UNUSED int sls)
Wrapper to pass data off to libsccp for processing.
#define sigtran_memdup(_x)
void sigtran_sccp_global_free(void)
static void sigtran_sccp_outgoing(UNUSED struct sccp_connection *sscp_conn, struct msgb *msg, UNUSED void *write_ctx, void *ctx)
Wrapper to pass data down to MTP3 layer for processing.
static fr_rb_tree_t * txn_tree
Global transaction tree... Should really be per module.
static uint32_t last_txn_id
Global transaction ID.
int sigtran_tcap_outgoing(UNUSED struct msgb *msg_in, void *ctx, sigtran_transaction_t *txn, UNUSED struct osmo_fd *ofd)
Send a request with static MAP data in it.
static int sigtran_tcap_incoming(struct msgb *msg, UNUSED unsigned int length, UNUSED void *ctx)
Incoming data.
int sigtran_sscp_init(sigtran_conn_t *conn)
Initialise libscctp.
static void sigtran_tcap_timeout(void *data)
static int sigtran_txn_cmp(void const *one, void const *two)
Compare rounds of a transaction.
int sigtran_sccp_global_init(void)
Declarations for various sigtran functions.
@ SIGTRAN_VECTOR_TYPE_UMTS_QUINTUPLETS
RAND, XRES, CK, IK, AUTN.
@ SIGTRAN_VECTOR_TYPE_SIM_TRIPLETS
RAND, SRES, Kc.
@ SIGTRAN_RESPONSE_OK
Request succeeded.
@ SIGTRAN_RESPONSE_FAIL
Request failed.
struct mtp_link_set * mtp3_link_set
uint8_t * imsi
BCD encoded IMSI.
struct sigtran_transaction::@173 response
sigtran_vector_type_t type
Type of vector returned.
struct sockaddr_sccp sccp_calling_sockaddr
Parsed version of the above.
sigtran_conn_conf_t * conf
uint8_t version
Application context version.
struct sigtran_transaction::@172 request
struct sigtran_transaction::@174 ctx
struct mtp_link * mtp3_link
sigtran_vector_t * vector
Linked list of vectors.
sigtran_vector_t * next
Next vector in list.
struct sockaddr_sccp sccp_called_sockaddr
Parsed version of the above.
Represents a connection to a remote SS7 entity.
MAP send auth info request.
MAP send auth info response.
Request and response from the event loop.
Authentication vector returned by HLR.
MEM(pair_append_request(&vp, attr_eap_aka_sim_identity) >=0)
char const * fr_syserror(int num)
Guaranteed to be thread-safe version of strerror.