static int forward_ussd(struct nat_sccp_connection *con, const struct ussd_request *req, struct msgb *input) { struct msgb *msg, *copy; struct ipac_msgt_sccp_state *state; struct bsc_nat_ussd_con *ussd; uint16_t lac, ci; if (!con->bsc->nat->ussd_con) return -1; msg = msgb_alloc_headroom(4096, 128, "forward ussd"); if (!msg) { LOGP(DNAT, LOGL_ERROR, "Allocation failed, not forwarding.\n"); return -1; } copy = msgb_alloc_headroom(4096, 128, "forward bts"); if (!copy) { LOGP(DNAT, LOGL_ERROR, "Allocation failed, not forwarding.\n"); msgb_free(msg); return -1; } copy->l2h = msgb_put(copy, msgb_l2len(input)); memcpy(copy->l2h, input->l2h, msgb_l2len(input)); msg->l2h = msgb_put(msg, 1); msg->l2h[0] = IPAC_MSGT_SCCP_OLD; /* fill out the data */ state = (struct ipac_msgt_sccp_state *) msgb_put(msg, sizeof(*state)); state->trans_id = req->transaction_id; state->invoke_id = req->invoke_id; memcpy(&state->src_ref, &con->remote_ref, sizeof(con->remote_ref)); memcpy(&state->dst_ref, &con->real_ref, sizeof(con->real_ref)); memcpy(state->imsi, con->filter_state.imsi, strlen(con->filter_state.imsi)); /* add additional tag/values */ lac = htons(con->lac); ci = htons(con->ci); msgb_tv_fixed_put(msg, USSD_LAC_IE, sizeof(lac), (const uint8_t *) &lac); msgb_tv_fixed_put(msg, USSD_CI_IE, sizeof(ci), (const uint8_t *) &ci); ussd = con->bsc->nat->ussd_con; bsc_do_write(&ussd->queue, msg, IPAC_PROTO_IPACCESS); bsc_do_write(&ussd->queue, copy, IPAC_PROTO_SCCP); return 0; }
static void ussd_pong(struct bsc_nat_ussd_con *conn) { struct msgb *msg; msg = msgb_alloc_headroom(4096, 128, "pong message"); if (!msg) { LOGP(DNAT, LOGL_ERROR, "Failed to allocate pong msg\n"); return; } msgb_v_put(msg, IPAC_MSGT_PONG); bsc_do_write(&conn->queue, msg, IPAC_PROTO_IPACCESS); }
static void ussd_start_auth(struct bsc_nat_ussd_con *conn) { struct msgb *msg; conn->auth_timeout.data = conn; conn->auth_timeout.cb = ussd_auth_cb; osmo_timer_schedule(&conn->auth_timeout, conn->nat->auth_timeout, 0); msg = msgb_alloc_headroom(4096, 128, "auth message"); if (!msg) { LOGP(DNAT, LOGL_ERROR, "Failed to allocate auth msg\n"); return; } msgb_v_put(msg, IPAC_MSGT_ID_GET); bsc_do_write(&conn->queue, msg, IPAC_PROTO_IPACCESS); }
static int forward_ussd_simple(struct sccp_connections *con, struct msgb *input) { struct msgb *copy; struct bsc_nat_ussd_con *ussd; if (!con->bsc->nat->ussd_con) return -1; copy = msgb_alloc_headroom(4096, 128, "forward bts"); if (!copy) { LOGP(DNAT, LOGL_ERROR, "Allocation failed, not forwarding.\n"); return -1; } /* copy the data into the copy */ copy->l2h = msgb_put(copy, msgb_l2len(input)); memcpy(copy->l2h, input->l2h, msgb_l2len(input)); /* send it out */ ussd = con->bsc->nat->ussd_con; bsc_do_write(&ussd->queue, copy, IPAC_PROTO_SCCP); return 0; }