Esempio n. 1
0
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();
}
Esempio n. 2
0
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;
}
Esempio n. 3
0
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;



}
Esempio n. 4
0
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;



}
Esempio n. 5
0
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;
}
Esempio n. 6
0
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;
}
Esempio n. 7
0
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;



}
Esempio n. 8
0
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;

}
Esempio n. 9
0
  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);
  }
Esempio n. 10
0
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;



}
Esempio n. 11
0
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;



}
Esempio n. 12
0
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;
  }
};
Esempio n. 13
0
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");
}
Esempio n. 14
0
  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));
  }
Esempio n. 15
0
  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));
  }
Esempio n. 16
0
/* 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;
}
Esempio n. 17
0
  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);
  }
Esempio n. 18
0
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;



}
Esempio n. 19
0
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);
	}
Esempio n. 20
0
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;
    
}
Esempio n. 21
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;

}
Esempio n. 22
0
/* 
 * 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;
}
Esempio n. 23
0
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;
}