cell socket::recv_cell() { cell result; uint8_t header[5]; _socket.read(header, _protocol_version == 3 ? 3 : 5); if (_protocol_version < 4) { result.circuit_id = (uint32_t)swap_endianness(*(uint16_t*)header); } else { result.circuit_id = (uint32_t)swap_endianness(*(uint32_t*)header); } result.command = (cell::command_type)header[_protocol_version < 4 ? 2 : 4]; size_t payload_length = 509; if (result.command == cell::command_type::versions || (uint32_t)result.command >= 128) { _socket.read((uint8_t*)&payload_length, 2); payload_length = swap_endianness((uint16_t)payload_length); } result.payload.resize(payload_length); _socket.read(result.payload.get_buffer(), payload_length); printf("<< recv_cell [circ_id: %i, cmd_id: %u]\n", result.circuit_id, result.command); return result; }
void socket::send_net_info() { byte_buffer nibuf(4 + 2 + 4 + 3 + 4); uint32_t remote = _socket.get_underlying_socket().get_ip().to_int(); uint32_t local = 0xC0A80016; uint32_t epoch = time::now().to_timestamp(); *(uint32_t*)&nibuf[0] = swap_endianness(epoch); *(uint8_t*)&nibuf[4] = 0x04; *(uint8_t*)&nibuf[5] = 0x04; *(uint32_t*)&nibuf[6] = swap_endianness(remote); *(uint8_t*)&nibuf[10] = 0x01; *(uint8_t*)&nibuf[11] = 0x04; *(uint8_t*)&nibuf[12] = 0x04; *(uint32_t*)&nibuf[13] = swap_endianness(local); send_cell(cell(0, cell::command_type::netinfo, nibuf)); }
int check_firmware(int fd) { frm_hdr_t it, bkp; char *filebuf; ssize_t red, filesize, err; if (gV > 1) puts("check_firmware"); memset((char*)&it, 0, sizeof(it)); memset((char*)&bkp, 0, sizeof(bkp)); if ((red = read(fd, &it, sizeof(it))) != sizeof(it)) die("Reading header:"); if (strncmp(FIRM_MAGIC, (char *)it.fm_magic, strlen(FIRM_MAGIC))) die("Bad magic!"); memcpy((char*)&bkp, (char*)&it, sizeof(it)); swap_endianness(&it); filesize = 392; //it.fm_hdr_len + it.mdul_hdr_len * it.num_mduls; if (!(filebuf = malloc(filesize*sizeof(unsigned char)))) die ("Malloc failed:"); memset(filebuf, 0, filesize); filesize -= sizeof(bkp); memcpy(filebuf, &bkp, sizeof(bkp)); if (sizeof(bkp)!=136) die("oops"); // if ((red = read(fd, filebuf, filesize)) != filesize) die("Reading headers:"); if ((red = read(fd, filebuf+sizeof(bkp), filesize)) != filesize) die("Reading headers:"); if (red + 136 != filesize+sizeof(bkp)) { die("oops2"); } if (gV > 1) printf("We got %d modules weighing %d bytes and a %d bytes header. Total Header size: %ld bytes\n", it.num_mduls, it.mdul_hdr_len, it.fm_hdr_len, filesize+sizeof(it)); if (it.num_mduls > 20 || it.mdul_hdr_len > 0x1000 || it.fm_hdr_len > 0x1000) return(printf("Incorrect header length\n")); if (!(err = check_fmhdr(filebuf, filesize+sizeof(it)))) { mdul_hdr_t * mdl; for (int i = 0; i < it.num_mduls && !err; ++i) { if (gV > 1) printf("\n\n--- MODULE %d ---\n",i); if (MUST_DUMP) { if (curDumpFd) xclose(&curDumpFd); if (MUST_SPLIT_HDR && curHdrDumpFd) xclose(&curHdrDumpFd); currentDumpFd(); // to reset inner variable createDumpFd(mdl); mdl = (mdul_hdr_t*) (filebuf + it.fm_hdr_len + (i * it.mdul_hdr_len)); whereami(fd); err = check_mdul_hdr(fd, mdl); } } } free(filebuf); return err; }
void socket::connect( net::ip& ip, uint16_t port) { _socket.connect(ip.to_string().get_buffer(), port); send_cell(cell(0, cell::command_type::versions, { 0, 3, 0, 4 })); cell version_reply = recv_cell(); for (size_t i = 0; i < version_reply.payload.get_size(); i += 2) { uint16_t offered_version = swap_endianness(*(uint16_t*)(version_reply.payload.get_buffer() + i)); if (offered_version <= protocol_version_max && offered_version > _protocol_version) { _protocol_version = offered_version; } } // std::thread t(this, &socket::receive_handler_loop); }