void p2pRequest(struct session *session_a, struct session *session_b) { char *ip_a; char *ip_b; uint32_t port; DNDSMessage_t *msg; if (session_a->netc == NULL || session_b->netc == NULL) { return; } if (!strcmp(session_a->netc->peer->host, session_b->netc->peer->host)) { ip_a = session_a->ip_local; ip_b = session_b->ip_local; } else { ip_a = session_a->netc->peer->host; ip_b = session_b->netc->peer->host; } /* basic random port : 49152–65535 */ port = rand() % (65535-49152+1)+49152; jlog(L_DEBUG, "node A ip public %s", ip_a); jlog(L_DEBUG, "node B ip public %s", ip_b); /* msg session A */ DNDSMessage_new(&msg); DNDSMessage_set_pdu(msg, pdu_PR_dnm); DNMessage_set_operation(msg, dnop_PR_p2pRequest); P2pRequest_set_macAddrDst(msg, session_b->tun_mac_addr); P2pRequest_set_ipAddrDst(msg, ip_b); P2pRequest_set_port(msg, port); P2pRequest_set_side(msg, P2pSide_client); net_send_msg(session_a->netc, msg); DNDSMessage_del(msg); /* msg session B */ DNDSMessage_new(&msg); DNDSMessage_set_pdu(msg, pdu_PR_dnm); DNMessage_set_operation(msg, dnop_PR_p2pRequest); P2pRequest_set_macAddrDst(msg, session_a->tun_mac_addr); P2pRequest_set_ipAddrDst(msg, ip_a); P2pRequest_set_port(msg, port); P2pRequest_set_side(msg, P2pSide_server); net_send_msg(session_b->netc, msg); DNDSMessage_del(msg); }
int send_msg_to_switch(Csprite* p, uint16_t cmd, userid_t sender_id ,Cmessage * c_in) { //Common buffer for sending package to switch //Connect to switch and send init package in case of disconnection if (switch_fd == -1) { connect_to_switch(); } if ((switch_fd == -1) ) { KDEBUG_LOG(sender_id, "FAILED SENDING PACKAGE TO SWITCH\t[switch_fd=%d]", switch_fd); return 0; } //Build the package static uint8_t sw_pkg[sizeof(switch_proto_t) ]; switch_proto_t* pkg = (switch_proto_t*)sw_pkg; pkg->len = sizeof(switch_proto_t ); pkg->seq = (p ? ((p->fdsess->fd) << 16) | (p->get_waitcmd()) : 0); // set higher 16 bytes fd and lower 16 bytes waitcmd pkg->cmd = cmd; pkg->ret = 0; pkg->sender_id = sender_id; if (p) { KDEBUG_LOG(p->id, "TO SW\t[cmd=%u waitcmd=%u]", cmd, p->get_waitcmd()); } return net_send_msg(switch_fd , (char*)pkg , c_in ); }
int send_msg_to_db_ex(Csprite* p, userid_t id, uint16_t cmd, Cmessage * c_in ) { if (proxysvr_fd == -1) { proxysvr_fd = connect_to_service(config_get_strval("service_dbproxy"), 0, 65535, 1); } if ((proxysvr_fd == -1) ) { KDEBUG_LOG(id, "send to dbproxy failed: fd=%d ", proxysvr_fd ); if (p) { if (p->get_waitcmd()== cli_login_cmd) { return -1; } return p->send_err( cli_err_system_error ); } return 0; } static char dbbuf[ sizeof(db_proto_t) ]; db_proto_t* pkg = (db_proto_t*)dbbuf; pkg->len = sizeof(db_proto_t); pkg->seq = (p ? ((p->fdsess->fd << 16) | p->get_waitcmd()) : 0); pkg->cmd = cmd; pkg->ret = 0; pkg->id = id; KDEBUG_LOG(pkg->id,"SO[0x%04X]",pkg->cmd ); return net_send_msg(proxysvr_fd, (char*)dbbuf, c_in ); }
static void on_secure(netc_t *netc) { struct session *session; session = netc->ext_ptr; if (session->state == SESSION_STATE_WAIT_STEPUP) { /* Set the session as authenticated */ session->state = SESSION_STATE_AUTHED; /* Send a message to acknowledge the client */ DNDSMessage_t *msg = NULL; DNDSMessage_new(&msg); DNDSMessage_set_channel(msg, 0); DNDSMessage_set_pdu(msg, pdu_PR_dnm); DNMessage_set_seqNumber(msg, 1); DNMessage_set_ackNumber(msg, 0); DNMessage_set_operation(msg, dnop_PR_authResponse); AuthResponse_set_result(msg, DNDSResult_success); net_send_msg(session->netc, msg); DNDSMessage_del(msg); context_add_session(session->context, session); jlog(L_DEBUG, "session id: %d", session->id); } }
void transmit_netinfo_response(netc_t *netc) { struct session *session = netc->ext_ptr; DNDSMessage_t *msg = NULL; DNDSMessage_new(&msg); DNDSMessage_set_channel(msg, 0); DNDSMessage_set_pdu(msg, pdu_PR_dnm); DNMessage_set_seqNumber(msg, 1); DNMessage_set_ackNumber(msg, 0); DNMessage_set_operation(msg, dnop_PR_netinfoResponse); net_send_msg(session->netc, msg); DNDSMessage_del(msg); transmit_node_connectinfo(ConnectState_connected, session->ip, session->cert_name); }
/* Authentication Request from the node */ int authRequest(struct session *session, DNDSMessage_t *req_msg) { char *certName = NULL; size_t length = 0; struct session *old_session = NULL; if (session->state != SESSION_STATE_NOT_AUTHED) { jlog(L_WARNING, "authRequest duplicate"); return -1; } DNDSMessage_t *msg = NULL; DNDSMessage_new(&msg); DNDSMessage_set_channel(msg, 0); DNDSMessage_set_pdu(msg, pdu_PR_dnm); DNMessage_set_seqNumber(msg, 1); DNMessage_set_ackNumber(msg, 0); DNMessage_set_operation(msg, dnop_PR_authResponse); AuthRequest_get_certName(req_msg, &certName, &length); jlog(L_DEBUG, "URI:%s", certName); session->node_info = cn2node_info(certName); if (session->node_info == NULL) { jlog(L_WARNING, "cn2node_info failed"); DNDSMessage_del(msg); return -1; } // jlog(L_DEBUG, "type: %s", session->node_info->type); jlog(L_DEBUG, "uuid: %s", session->node_info->uuid); jlog(L_DEBUG, "network_uuid: %s", session->node_info->network_uuid); jlog(L_DEBUG, "network_id: %s", session->node_info->network_id); jlog(L_DEBUG, "v: %d", session->node_info->v); if (session->node_info->v == 1) { session->vnetwork = vnetwork_lookup_id(session->node_info->network_id); if (session->vnetwork != NULL) { strncpy(session->node_info->network_uuid, session->vnetwork->uuid, 36); session->node_info->network_uuid[36] = '\0'; } } else session->vnetwork = vnetwork_lookup(session->node_info->network_uuid); if (session->vnetwork == NULL) { AuthResponse_set_result(msg, DNDSResult_noRight); net_send_msg(session->netc, msg); DNDSMessage_del(msg); return -1; } /* check if the node's uuid is known if (ctable_find(session->context->atable, session->node_info->uuid) == NULL) { AuthResponse_set_result(msg, DNDSResult_noRight); net_send_msg(session->netc, msg); DNDSMessage_del(msg); jlog(L_ERROR, "authentication failed, invalid certificate"); return -1; } */ /* check if the node is already connected */ old_session = ctable_find(session->vnetwork->ctable, session->node_info->uuid); // if (old_session == NULL) { ctable_insert(session->vnetwork->ctable, session->node_info->uuid, session); /* } else { // that node is already connected, if the new session is from the same IP // disconnect the old session, and let this one connect if (old_session->ip == NULL) { net_disconnect(old_session->netc); ctable_insert(session->vnetwork->ctable, session->node_info->uuid, session); } else if (strcmp(old_session->ip, session->ip) == 0) { net_disconnect(old_session->netc); ctable_insert(session->vnetwork->ctable, session->node_info->uuid, session); } } */ session->cert_name = strdup(certName); if (session->netc->security_level == NET_UNSECURE) { AuthResponse_set_result(msg, DNDSResult_success); net_send_msg(session->netc, msg); session->state = SESSION_STATE_AUTHED; session->netc->on_secure(session->netc); } else { AuthResponse_set_result(msg, DNDSResult_secureStepUp); net_send_msg(session->netc, msg); krypt_add_passport(session->netc->kconn, session->vnetwork->passport); session->state = SESSION_STATE_WAIT_STEPUP; net_step_up(session->netc); } DNDSMessage_del(msg); return 0; }
static void forward_ethernet(struct session *session, DNDSMessage_t *msg) { uint8_t *frame; size_t frame_size; uint8_t macaddr_src[ETHER_ADDR_LEN]; uint8_t macaddr_dst[ETHER_ADDR_LEN]; uint8_t macaddr_dst_type; struct session *session_dst = NULL; struct session *session_src = NULL; struct session *session_list = NULL; if (session->state != SESSION_STATE_AUTHED) return; DNDSMessage_get_ethernet(msg, &frame, &frame_size); /* New mac address ? Add it to the lookup table */ inet_get_mac_addr_src(frame, macaddr_src); session_src = ftable_find(session->context->ftable, macaddr_src); if (session_src == NULL) { memcpy(session->mac_addr, macaddr_src, ETHER_ADDR_LEN); ftable_insert(session->context->ftable, macaddr_src, session); session_src = session; session_add_mac(session, macaddr_src); } /* Lookup the destination */ inet_get_mac_addr_dst(frame, macaddr_dst); macaddr_dst_type = inet_get_mac_addr_type(macaddr_dst); session_dst = ftable_find(session->context->ftable, macaddr_dst); if (session_src != NULL && session_dst != NULL && (session_src == session_dst)) { /* prevent loops */ return; } if (macaddr_dst_type == ADDR_MULTICAST) { /* Multicast is not supported yet */ return; } /* Switch forwarding */ if (macaddr_dst_type == ADDR_UNICAST /* The destination address is unicast */ && session_dst != NULL && session_dst->netc != NULL) { /* AND the session is up */ /*jlog(L_DEBUG, "forwarding the packet to [%s]", session_dst->ip);*/ net_send_msg(session_dst->netc, msg); int lnk_state = 0; lnk_state = linkst_joined(session_src->context->linkst, session_src->id, session_dst->id); if (lnk_state != 1) { p2pRequest(session_src, session_dst); linkst_join(session_src->context->linkst, session_src->id, session_dst->id); } /* Switch flooding */ } else if (macaddr_dst_type == ADDR_BROADCAST || /* This packet has to be broadcasted */ session_dst == NULL) { /* OR the fib session is down */ session_list = session->context->session_list; while (session_list != NULL) { net_send_msg(session_list->netc, msg); /*jlog(L_DEBUG, "flooding the packet to [%s]", session_list->ip);*/ session_list = session_list->next; } } else { jlog(L_WARNING, "unknown packet"); } }
int provisioning(json_t *jmsg) { char *cert; char *ipaddr; char *pkey; char *response; char *tcert; char *tid; json_t *node; struct session *session; if (json_unpack(jmsg, "{s:s}", "response", &response) == -1) { jlog(L_ERROR, "json_unpack failed"); return -1; } if (strcmp(response, "success") != 0) { jlog(L_ERROR, "provisioning != success"); return -1; } if (json_unpack(jmsg, "{s:s}", "tid", &tid) == -1) { jlog(L_ERROR, "json_unpack failed"); return -1; } if ((node = json_object_get(jmsg, "node")) == NULL) { jlog(L_ERROR, "json_object_get failed"); return -1; } if (json_unpack(node, "{s:s}", "cert", &cert) == -1 || json_unpack(node, "{s:s}", "pkey", &pkey) == -1 || json_unpack(node, "{s:s}", "tcert", &tcert) == -1 || json_unpack(node, "{s:s}", "ipaddr", &ipaddr) == -1) { jlog(L_ERROR, "NULL parameter"); return -1; } DNDSMessage_t *new_msg; DNDSMessage_new(&new_msg); DNDSMessage_set_channel(new_msg, 0); DNDSMessage_set_pdu(new_msg, pdu_PR_dnm); DNMessage_set_operation(new_msg, dnop_PR_provResponse); ProvResponse_set_certificate(new_msg, cert, strlen(cert)); ProvResponse_set_certificateKey(new_msg, (uint8_t*)pkey, strlen(pkey)); ProvResponse_set_trustedCert(new_msg, (uint8_t*)tcert, strlen(tcert)); ProvResponse_set_ipAddress(new_msg, ipaddr); session = session_tracking_table[atoi(tid) % MAX_SESSION]; session_tracking_table[atoi(tid) % MAX_SESSION] = NULL; if (session) net_send_msg(session->netc, new_msg); DNDSMessage_del(new_msg); /* XXX * If the provisioning is not a success, * we must disconnect the client. */ return 0; }
int process_tch(struct session_info *s, struct l1ctl_burst_ind *bi, uint8_t *msg) { int ret, ul; uint16_t arfcn; uint32_t fn; uint8_t conv_data[CONV_SIZE]; struct burst_buf *bb; arfcn = ntohs(bi->band_arfcn); ul = !!(arfcn & ARFCN_UPLINK); fn = ntohl(bi->frame_nr); bb = &s->facch[ul]; /* append data to message buffer */ expand_msb(bi->bits, bb->data + bb->count * 114, 114); if(not_zero(s->key, 8)) { int i; uint8_t ks[114]; if (ul) osmo_a5(1, s->key, fn, 0, ks); else osmo_a5(1, s->key, fn, ks, 0); for (i=0; i<114; i++) { bb->data[bb->count * 114 + i] ^= ks[i]; } } // not used bb->sbit[bb->count * 2 + 0] = !!(bi->bits[14] & 0x10); bb->sbit[bb->count * 2 + 1] = !!(bi->bits[14] & 0x20); bb->snr[bb->count] = bi->snr; bb->rxl[bb->count] = bi->rx_level; /* check burst flags */ switch (bi->bits[14] & 0x30) { case 0x00: /* TCH + TCH */ //printf("TCH\n"); /* voice blocks or flags corrupted */ if (bb->count) { /* already had errors? */ if (bb->errors < 2) { /* give a try and record error */ bb->count++; bb->errors++; } else { /* discard all bursts in buffer */ bb->count = 0; bb->errors = 0; return 0; } } else { /* process voice */ return 0; } break; case 0x20: /* FACCH + TCH */ //printf("FACCH+TCH\n"); if (bb->count == 0) { /* start burst buffering */ bb->count = 1; } else { /* check how many bursts in buffer */ if (bb->count < 4) { /* all ok, append */ bb->count++; } else { /* severely errored burst, other errors? */ if (bb->errors < 2) { /* give a try and record error */ bb->count++; bb->errors++; } else { /* discard all bursts in buffer */ bb->count = 0; bb->errors = 0; return 0; } } } break; case 0x10: /* TCH + FACCH */ //printf("TCH+FACCH\n"); if (bb->count > 3) { /* all ok, append */ bb->count++; } else { /* severely errored burst, other errors? */ if (bb->errors < 2) { /* give a try and record error */ bb->count++; bb->errors++; } else { /* discard all bursts in buffer */ bb->count = 0; bb->errors = 0; return 0; } } break; case 0x30: /* FACCH + FACCH (or GPRS) */ //printf("FACCH\n"); if (bb->count > 3) { /* probably overlapping FACCHs */ bb->count++; //record a & b facch separately } else { /* overlapping and misaligned? */ bb->count++; bb->errors++; } } /* Return if not enough bursts for a full gsm message */ if (bb->count == 8) { struct radio_message *m; /* try to decode FACCH */ /* de-interleaving */ gsm_deinter_facch(bb->data, conv_data); ret = decode_signalling(conv_data, msg); if (!ret) { /* skip one burst and wait next */ // some circular buffer needed memcpy(bb->data, bb->data + 114, 7 * 114); memcpy(bb->sbit, bb->sbit + 2, 7 * 2); bb->count = 7; bb->errors /= 2; // approximated value return 0; } m = malloc(sizeof(struct radio_message)); memcpy(&m->bb, bb, sizeof(*bb)); m->chan_nr = bi->chan_nr; m->flags = MSG_FACCH|MSG_DECODED; if (s->have_key) m->flags |= MSG_CIPHERED; memcpy(m->msg, msg, 23); m->msg_len = 23; handle_lapdm(s, &s->chan_facch[ul], m->msg, m->msg_len, m->bb.fn[0], ul); net_send_msg(m); /* check overlapping status */ if ((bi->bits[14] & 0x30) == 0x30) { /* start subsequent message processing */ memcpy(bb->data, bb->data + 4 * 114, 4 * 114); memcpy(bb->sbit, bb->sbit + 4 * 2, 4 * 2); bb->count = 4; bb->errors /= 2; // approximated value memset(bb->data + bb->count*114, 0, sizeof(bb->data)/2); } else { /* nothing else in the buffer, reset */ bb->count = 0; bb->errors = 0; memset(bb->data, 0, sizeof(bb->data)); } return 23; } return 0; }