Esempio n. 1
0
File: pkt_proc.c Progetto: houcy/joy
struct flow_record *
process_tcp(const struct pcap_pkthdr *h, const void *tcp_start, int tcp_len, struct flow_key *key) {
  unsigned int tcp_hdr_len;
  const unsigned char *payload;
  unsigned int payload_len;
  const struct tcp_hdr *tcp = (const struct tcp_hdr *)tcp_start;
  struct flow_record *record = NULL;
  unsigned int cur_itr = 0;
  
  if (output_level > none) {
    fprintf(output, "   protocol: TCP\n");
  }

  //  tcp_hdr_len = TCP_OFF(tcp)*4;
  tcp_hdr_len = tcp_hdr_length(tcp);
  if (tcp_hdr_len < 20 || tcp_hdr_len > tcp_len) {
    // fprintf(output, "   * Invalid TCP header length: %u bytes\n", tcp_hdr_len);
    return NULL;
  }
    
  /* define/compute tcp payload (segment) offset */
  payload = (unsigned char *)(tcp_start + tcp_hdr_len);
  
  /* compute tcp payload (segment) size */
  payload_len = tcp_len - tcp_hdr_len;

  if (output_level > none) {
    fprintf(output, "   src port: %d\n", ntohs(tcp->src_port));
    fprintf(output, "   dst port: %d\n", ntohs(tcp->dst_port));
    fprintf(output, "payload len: %u\n", payload_len);
    fprintf(output, "    tcp len: %u\n", tcp_len);
    fprintf(output, "tcp hdr len: %u\n", tcp_hdr_len);
    fprintf(output, "      flags:");
    if (tcp->tcp_flags & TCP_FIN) { fprintf(output, "FIN "); }
    if (tcp->tcp_flags & TCP_SYN) { fprintf(output, "SYN "); }
    if (tcp->tcp_flags & TCP_RST) { fprintf(output, "RST "); }
    if (tcp->tcp_flags & TCP_PSH) { fprintf(output, "PSH "); }
    if (tcp->tcp_flags & TCP_ACK) { fprintf(output, "ACK "); }
    if (tcp->tcp_flags & TCP_URG) { fprintf(output, "URG "); }
    if (tcp->tcp_flags & TCP_ECE) { fprintf(output, "ECE "); }
    if (tcp->tcp_flags & TCP_CWR) { fprintf(output, "CWR "); }
    fprintf(output, "\n");

    if (output_level > packet_summary) {
      if (payload_len > 0) {
	fprintf(output, "    payload:\n");
	print_payload(payload, payload_len);
      }
    }
  }

  key->sp = ntohs(tcp->src_port);
  key->dp = ntohs(tcp->dst_port);

  record = flow_key_get_record(key, CREATE_RECORDS); 
  if (record == NULL) {
    return NULL;
  }
  if (output_level > none) {
    fprintf(output, "   SEQ:      %d\trelative SEQ: %d\n", ntohl(tcp->tcp_seq), ntohl(tcp->tcp_seq) - record->seq);
    fprintf(output, "   ACK:      %d\trelative ACK: %d\n", ntohl(tcp->tcp_ack), ntohl(tcp->tcp_ack) - record->ack);
    // fprintf(output, "   SEQ:      %d\n", ntohl(tcp->tcp_seq) - record->seq);
    // fprintf(output, "   ACK:      %d\n", ntohl(tcp->tcp_ack) - record->ack);
  }

  if (payload_len > 0) {
    if (ntohl(tcp->tcp_seq) < record->seq) {
      // fprintf(info, "retransmission detected\n");
      record->retrans++;
    } 
  }
  if (include_zeroes || payload_len > 0) {
      flow_record_process_packet_length_and_time_ack(record, payload_len, &h->ts, tcp);
  }

  // if initial SYN/ACK packet, parse TCP options
  unsigned int offset = 20;
  if (tcp->tcp_flags == 2 || tcp->tcp_flags == 18) { // SYN==2, SYN/ACK==18
    // get initial window size
    if (!record->tcp_initial_window_size) {
      record->tcp_initial_window_size = ntohs(tcp->tcp_win);
    }

    // get SYN packet size
    if (tcp->tcp_flags == 2) {
      record->tcp_syn_size = tcp_len;
    }

    // parse TCP options
    cur_itr = 0;
    while (offset < tcp_hdr_len) { // while there are TCP options present
      cur_itr += 1;
      if (cur_itr > 20) {
	break;
      }
      if ((unsigned int)*(const unsigned char *)(tcp_start+offset) <= 0) { // EOL
	break ;
      }
      if ((unsigned int)*(const unsigned char *)(tcp_start+offset) == 1) { // NOP
	record->tcp_option_nop += 1;
	offset += 1;
      } else if ((unsigned int)*(const unsigned char *)(tcp_start+offset) == 2) { // MSS
	if ((unsigned int)*(const unsigned char *)(tcp_start+offset+1) == 4) {
	  record->tcp_option_mss = htons(*(const unsigned short *)(tcp_start+offset+2));
	}
	offset += (unsigned int)*(const unsigned char *)(tcp_start+offset+1);
      } else if ((unsigned int)*(const unsigned char *)(tcp_start+offset) == 3) { // WSCALE
	record->tcp_option_wscale = (unsigned int)*(const unsigned char *)(tcp_start+offset+2);

	offset += (unsigned int)*(const unsigned char *)(tcp_start+offset+1);
      } else if ((unsigned int)*(const unsigned char *)(tcp_start+offset) == 4) { // SACK
	record->tcp_option_sack = 1;

	offset += (unsigned int)*(const unsigned char *)(tcp_start+offset+1);
      } else if ((unsigned int)*(const unsigned char *)(tcp_start+offset) == 8) { // TSTAMP
	record->tcp_option_tstamp = 1;

	offset += (unsigned int)*(const unsigned char *)(tcp_start+offset+1);
      } else if ((unsigned int)*(const unsigned char *)(tcp_start+offset) == 34) { // TCP FAST OPEN
	record->tcp_option_fastopen = 1;

	offset += (unsigned int)*(const unsigned char *)(tcp_start+offset+1);
      } else { // if all TCP options are being correctly parsed, this else should not be called
	offset += (unsigned int)*(const unsigned char *)(tcp_start+offset+1);
      }
    }
  }

  record->ob += payload_len; 
  
  flow_record_update_byte_count(record, payload, payload_len);
  flow_record_update_compact_byte_count(record, payload, payload_len);
  flow_record_update_byte_dist_mean_var(record, payload, payload_len);
  wht_update(&record->wht, payload, payload_len, report_wht);
  
  /* if packet has port 443 and nonzero data length, process it as TLS */
  if (include_tls && payload_len && (key->sp == 443 || key->dp == 443)) {
    process_tls(h, payload, payload_len, &record->tls_info);
  }

  /* if packet has port 80 and nonzero data length, process it as HTTP */
  if (config.http && payload_len && (key->sp == 80 || key->dp == 80)) {
    http_update(&record->http_data, payload, payload_len, config.http);
  }

  /*
   * update header description
   */
  if (payload_len >= report_hd) {
    header_description_update(&record->hd, payload, report_hd);
  }

  return record;
}
Esempio n. 2
0
void process_elf(const char *path) {
	Elf32_Ehdr hdr;
	Elf32_Phdr phdrs[MAX_PHDRS];
	int i;
	int fd = syscall(SYS_open, path, O_RDONLY);
	syscall(SYS_read, fd, &hdr, sizeof(Elf32_Ehdr));
	
	// Move to the beginning of program segment headers
	syscall(SYS_lseek, fd, hdr.e_phoff, SEEK_SET);
	
	// Read the table of phdrs
	for (i = 0; i < hdr.e_phnum; ++i) {
		syscall(SYS_read,fd, &phdrs[i], hdr.e_phentsize);
	}
	
	for (i = 0; i < hdr.e_phnum; ++i) {
		syscall(SYS_mmap2, (void *)phdrs[i].p_vaddr, phdrs[i].p_memsz, PROT_READ | PROT_WRITE | PROT_EXEC, 
			MAP_PRIVATE | MAP_ANONYMOUS | MAP_FIXED, -1, 0);
	}
	
	// Map PT_NOTE files
	for (i = 0; i < hdr.e_phnum; ++i) {
		if (phdrs[i].p_type == PT_NOTE) {
			syscall(SYS_lseek, fd, phdrs[i].p_offset, SEEK_SET);
			size_t bytes_read = 0;
			while (bytes_read < phdrs[i].p_filesz) {
				// Read the note header
				Elf32_Nhdr nhdr;
				syscall(SYS_read, fd, &nhdr, sizeof(Elf32_Nhdr));
				            bytes_read += sizeof(Elf32_Nhdr);
				
				// Skip name (we don't use it anyway)
				int padding = (4 - (nhdr.n_namesz % 4)) % 4;
				syscall(SYS_lseek, fd, nhdr.n_namesz + padding, SEEK_CUR);
				            bytes_read += nhdr.n_namesz + padding;
				
				// Read the description.
				syscall(SYS_read, fd, desc_buf, nhdr.n_descsz);
				padding = (4 - (nhdr.n_descsz % 4)) % 4;
				            bytes_read += nhdr.n_descsz + padding;
				
				// Skip padding
				syscall(SYS_lseek, fd, padding, SEEK_CUR);
				
				switch (nhdr.n_type) {
					case NT_FILE:
						process_note_file(desc_buf);
						break;
					case NT_PRSTATUS:
						process_prstatus(desc_buf);
						break;
					case NT_386_TLS:
						process_tls(desc_buf);
						break;
					default:
						break;
				};
			}
		}
	}
	
	// Scan the table again, this time only load PT_LOAD and set the flags
	for (i = 0; i < hdr.e_phnum; ++i) {
		if (phdrs[i].p_type == PT_LOAD) {
			if (phdrs[i].p_filesz > 0) {
				syscall(SYS_mmap2, (void *)(phdrs[i].p_vaddr), phdrs[i].p_filesz, 
					PROT_READ | PROT_WRITE | PROT_EXEC, 
					MAP_PRIVATE | MAP_FIXED, fd, phdrs[i].p_offset / 4096);
			}
			
			int RWX = 0;
			if (phdrs[i].p_flags & PF_X) {
				RWX |= PROT_EXEC;
			}
			if (phdrs[i].p_flags & PF_R) {
				RWX |= PROT_READ;
			}
			if (phdrs[i].p_flags & PF_W) {
				RWX |= PROT_WRITE;
			}
			
			syscall(SYS_mprotect, (void *)(phdrs[i].p_vaddr), phdrs[i].p_memsz, RWX);
		}
	}
	
	syscall(SYS_close, fd);
	return;
}