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; }
void http_engine(unsigned int idx, char *rx, unsigned int rx_len, unsigned char *tx) { unsigned int tx_len = 0; static unsigned int updFlag=0; switch (http_table[idx].status) { case HTTP_CLOSED: if (rx_len) { if(strncmpi(rx, "GET", 3) == 0)/*METHOD/part-to-resource-HTTP/Version-number*/ { updFlag=0; log_info("GET Table form data.\n"); rx += 3+1; rx_len -= 3+1; if (strncmpi(rx, "/login.html", strlen("/login.html")) == 0) { log_info("Login system.\n"); http_sendfile(idx, "/login.html", tx); } else if (strncmpi(rx, "/status.html", strlen("/status.html")) == 0) { log_info("Get system status html.\n"); http_sendfile(idx, "/status.html", tx); } else if (strncmpi(rx, "/wifibase.html", strlen("/wifibase.html")) == 0) { log_info("Get wifibase html.\n"); http_sendfile(idx, "/wifibase.html", tx); } else if (strncmpi(rx, "/wifinet.html", strlen("/wifinet.html")) == 0) { log_info("Get wifi network html.\n"); http_sendfile(idx, "/wifinet.html", tx); } else if (strncmpi(rx, "/public.css", strlen("/public.css")) == 0) { log_info("Get public css.\n"); http_sendfile(idx, "/public.css", tx); } else { log_info("Default login webserver.\n\n"); http_sendfile(idx, "/login.html", tx); } } else if(strncmpi(rx, "POST", 4) == 0) { log_info("POST Table form data.\n"); updFlag=0; rx += 4+1; rx_len -= 4+1; if (strncmpi(rx, "/reboot", 7) == 0) /* process setupwifi form */ { tx_len = sprintf((char*)tx, HTTP_200_HEADER); http_resetsys(idx, (char*)tx, tx_len); } else if (strncmpi(rx, "/factory", 8) == 0) /* process resetwifi form */ { tx_len = sprintf((char*)tx, HTTP_200_HEADER); http_factory(idx, (char*)tx, tx_len); } else if (strncmpi(rx, "/update", 7) == 0) /* process resetwifi form */ { updFlag=1; } else if (strncmpi(rx, "/wifibase", 9) == 0) /* process resetwifi form */ { http_setup_wifibase(idx, (char*)rx, rx_len, (char *)tx); } else if (strncmpi(rx, "/setupuart", 10) == 0) /* process resetwifi form */ { http_setup_uart(idx, (char*)rx, rx_len, (char *)tx); } else if (strncmpi(rx, "/setupnet", 9) == 0) /* process resetwifi form */ { http_setup_net(idx, (char*)rx, rx_len, (char *)tx); } else { http_sendfile(idx, rx, tx); } } else if(updFlag != 0) { if(http_update(idx, (char*)rx, rx_len, (char *)tx, updFlag) == 0) { updFlag=0; printf("rebooting....\r\n"); BSP_ChipReset(); } else updFlag++; } else { tx_len = sprintf((char*)tx, HTTP_400_HEADER"Error 400 Bad request\r\n\r\n"); tcp_send(idx, tx_len); } } break; case HTTP_SEND: http_sendfile(idx, 0, tx); break; default: break; } return; }