void MemoryCell::set_int(const uint64_t &pattern) { unsigned long long int lopcode = pattern & 0xffull; set_opcode(true, lopcode); unsigned long long int laddress = (pattern & (0xfffull << 8)) >> 8; set_address(true, laddress); //leftInstruction.print(); unsigned long long int ropcode = (pattern & (0xffull << 20)) >> 20; set_opcode(false, ropcode); unsigned long long int raddress = (pattern & (0xfffull << 28)) >> 28; set_address(false, raddress); //rightInstruction.print(); //bool sign = pattern < 0; //rightInstruction.get_address().set(11, sign); //rightInstruction.print(); }
errval_t tftp_send_ack(struct udp_pcb *pcb, uint32_t blockno, struct ip_addr *addr, u16_t port, struct pbuf *p, void *payload) { TFTP_DEBUG_PACKETS("sending ack(%u)\n", blockno); p->len = TFTP_MAX_MSGSIZE; p->tot_len = TFTP_MAX_MSGSIZE; p->payload = payload; memset(p->payload, 0, sizeof(uint32_t) + sizeof(uint16_t)); size_t length = set_opcode(p->payload, TFTP_OP_ACK); length += set_block_no(p->payload + length, blockno); p->len = (uint16_t)length +1; p->tot_len = (uint16_t)length+1; int r = udp_sendto(pcb, p, addr, port); if (r != ERR_OK) { TFTP_DEBUG("send failed\n"); } return SYS_ERR_OK; }
struct octet_buffer get_random (int fd, bool update_seed) { uint8_t *random = NULL; uint8_t param2[2] = {0}; uint8_t param1 = update_seed ? 0 : 1; struct octet_buffer buf = {}; random = malloc_wipe (RANDOM_RSP_LENGTH); struct Command_ATSHA204 c = make_command (); set_opcode (&c, COMMAND_RANDOM); set_param1 (&c, param1); set_param2 (&c, param2); set_data (&c, NULL, 0); set_execution_time (&c, 0, RANDOM_AVG_EXEC); if (RSP_SUCCESS == process_command (fd, &c, random, RANDOM_RSP_LENGTH)) { buf.ptr = random; buf.len = RANDOM_RSP_LENGTH; } else CTX_LOG (DEBUG, "Random command failed"); return buf; }
bool write4 (int fd, enum DATA_ZONE zone, uint8_t addr, uint32_t buf) { bool status = false; uint8_t recv = 0; uint8_t param2[2] = {0}; uint8_t param1 = set_zone_bits (zone); param2[0] = addr; struct Command_ATSHA204 c = make_command (); set_opcode (&c, COMMAND_WRITE); set_param1 (&c, param1); set_param2 (&c, param2); set_data (&c, (uint8_t *)&buf, sizeof (buf)); set_execution_time (&c, 0, 4000000); if (RSP_SUCCESS == process_command (fd, &c, &recv, sizeof (recv))); { if (0 == (int) recv) status = true; } return status; }
struct octet_buffer read32 (int fd, enum DATA_ZONE zone, uint8_t addr) { uint8_t param2[2] = {0}; uint8_t param1 = set_zone_bits (zone); uint8_t READ_32_MASK = 0b10000000; param1 |= READ_32_MASK; param2[0] = addr; struct Command_ATSHA204 c = make_command (); set_opcode (&c, COMMAND_READ); set_param1 (&c, param1); set_param2 (&c, param2); set_data (&c, NULL, 0); set_execution_time (&c, 0, READ_AVG_EXEC); const unsigned int LENGTH_OF_RESPONSE = 32; struct octet_buffer buf = make_buffer (LENGTH_OF_RESPONSE); if (RSP_SUCCESS != process_command (fd, &c, buf.ptr, LENGTH_OF_RESPONSE)) { free_wipe (buf.ptr, LENGTH_OF_RESPONSE); buf.ptr = NULL; buf.len = 0; } return buf; }
bool read4 (int fd, enum DATA_ZONE zone, uint8_t addr, uint32_t *buf) { bool result = false; uint8_t param2[2] = {0}; uint8_t param1 = set_zone_bits (zone); assert (NULL != buf); param2[0] = addr; struct Command_ATSHA204 c = make_command (); set_opcode (&c, COMMAND_READ); set_param1 (&c, param1); set_param2 (&c, param2); set_data (&c, NULL, 0); set_execution_time (&c, 0, 1000000); if (RSP_SUCCESS == process_command (fd, &c, (uint8_t *)buf, sizeof (uint32_t))) { result = true; } return result; }
bool check_mac (int fd, struct check_mac_encoding cm, unsigned int data_slot, struct octet_buffer challenge, struct octet_buffer challenge_response, struct octet_buffer other_data) { uint8_t response = 0; bool result = false; uint8_t param1 = serialize_check_mac_mode (cm); uint8_t param2[2] = {0}; const unsigned int CHALLENGE_SIZE = 32; const unsigned int OTHER_DATA_SIZE = 13; assert (NULL != challenge.ptr); assert (NULL != challenge_response.ptr); assert (NULL != other_data.ptr); assert (CHALLENGE_SIZE == challenge.len); assert (CHALLENGE_SIZE == challenge_response.len); assert (OTHER_DATA_SIZE == other_data.len); assert (data_slot <= MAX_NUM_DATA_SLOTS); const unsigned int DATA_LEN = CHALLENGE_SIZE * 2 + OTHER_DATA_SIZE; struct octet_buffer data; data = make_buffer(DATA_LEN); memcpy (data.ptr, challenge.ptr, CHALLENGE_SIZE); memcpy (data.ptr + CHALLENGE_SIZE, challenge_response.ptr, CHALLENGE_SIZE); memcpy (data.ptr + CHALLENGE_SIZE * 2, other_data.ptr, OTHER_DATA_SIZE); /* Param 2 is guaranteed to be less than 15 (check above) */ param2[0] = data_slot; param2[1] = 0; struct Command_ATSHA204 c = make_command (); set_opcode (&c, COMMAND_CHECK_MAC); set_param1 (&c, param1); set_param2 (&c, param2); set_data (&c, data.ptr, data.len); set_execution_time (&c, 0, CHECK_MAC_AVG_EXEC); if (RSP_SUCCESS == process_command (fd, &c, &response, sizeof(response))) { if (0 == response) result = true; } return result; }
bool lock (int fd, enum DATA_ZONE zone, uint16_t crc) { uint8_t param1 = 0; uint8_t param2[2]; uint8_t response; bool result = false; if (is_locked (fd, zone)) return true; memcpy (param2, &crc, sizeof (param2)); const uint8_t CONFIG_MASK = 0; const uint8_t DATA_MASK = 1; switch (zone) { case CONFIG_ZONE: param1 |= CONFIG_MASK; break; case DATA_ZONE: case OTP_ZONE: param1 |= DATA_MASK; break; default: assert (false); } struct Command_ATSHA204 c = make_command (); set_opcode (&c, COMMAND_LOCK); set_param1 (&c, param1); set_param2 (&c, param2); set_data (&c, NULL, 0); set_execution_time (&c, 0, LOCK_AVG_EXEC); if (RSP_SUCCESS == process_command (fd, &c, &response, sizeof (response))) { if (0 == response) { result = true; CTX_LOG (DEBUG, "Lock Successful"); } else { CTX_LOG (DEBUG, "Lock Failed"); } } return result; }
void Arp::arp_resolve(IP4::addr next_hop) { PRINT("<ARP RESOLVE> %s\n", next_hop.str().c_str()); auto req = static_unique_ptr_cast<PacketArp>(inet_.create_packet()); req->init(mac_, inet_.ip_addr(), next_hop); req->set_dest_mac(MAC::BROADCAST); req->set_opcode(H_request); // Stat increment requests sent requests_tx_++; linklayer_out_(std::move(req), MAC::BROADCAST, Ethertype::ARP); }
struct mac_response perform_mac (int fd, struct mac_mode_encoding m, unsigned int data_slot, struct octet_buffer challenge) { const unsigned int recv_len = 32; struct mac_response rsp = {0}; rsp.status = false; uint8_t param1 = serialize_mac_mode (m); uint8_t param2[2] = {0}; assert (data_slot <= MAX_NUM_DATA_SLOTS); if (!m.use_second_32_temp_key) assert (NULL != challenge.ptr && recv_len == challenge.len); /* Param 2 is guaranteed to be less than 15 (check above) */ param2[0] = data_slot; param2[1] = 0; rsp.mac = make_buffer (recv_len); struct Command_ATSHA204 c = make_command (); set_opcode (&c, COMMAND_MAC); set_param1 (&c, param1); set_param2 (&c, param2); /* TODO Fix for situations not sending the challlenge */ set_data (&c, challenge.ptr, challenge.len); set_execution_time (&c, 0, MAC_AVG_EXEC); if (RSP_SUCCESS == process_command (fd, &c, rsp.mac.ptr, recv_len)) { /* Perform a check mac to ensure we have the data correct */ rsp.meta = get_check_mac_meta_data (fd, m, data_slot); struct check_mac_encoding cm = {0}; rsp.status = check_mac (fd, cm, data_slot, challenge, rsp.mac, rsp.meta); } else { free_octet_buffer (rsp.mac); } return rsp; }
struct octet_buffer gen_nonce (int fd, int seed_update_flag, struct octet_buffer input) { uint8_t *recv = NULL; uint8_t param1 = seed_update_flag; uint8_t param2[2] = {0}; unsigned int recv_len = 0; struct octet_buffer response = {NULL, 0}; assert (1 == seed_update_flag || 0 == seed_update_flag); assert (NULL != input.ptr); /* If 32, the nonce is considered a pass through and will be used directly by the system */ /* If 20, the nonce will be combined with a random number */ assert (32 == input.len || 20 == input.len); if (32 == input.len) { recv_len = 1; } else { recv_len = 32; } recv = malloc (recv_len); assert (NULL != recv); struct Command_ATSHA204 c = make_command (); set_opcode (&c, COMMAND_NONCE); set_param1 (&c, param1); set_param2 (&c, param2); set_data (&c, input.ptr, input.len); set_execution_time (&c, 0, 22000000); /* avg. 22 msec */ if (RSP_SUCCESS == process_command (fd, &c, recv, recv_len)); { response.ptr = recv; response.len= recv_len; } return response; }
void patch_iput(IRList::iterator it) { auto insn = it->insn; const auto op = insn->opcode(); always_assert(is_iput(op)); switch (op) { case OPCODE_IPUT_BYTE: case OPCODE_IPUT_CHAR: case OPCODE_IPUT_SHORT: insn->set_opcode(OPCODE_IPUT); break; default: break; } };
static void cx23882_risc_ram_setup(cx23882_device *device) { char *start = (char *)(device->regs) + SRAM_START_ADDRESS + SRAM_BASE_RISC_PROG; volatile uint32 *rp = (volatile uint32 *)start; int i; #define set_opcode(a) (*rp++) = B_HOST_TO_LENDIAN_INT32((a)) dprintf("cx23882_risc_ram_setup enter\n"); // sync set_opcode(RISC_RESYNC | 0); // copy buffer 1 for (i = 0; i < LINES_PER_BUFFER; i++) { set_opcode(RISC_WRITE | RISC_SOL | RISC_EOL | BYTES_PER_LINE); set_opcode((unsigned long)device->dma_buf1_phys + i * BYTES_PER_LINE); } // execute IRQ 1 set_opcode(RISC_SKIP | RISC_IRQ1 | RISC_SOL | 0); // copy buffer 2 for (i = 0; i < LINES_PER_BUFFER; i++) { set_opcode(RISC_WRITE | RISC_SOL | RISC_EOL | BYTES_PER_LINE); set_opcode((unsigned long)device->dma_buf2_phys + i * BYTES_PER_LINE); } // execute IRQ 2 set_opcode(RISC_SKIP | RISC_IRQ2 | RISC_SOL | 0); // jmp to start, but skip sync instruction set_opcode(RISC_JUMP | RISC_SRP); set_opcode(SRAM_START_ADDRESS + SRAM_BASE_RISC_PROG + 4); #undef set_opcode dprintf("cx23882_risc_ram_setup leave\n"); }
void Arp::arp_resolve(Packet_ptr pckt) { debug("<ARP RESOLVE> %s\n", pckt->next_hop().str().c_str()); const auto next_hop = pckt->next_hop(); await_resolution(std::move(pckt), next_hop); auto req = static_unique_ptr_cast<PacketArp>(inet_.create_packet(sizeof(header))); req->init(mac_, inet_.ip_addr()); req->set_dest_mac(Ethernet::BROADCAST_FRAME); req->set_dest_ip(next_hop); req->set_opcode(H_request); // Stat increment requests sent requests_tx_++; linklayer_out_(std::move(req)); }
void Arp::arp_respond(header* hdr_in) { debug2("\t IP Match. Constructing ARP Reply\n"); // Stat increment replies sent replies_tx_++; // Populate ARP-header auto res = static_unique_ptr_cast<PacketArp>(inet_.create_packet(sizeof(header))); res->init(mac_, inet_.ip_addr()); res->set_dest_mac(hdr_in->shwaddr); res->set_dest_ip(hdr_in->sipaddr); res->set_opcode(H_reply); debug2("\t My IP: %s belongs to My Mac: %s\n", res->source_ip().str().c_str(), res->source_mac().str().c_str()); linklayer_out_(std::move(res)); }
/* Send the appropriate WPS message based on the current WPS state (globule->wps->state) */ int send_msg(int type) { int ret_val = 0; const struct wpabuf *msg = NULL; unsigned char *payload = NULL; const void *packet = NULL; size_t packet_len = 0; uint16_t payload_len = 0; enum wsc_op_code opcode = 0; struct wps_data *wps = get_wps(); /* * Get the next message we need to send based on the data retrieved * from wps_registrar_process_msg (see exchange.c). */ msg = wps_registrar_get_msg(wps, &opcode, type); set_opcode(opcode); if(msg) { /* Get a pointer to the actual data inside of the wpabuf */ payload = (unsigned char *) wpabuf_head(msg); payload_len = (uint16_t) msg->used; /* Build and send an EAP packet with the message payload */ packet = build_eap_packet(payload, payload_len, &packet_len); if(packet) { if(send_packet(packet, packet_len, 1)) { ret_val = 1; } else { free((void *) packet); } } wpabuf_free((struct wpabuf *) msg); } return ret_val; }
void Arp::arp_respond(header* hdr_in, IP4::addr ack_ip) { PRINT("\t IP Match. Constructing ARP Reply\n"); // Stat increment replies sent replies_tx_++; // Populate ARP-header auto res = static_unique_ptr_cast<PacketArp>(inet_.create_packet()); res->init(mac_, ack_ip, hdr_in->sipaddr); res->set_dest_mac(hdr_in->shwaddr); res->set_opcode(H_reply); PRINT("\t IP: %s is at My Mac: %s\n", res->source_ip().str().c_str(), res->source_mac().str().c_str()); MAC::Addr dest = hdr_in->shwaddr; PRINT("<ARP -> physical> Sending response to %s. Linklayer begin: buf + %i \n", dest.str().c_str(), res->layer_begin() - res->buf() ); linklayer_out_(std::move(res), dest, Ethertype::ARP); }
bool write32 (int fd, enum DATA_ZONE zone, uint8_t addr, struct octet_buffer buf) { assert (NULL != buf.ptr); assert (32 == buf.len); bool status = false; uint8_t recv = 0; uint8_t param2[2] = {0}; uint8_t param1 = set_zone_bits (zone); /* If writing 32 bytes, this bit must be set in param1 */ uint8_t WRITE_32_MASK = 0b10000000; param1 |= WRITE_32_MASK; param2[0] = addr; struct Command_ATSHA204 c = make_command (); set_opcode (&c, COMMAND_WRITE); set_param1 (&c, param1); set_param2 (&c, param2); set_data (&c, buf.ptr, buf.len); set_execution_time (&c, 0, WRITE_AVG_EXEC); if (RSP_SUCCESS == process_command (fd, &c, &recv, sizeof (recv))); { if (0 == (int) recv) status = true; } return status; }
void obex_dump(int level, struct frame *frm) { uint8_t last_opcode, opcode, status; uint8_t version, flags, constants; uint16_t length, pktlen; frm = add_frame(frm); while (frm->len > 2) { opcode = get_u8(frm); length = get_u16(frm); status = opcode & 0x7f; if ((int) frm->len < length - 3) { frm->ptr -= 3; frm->len += 3; return; } p_indent(level, frm); last_opcode = get_opcode(frm->handle, frm->dlci); if (!(opcode & 0x70)) { printf("OBEX: %s cmd(%c): len %d", opcode2str(opcode), opcode & 0x80 ? 'f' : 'c', length); set_opcode(frm->handle, frm->dlci, opcode); } else { printf("OBEX: %s rsp(%c): status %x%02d len %d", opcode2str(last_opcode), opcode & 0x80 ? 'f' : 'c', status >> 4, status & 0xf, length); opcode = last_opcode; } if (get_status(frm->handle, frm->dlci) == 0x10) printf(" (continue)"); set_status(frm->handle, frm->dlci, status); if (frm->len == 0) { printf("\n"); break; } switch (opcode & 0x7f) { case 0x00: /* Connect */ if (frm->len < 4) { printf("\n"); return; } version = get_u8(frm); flags = get_u8(frm); pktlen = get_u16(frm); printf(" version %d.%d flags %d mtu %d\n", version >> 4, version & 0xf, flags, pktlen); break; case 0x05: /* SetPath */ if (frm->len < 2) { printf("\n"); return; } flags = get_u8(frm); constants = get_u8(frm); printf(" flags %d constants %d\n", flags, constants); break; default: printf("\n"); break; } if ((status & 0x70) && (parser.flags & DUMP_VERBOSE)) { p_indent(level, frm); printf("Status %x%02d = %s\n", status >> 4, status & 0xf, opcode2str(status)); } parse_headers(level, frm); }
void* handle_connection(void* client_connection_info) { int new_listening_socket = socket(AF_INET, SOCK_DGRAM, 0); int block_num = 0; FILE *fp; struct connection_info *conn_info = client_connection_info; unsigned short opcode = conn_info->opcode; strcpy(filename, conn_info->file); struct sockaddr_in client = conn_info->client; char buffer[BUFFER_LENGTH]; // temp storage of packets received int fromlen; if (opcode == OPCODE_READ) { block_num++; // In contrast to WRQ, block number begins at 1 and not 0 char *file_contents_buffer; // Buffer used to store contents of file size_t file_size; // Size of the file // don't need a mutex when reading from files fp = fopen(filename, "rb"); // open file for reading fseek(fp, 0, SEEK_END); file_size = ftell(fp); // get the size of the file rewind(fp); // set our filestream back to the top of the file instead of the bottom file_contents_buffer = malloc(file_size * (sizeof(char))); // allocate buffer size to hold contents of file fread(file_contents_buffer, sizeof(char), file_size, fp); // read the contents of the file into the buffer fclose(fp); int payload_length = MAX_PAYLOAD_LENGTH; if (file_size < MAX_PAYLOAD_LENGTH) // Always check the size of the file in case the file is small enough to transfer just one packet with reduced size { payload_length = file_size; } char packet[4+payload_length]; // 516 bytes (4 bytes for opcode and blocknum + payload) is the bzero(packet, 4+payload_length); set_opcode(packet, OPCODE_DATA); // default for data packets, but our file size might be small enough forless set_block_num(packet, block_num); memcpy(packet+4, file_contents_buffer, payload_length); // Create our first packet of data sendto(new_listening_socket, packet, sizeof(packet), 0, &client, sizeof(client)); // Send our first data packet // Keep receiving requests while keeping track of block number int new_msg_len; int offset = 1; int retransmit_attempts = 0; int sent_last_packet = 0; int dont_exit = 1; while(dont_exit) { unsigned short op_code; unsigned short block; bzero(buffer, BUFFER_LENGTH); // Set all contents of the buffer to contain 0s new_msg_len = recvfrom(new_listening_socket,buffer,BUFFER_LENGTH,0,(struct sockaddr *)&client,(socklen_t *)&fromlen); if (new_msg_len < 0) { continue; } op_code = ntohs(*(unsigned short int*)&buffer); block = buffer[2] << 8 | buffer[3]; if (op_code == OPCODE_ERROR) { fprintf(stderr,"Error received, exiting.\n"); close(new_listening_socket); dont_exit = 0; } else if (op_code == OPCODE_ACK) { // we are receiving the proper ack packet, proceed transmitting data normally if (block == block_num && !sent_last_packet) { retransmit_attempts = 0; block_num++; if (file_size-offset*payload_length < payload_length) { payload_length = file_size-offset*payload_length; } char data_packet[4+payload_length]; // Only create a data packet as large as needed to contain the remaining file data set_opcode(data_packet, OPCODE_DATA); set_block_num(data_packet, block_num); memcpy(data_packet+4, file_contents_buffer+offset*MAX_PAYLOAD_LENGTH, payload_length); sendto(new_listening_socket, data_packet, sizeof(data_packet), 0, &client, sizeof(client)); // We have sent our last packet if (sizeof(data_packet) < 516) { sent_last_packet = 1; } offset++; } // a packet was lost somewhere, retransmit last packet else if ((block != block_num) && (retransmit_attempts < 5) && !sent_last_packet) { offset--; if (file_size-offset*payload_length < payload_length) { payload_length = file_size-offset*payload_length; } char data_packet[4+payload_length]; // Only create a data packet as large as needed to contain the remaining file data set_opcode(data_packet, OPCODE_DATA); set_block_num(data_packet, block_num); memcpy(data_packet+4, file_contents_buffer+offset*MAX_PAYLOAD_LENGTH, payload_length); sendto(new_listening_socket, data_packet, sizeof(data_packet), 0, &client, sizeof(client)); offset++; retransmit_attempts++; } // We've transmitted the same packet 5 times and are timing out, or we've sent our last packet else { fprintf(stderr,"Thread %d exiting.\n", pthread_self()); close(new_listening_socket); fclose(fp); dont_exit = 0; } } } } else if (opcode == OPCODE_WRITE) { char temp_filename[80]; // arbitrarily large filename to specify filename+directory strcpy(temp_filename, "temp"); // add temp directory to empty string strcat(temp_filename, filename); // concatenate temp directory with unique filename // This is a temporary file for writing to while receiving packets, so as to // only display the final file when all data has been written pthread_mutex_lock(&temp_file_mutex); // Lock the temp file from any other thread fp = fopen(temp_filename, "wb"); char packet[MAX_PAYLOAD_LENGTH]; set_opcode(packet, OPCODE_ACK); set_block_num(packet, block_num); // We've already confirmed we just received a WRQ and that the file doesn't exist already // Send an ACK packet // sendto without binding first will bind to random port, allowing for concurrency sendto(new_listening_socket, packet, sizeof(packet), 0, &client, sizeof(client)); block_num++; // Keep receiving requests while keeping track of block number int new_msg_len; int dont_exit = 1; while(dont_exit) { unsigned short op_code; unsigned short block; bzero(buffer, BUFFER_LENGTH); // Set all contents of the buffer to contain 0s new_msg_len = recvfrom(new_listening_socket,buffer,BUFFER_LENGTH,0,(struct sockaddr *)&client,(socklen_t *)&fromlen); if (new_msg_len < 0) { continue; } op_code = ntohs(*(unsigned short int*)&buffer); block = buffer[2] << 8 | buffer[3]; // Concatenate upper and lower halves of the block into one short if (op_code == OPCODE_ERROR) { fprintf(stderr,"Error received, exiting.\n"); close(new_listening_socket); fclose(fp); pthread_mutex_unlock(&temp_file_mutex); dont_exit = 0; } else if (op_code == OPCODE_DATA) { set_opcode(packet, OPCODE_ACK); set_block_num(packet, block_num); char payload[new_msg_len-HEADER_SIZE]; // Source, size per element in bytes, # of elements, filestream memcpy(payload, buffer+HEADER_SIZE, sizeof(payload)); fwrite(payload, 1, sizeof(payload), fp); sendto(new_listening_socket, packet, sizeof(packet), 0, &client, sizeof(client)); block_num++; } // Last packet received, child process should exit if (new_msg_len < MAX_PAYLOAD_LENGTH) { close(fp); pthread_mutex_unlock(&temp_file_mutex); // Transfer contents of temp file into correct file // Do this by looping through the temp file and copying into destination file complete_write(filename, temp_filename); close(new_listening_socket); dont_exit = 0; } } } return 0; }
int main(int argc, char *argv[]){ int main_listening_socket; int listening_port; int pid; if (argc < 2) { fprintf(stderr,"Please provide a port number and try again.\n"); exit(1); } main_listening_socket = socket(AF_INET, SOCK_DGRAM, 0); if(main_listening_socket < 0){ fprintf (stderr,"Cannot create socket.\n"); exit(-1); } struct sockaddr_in server; struct sockaddr_in client; int addr_length = sizeof(server); bzero(&server,addr_length); listening_port = atoi(argv[1]); server.sin_family = AF_INET; server.sin_addr.s_addr = INADDR_ANY; server.sin_port = htons(listening_port); if(bind(main_listening_socket,(struct sockaddr *)&server,addr_length)<0){ fprintf(stderr,"Cannot listen on the port.\n"); exit(-1); } int msg_len =-1; // length of the packets received by client int fromlen; char buffer[BUFFER_LENGTH]; // temp storage of packets received unsigned short opcode; struct stat st = {0}; while(1){ // create working directory for server temp storage /*if (stat("../tftp_temp/", &st) == -1) { mkdir("../tftp_temp/", 0700); }*/ msg_len = recvfrom(main_listening_socket,buffer,BUFFER_LENGTH,0,(struct sockaddr *)&client,(socklen_t *)&fromlen); if (msg_len < 0) { continue; } opcode = ntohs(*(unsigned short int*)&buffer); //opcode is in network byte order, convert to local byte order filename = (char*)&buffer+2; if (opcode == OPCODE_READ) { struct stat st; int result = stat(filename, &st); // Check to see if the file doesn't exist if (result != 0) { fprintf(stderr, "Error: File doesn't exist.\n"); char packet[MAX_PAYLOAD_LENGTH]; set_opcode(packet, OPCODE_ERROR); set_block_num(packet, 1); // Error Code 1: File not found sendto(main_listening_socket, packet, sizeof(packet), 0, &client, sizeof(client)); continue; } } else if (opcode == OPCODE_WRITE) { // Check to see if the file already exists if (access(filename, F_OK) != -1) { fprintf(stderr, "Error: File already exists.\n"); char packet[MAX_PAYLOAD_LENGTH]; set_opcode(packet, OPCODE_ERROR); set_block_num(packet, 6); // Error Code 6: File already exists sendto(main_listening_socket, packet, sizeof(packet), 0, &client, sizeof(client)); continue; } } // No errors, we can proceed with the client connection struct connection_info new_connection; new_connection.opcode = opcode; strcpy(new_connection.file, filename); new_connection.client = client; pthread_t client_thread; pthread_create(&client_thread, NULL, handle_connection, &new_connection); } return 1; }
/* * Processes incoming packets looking for EAP and WPS messages. * Responsible for stopping the timer when a valid EAP packet is received. * Returns the type of WPS message received, if any. */ enum wps_type process_packet(const u_char *packet, struct pcap_pkthdr *header) { struct radio_tap_header *rt_header = NULL; struct dot11_frame_header *frame_header = NULL; struct llc_header *llc = NULL; struct dot1X_header *dot1x = NULL; struct eap_header *eap = NULL; struct wfa_expanded_header *wfa = NULL; const void *wps_msg = NULL; size_t wps_msg_len = 0; enum wps_type type = UNKNOWN; struct wps_data *wps = NULL; if (packet == NULL || header == NULL) { return UNKNOWN; } else if (header->len < MIN_PACKET_SIZE) { return UNKNOWN; } /* Cast the radio tap and 802.11 frame headers and parse out the Frame Control field */ rt_header = (struct radio_tap_header *) packet; frame_header = (struct dot11_frame_header *) (packet + rt_header->len); /* Does the BSSID/source address match our target BSSID? */ if (memcmp(frame_header->addr3, get_bssid(), MAC_ADDR_LEN) == 0) { /* Is this a data packet sent to our MAC address? */ if (frame_header->fc.type == DATA_FRAME && frame_header->fc.sub_type == SUBTYPE_DATA && (memcmp(frame_header->addr1, get_mac(), MAC_ADDR_LEN) == 0)) { llc = (struct llc_header *) (packet + rt_header->len + sizeof (struct dot11_frame_header) ); /* All packets in our exchanges will be 802.1x */ if (llc->type == DOT1X_AUTHENTICATION) { dot1x = (struct dot1X_header *) (packet + rt_header->len + sizeof (struct dot11_frame_header) + sizeof (struct llc_header) ); /* All packets in our exchanges will be EAP packets */ if (dot1x->type == DOT1X_EAP_PACKET && (header->len >= EAP_PACKET_SIZE)) { eap = (struct eap_header *) (packet + rt_header->len + sizeof (struct dot11_frame_header) + sizeof (struct llc_header) + sizeof (struct dot1X_header) ); /* EAP session termination. Break and move on. */ if (eap->code == EAP_FAILURE) { cprintf(VERBOSE, "[!] EAP_FAILURE: TERMINATE\n"); type = TERMINATE; } /* If we've received an EAP request and then this should be a WPS message */ else if (eap->code == EAP_REQUEST) { /* The EAP header builder needs this ID value */ set_eap_id(eap->id); /* Stop the receive timer that was started by the last send_packet() */ stop_timer(); /* Check to see if we received an EAP identity request */ if (eap->type == EAP_IDENTITY) { /* We've initiated an EAP session, so reset the counter */ set_eapol_start_count(0); type = IDENTITY_REQUEST; } /* An expanded EAP type indicates a probable WPS message */ else if ((eap->type == EAP_EXPANDED) && (header->len > WFA_PACKET_SIZE)) { wfa = (struct wfa_expanded_header *) (packet + rt_header->len + sizeof (struct dot11_frame_header) + sizeof (struct llc_header) + sizeof (struct dot1X_header) + sizeof (struct eap_header) ); /* Verify that this is a WPS message */ if (wfa->type == SIMPLE_CONFIG) { wps_msg_len = (size_t) ntohs(eap->len) - sizeof (struct eap_header) - sizeof (struct wfa_expanded_header); wps_msg = (const void *) (packet + rt_header->len + sizeof (struct dot11_frame_header) + sizeof (struct llc_header) + sizeof (struct dot1X_header) + sizeof (struct eap_header) + sizeof (struct wfa_expanded_header) ); /* Save the current WPS state. This way if we get a NACK message, we can * determine what state we were in when the NACK arrived. */ wps = get_wps(); set_last_wps_state(wps->state); set_opcode(wfa->opcode); /* Process the WPS message and send a response */ type = process_wps_message(wps_msg, wps_msg_len); } } } } } } } return type; }
bool IRCode::try_sync(DexCode* code) { std::unordered_map<MethodItemEntry*, uint32_t> entry_to_addr; uint32_t addr = 0; // Step 1, regenerate opcode list for the method, and // and calculate the opcode entries address offsets. TRACE(MTRANS, 5, "Emitting opcodes\n"); for (auto miter = m_ir_list->begin(); miter != m_ir_list->end(); ++miter) { MethodItemEntry* mentry = &*miter; TRACE(MTRANS, 5, "Analyzing mentry %p\n", mentry); entry_to_addr[mentry] = addr; if (mentry->type == MFLOW_DEX_OPCODE) { TRACE(MTRANS, 5, "Emitting mentry %p at %08x\n", mentry, addr); addr += mentry->dex_insn->size(); } } // Step 2, Branch relaxation: calculate branch offsets for if-* and goto // opcodes, resizing them where necessary. Since resizing opcodes affects // address offsets, we need to iterate this to a fixed point. // // For instructions that use address offsets but never need resizing (i.e. // switch and fill-array-data opcodes), we calculate their offsets after // we have reached the fixed point. TRACE(MTRANS, 5, "Recalculating branches\n"); std::vector<MethodItemEntry*> multi_branches; std::unordered_map<MethodItemEntry*, std::vector<BranchTarget*>> multis; std::unordered_map<BranchTarget*, uint32_t> multi_targets; bool needs_resync = false; for (auto miter = m_ir_list->begin(); miter != m_ir_list->end(); ++miter) { MethodItemEntry* mentry = &*miter; if (entry_to_addr.find(mentry) == entry_to_addr.end()) { continue; } if (mentry->type == MFLOW_DEX_OPCODE) { auto opcode = mentry->dex_insn->opcode(); if (dex_opcode::is_switch(opcode)) { multi_branches.push_back(mentry); } } if (mentry->type == MFLOW_TARGET) { BranchTarget* bt = mentry->target; if (bt->type == BRANCH_MULTI) { multis[bt->src].push_back(bt); multi_targets[bt] = entry_to_addr.at(mentry); // We can't fix the primary switch opcodes address until we emit // the fopcode, which comes later. } else if (bt->type == BRANCH_SIMPLE && dex_opcode::is_branch(bt->src->dex_insn->opcode())) { MethodItemEntry* branch_op_mie = bt->src; auto branch_addr = entry_to_addr.find(branch_op_mie); always_assert_log(branch_addr != entry_to_addr.end(), "%s refers to nonexistent branch instruction", SHOW(*mentry)); int32_t branch_offset = entry_to_addr.at(mentry) - branch_addr->second; needs_resync |= !encode_offset(m_ir_list, mentry, branch_offset); } } } if (needs_resync) { return false; } size_t num_align_nops{0}; auto& opout = code->reset_instructions(); for (auto& mie : *m_ir_list) { // We are assuming that fill-array-data-payload opcodes are always at // the end of the opcode stream (we enforce that during instruction // lowering). I.e. they are only followed by other fill-array-data-payload // opcodes. So adjusting their addresses here does not require re-running // branch relaxation. entry_to_addr.at(&mie) += num_align_nops; if (mie.type == MFLOW_TARGET && mie.target->src->dex_insn->opcode() == DOPCODE_FILL_ARRAY_DATA) { // This MFLOW_TARGET is right before a fill-array-data-payload opcode, // so we should make sure its address is aligned if (entry_to_addr.at(&mie) & 1) { opout.push_back(new DexInstruction(DOPCODE_NOP)); ++entry_to_addr.at(&mie); ++num_align_nops; } mie.target->src->dex_insn->set_offset(entry_to_addr.at(&mie) - entry_to_addr.at(mie.target->src)); continue; } if (mie.type != MFLOW_DEX_OPCODE) { continue; } TRACE(MTRANS, 6, "Emitting insn %s\n", SHOW(mie.dex_insn)); opout.push_back(mie.dex_insn); } addr += num_align_nops; TRACE(MTRANS, 5, "Emitting multi-branches\n"); // Step 3, generate multi-branch fopcodes for (auto multiopcode : multi_branches) { auto& targets = multis[multiopcode]; auto multi_insn = multiopcode->dex_insn; std::sort(targets.begin(), targets.end(), multi_target_compare_case_key); always_assert_log( !targets.empty(), "need to have targets for %s", SHOW(*multiopcode)); if (sufficiently_sparse(targets)) { // Emit sparse. const size_t count = (targets.size() * 4) + 2; auto sparse_payload = std::make_unique<uint16_t[]>(count); sparse_payload[0] = FOPCODE_SPARSE_SWITCH; sparse_payload[1] = targets.size(); uint32_t* spkeys = (uint32_t*)&sparse_payload[2]; uint32_t* sptargets = (uint32_t*)&sparse_payload[2 + (targets.size() * 2)]; for (BranchTarget* target : targets) { *spkeys++ = target->case_key; *sptargets++ = multi_targets[target] - entry_to_addr.at(multiopcode); } // Emit align nop if (addr & 1) { DexInstruction* nop = new DexInstruction(DOPCODE_NOP); opout.push_back(nop); addr++; } // Insert the new fopcode... DexInstruction* fop = new DexOpcodeData(sparse_payload.get(), (int)(count - 1)); opout.push_back(fop); // re-write the source opcode with the address of the // fopcode, increment the address of the fopcode. multi_insn->set_offset(addr - entry_to_addr.at(multiopcode)); multi_insn->set_opcode(DOPCODE_SPARSE_SWITCH); addr += count; } else { // Emit packed. const uint64_t size = get_packed_switch_size(targets); always_assert(size <= std::numeric_limits<uint16_t>::max()); const size_t count = (size * 2) + 4; auto packed_payload = std::make_unique<uint16_t[]>(count); packed_payload[0] = FOPCODE_PACKED_SWITCH; packed_payload[1] = size; uint32_t* psdata = (uint32_t*)&packed_payload[2]; int32_t next_key = *psdata++ = targets.front()->case_key; for (BranchTarget* target : targets) { // Fill in holes with relative offsets that are falling through to the // instruction after the switch instruction for (; next_key != target->case_key; ++next_key) { *psdata++ = 3; // packed-switch statement is three code units } *psdata++ = multi_targets[target] - entry_to_addr.at(multiopcode); ++next_key; } // Emit align nop if (addr & 1) { DexInstruction* nop = new DexInstruction(DOPCODE_NOP); opout.push_back(nop); addr++; } // Insert the new fopcode... DexInstruction* fop = new DexOpcodeData(packed_payload.get(), (int)(count - 1)); opout.push_back(fop); // re-write the source opcode with the address of the // fopcode, increment the address of the fopcode. multi_insn->set_offset(addr - entry_to_addr.at(multiopcode)); multi_insn->set_opcode(DOPCODE_PACKED_SWITCH); addr += count; } } // Step 4, emit debug entries TRACE(MTRANS, 5, "Emitting debug entries\n"); auto debugitem = code->get_debug_item(); if (debugitem) { gather_debug_entries(m_ir_list, entry_to_addr, &debugitem->get_entries()); } // Step 5, try/catch blocks TRACE(MTRANS, 5, "Emitting try items & catch handlers\n"); auto& tries = code->get_tries(); tries.clear(); MethodItemEntry* active_try = nullptr; for (auto& mentry : *m_ir_list) { if (mentry.type != MFLOW_TRY) { continue; } auto& tentry = mentry.tentry; if (tentry->type == TRY_START) { always_assert(active_try == nullptr); active_try = &mentry; continue; } redex_assert(tentry->type == TRY_END); auto try_end = &mentry; auto try_start = active_try; active_try = nullptr; always_assert_log( try_start != nullptr, "unopened try_end found: %s", SHOW(*try_end)); always_assert_log(try_start->tentry->catch_start == try_end->tentry->catch_start, "mismatched try start (%s) and end (%s)", SHOW(*try_start), SHOW(*try_end)); auto start_addr = entry_to_addr.at(try_start); auto end_addr = entry_to_addr.at(try_end); if (start_addr == end_addr) { continue; } DexCatches catches; for (auto mei = try_end->tentry->catch_start; mei != nullptr; mei = mei->centry->next) { if (mei->centry->next != nullptr) { always_assert(mei->centry->catch_type != nullptr); } catches.emplace_back(mei->centry->catch_type, entry_to_addr.at(mei)); } split_and_insert_try_regions(start_addr, end_addr, catches, &tries); } always_assert_log(active_try == nullptr, "unclosed try_start found"); std::sort(tries.begin(), tries.end(), [](const std::unique_ptr<DexTryItem>& a, const std::unique_ptr<DexTryItem>& b) { return a->m_start_addr < b->m_start_addr; }); return true; }