static int dispose_packet(char *recv_buf, int recv_len, int *p_valid_flag) { int replica_num; char *packet; bool packet_valid = false; tc_ip_header_t *ip_header; packet = recv_buf; if (is_packet_needed((const char *) packet)) { replica_num = clt_settings.replica_num; ip_header = (tc_ip_header_t *) packet; if (LOCALHOST == ip_header->saddr) { if (0 != clt_settings.lo_tf_ip) { ip_header->saddr = clt_settings.lo_tf_ip; } } if (replica_num > 1) { packet_valid = process_packet(true, packet, recv_len); replicate_packs(packet, recv_len, replica_num); }else{ packet_valid = process_packet(false, packet, recv_len); } } if (p_valid_flag) { *p_valid_flag = (packet_valid == true ? 1 : 0); } return TC_OK; }
static int dispose_packet(unsigned char *frame, int frame_len, int ip_recv_len, int *p_valid_flag) { int replica_num; bool packet_valid = false; unsigned char *packet; tc_ip_header_t *ip_header; packet = frame + ETHERNET_HDR_LEN; if (is_packet_needed(packet)) { replica_num = clt_settings.replica_num; ip_header = (tc_ip_header_t *) packet; if (clt_settings.clt_tf_ip != 0) { ip_header->saddr = clt_settings.clt_tf_ip; } if (replica_num > 1) { packet_valid = process_packet(true, frame, frame_len); replicate_packs(frame, frame_len, replica_num); } else { packet_valid = process_packet(false, frame, frame_len); } } if (p_valid_flag) { *p_valid_flag = (packet_valid == true ? 1 : 0); } return TC_OK; }
int tc_offline_parse(char *pcap_file) { int l2_len, ip_pack_len = 0; bool stop = false; char ebuf[PCAP_ERRBUF_SIZE]; pcap_t *pcap; unsigned char *pkt_data, *ip_data; struct pcap_pkthdr pkt_hdr; struct timeval last_pack_time; if (pcap_file == NULL) { return TC_ERROR; } if ((settings.pcap = pcap_open_offline(pcap_file, ebuf)) == NULL) { tc_log_info(LOG_ERR, 0, "open %s" , ebuf); fprintf(stderr, "open %s\n", ebuf); return TC_ERROR; } pcap = settings.pcap; tc_log_info(LOG_NOTICE, 0, "open pcap success:%s", pcap_file); while (!stop) { pkt_data = (u_char *) pcap_next(pcap, &pkt_hdr); if (pkt_data != NULL) { if (pkt_hdr.caplen < pkt_hdr.len) { tc_log_debug0(LOG_DEBUG, 0, "truncated packets,drop"); } ip_data = get_ip_data(pkt_data, pkt_hdr.caplen, &l2_len); last_pack_time = pkt_hdr.ts; if (ip_data != NULL) { settings.pcap_time = last_pack_time.tv_sec * 1000 + last_pack_time.tv_usec/1000; ip_pack_len = pkt_hdr.len - l2_len; if (is_packet_needed((const char *) ip_data)) { process((char *)ip_data); } else { tc_log_debug0(LOG_DEBUG, 0, "invalid flag"); } } } else { tc_log_info(LOG_WARN, 0, "stop, null from pcap_next"); stop = true; } } return TC_OK; }
static int dispose_packet(char *recv_buf, int recv_len, int *p_valid_flag) { int replica_num, i, last, packet_num, max_payload, index, payload_len; char *packet, tmp_buf[RECV_BUF_SIZE]; bool packet_valid = false; uint16_t id, size_ip, size_tcp, tot_len, cont_len, pack_len = 0, head_len; uint32_t seq; tc_ip_header_t *ip_header; tc_tcp_header_t *tcp_header; packet = recv_buf; if (is_packet_needed((const char *) packet)) { replica_num = clt_settings.replica_num; packet_num = 1; ip_header = (tc_ip_header_t *)packet; if (localhost == ip_header->saddr) { if (clt_settings.lo_tf_ip != 0) { ip_header->saddr = clt_settings.lo_tf_ip; } } /* * If the packet length is larger than MTU, we split it. * This is to solve the ip fragmentation problem */ if (recv_len > clt_settings.mtu) { /* calculate number of packets */ size_ip = ip_header->ihl << 2; tot_len = ntohs(ip_header -> tot_len); if (tot_len != recv_len) { tc_log_info(LOG_WARN, 0, "packet len:%u, recv len:%u", tot_len, recv_len); return TC_ERROR; } tcp_header = (tc_tcp_header_t *) ((char *) ip_header + size_ip); size_tcp = tcp_header->doff << 2; cont_len = tot_len - size_tcp - size_ip; head_len = size_ip + size_tcp; max_payload = clt_settings.mtu - head_len; packet_num = (cont_len + max_payload - 1)/max_payload; seq = ntohl(tcp_header->seq); last = packet_num - 1; id = ip_header->id; #if (TCPCOPY_DEBUG) tc_log_trace(LOG_NOTICE, 0, CLIENT_FLAG, ip_header, tcp_header); #endif tc_log_debug1(LOG_DEBUG, 0, "recv:%d, more than MTU", recv_len); index = head_len; for (i = 0 ; i < packet_num; i++) { tcp_header->seq = htonl(seq + i * max_payload); if (i != last) { pack_len = clt_settings.mtu; } else { pack_len += (cont_len - packet_num * max_payload); } payload_len = pack_len - head_len; ip_header->tot_len = htons(pack_len); ip_header->id = id++; /* copy header here */ memcpy(tmp_buf, recv_buf, head_len); /* copy payload here */ memcpy(tmp_buf + head_len, recv_buf + index, payload_len); index = index + payload_len; if (replica_num > 1) { packet_valid = process_packet(true, tmp_buf, pack_len); replicate_packs(tmp_buf, pack_len, replica_num); } else { packet_valid = process_packet(false, tmp_buf, pack_len); } } } else { if (replica_num > 1) { packet_valid = process_packet(true, packet, recv_len); replicate_packs(packet, recv_len, replica_num); } else { packet_valid = process_packet(false, packet, recv_len); } } } if (p_valid_flag) { *p_valid_flag = (packet_valid == true ? 1 : 0); } return TC_OK; }
static int dispose_packet(char *recv_buf, int recv_len, int *p_valid_flag) { int replica_num, i, last, packet_num, max_payload, index, payload_len; char *packet, tmp_buf[RECV_BUF_SIZE]; bool packet_valid = false; uint16_t id, size_ip, size_udp, tot_len, cont_len, pack_len, head_len; struct udphdr *udp_header; struct iphdr *ip_header; packet = recv_buf; if (is_packet_needed((const char *)packet)){ replica_num = clt_settings.replica_num; packet_num = 1; ip_header = (struct iphdr*)packet; if (localhost == ip_header->saddr){ if (0 != clt_settings.lo_tf_ip){ ip_header->saddr = clt_settings.lo_tf_ip; } } /* * If packet length larger than MTU, then we split it. * This is to solve the ip fragmentation problem */ if (recv_len > clt_settings.mtu){ /* Calculate number of packets */ size_ip = ip_header->ihl << 2; tot_len = ntohs(ip_header -> tot_len); if (tot_len != recv_len){ log_info(LOG_WARN, "packet len:%u, recv len:%u", tot_len, recv_len); return FAILURE; } udp_header = (struct udphdr*)((char *)ip_header + size_ip); size_udp = ntohs(udp_header->len); cont_len = size_udp - sizeof(struct udphdr); head_len = size_ip + sizeof(struct udphdr); max_payload = clt_settings.mtu - head_len; packet_num = (cont_len + max_payload - 1)/max_payload; last = packet_num - 1; id = ip_header->id; tc_log_debug1(LOG_INFO, "recv:%d, more than MTU", recv_len); index = head_len; for (i = 0 ; i < packet_num; i++){ if (i != last){ pack_len = clt_settings.mtu; }else{ pack_len += (cont_len - packet_num * max_payload); } payload_len = pack_len - head_len; udp_header->len = htons(pack_len - size_ip); ip_header->tot_len = htons(pack_len); ip_header->id = id++; /* Copy header here */ memcpy(tmp_buf, recv_buf, head_len); /* Copy payload here */ memcpy(tmp_buf + head_len, recv_buf + index, payload_len); index = index + payload_len; if (replica_num > 1){ packet_valid = process_packet(true, tmp_buf, pack_len); replicate_packs(tmp_buf, pack_len, replica_num); }else{ packet_valid = process_packet(false, tmp_buf, pack_len); } } }else{ if (replica_num > 1){ packet_valid = process_packet(true, packet, recv_len); replicate_packs(packet, recv_len, replica_num); }else{ packet_valid = process_packet(false, packet, recv_len); } } } if (packet_valid){ *p_valid_flag = 1; } else { *p_valid_flag = 0; } return SUCCESS; }
static int dispose_packet(unsigned char *frame, int frame_len, int ip_recv_len, int *p_valid_flag) { int replica_num, i, last, packet_num, max_payload, index, payload_len; char *p, buf[ETHERNET_HDR_LEN + IP_RECV_BUF_SIZE]; bool packet_valid = false; uint16_t id, size_ip, size_tcp, tot_len, cont_len, pack_len = 0, head_len; uint32_t seq; unsigned char *packet; tc_ip_header_t *ip_header; tc_tcp_header_t *tcp_header; packet = frame + ETHERNET_HDR_LEN; if (is_packet_needed(packet)) { replica_num = clt_settings.replica_num; ip_header = (tc_ip_header_t *) packet; if (clt_settings.clt_tf_ip != 0) { ip_header->saddr = clt_settings.clt_tf_ip; } /* * If the packet length is larger than MTU, we split it. */ if (ip_recv_len > clt_settings.mtu) { /* calculate number of packets */ size_ip = ip_header->ihl << 2; tot_len = ntohs(ip_header -> tot_len); if (tot_len != ip_recv_len) { tc_log_info(LOG_WARN, 0, "packet len:%u, recv len:%u", tot_len, ip_recv_len); return TC_ERROR; } tcp_header = (tc_tcp_header_t *) ((char *) ip_header + size_ip); size_tcp = tcp_header->doff << 2; cont_len = tot_len - size_tcp - size_ip; head_len = size_ip + size_tcp; max_payload = clt_settings.mtu - head_len; packet_num = (cont_len + max_payload - 1)/max_payload; seq = ntohl(tcp_header->seq); last = packet_num - 1; id = ip_header->id; #if (TCPCOPY_DEBUG) tc_log_trace(LOG_NOTICE, 0, CLIENT_FLAG, ip_header, tcp_header); #endif tc_log_debug1(LOG_DEBUG, 0, "recv:%d, more than MTU", ip_recv_len); index = head_len; for (i = 0 ; i < packet_num; i++) { tcp_header->seq = htonl(seq + i * max_payload); if (i != last) { pack_len = clt_settings.mtu; } else { pack_len += (cont_len - packet_num * max_payload); } payload_len = pack_len - head_len; ip_header->tot_len = htons(pack_len); ip_header->id = id++; p = buf + ETHERNET_HDR_LEN; /* copy header here */ memcpy(p, (char *) packet, head_len); p += head_len; /* copy payload here */ memcpy(p, (char *) (packet + index), payload_len); index = index + payload_len; if (replica_num > 1) { packet_valid = process_packet(true, (unsigned char *) buf, ETHERNET_HDR_LEN + pack_len); replicate_packs((unsigned char *) buf, ETHERNET_HDR_LEN + pack_len, replica_num); } else { packet_valid = process_packet(false, (unsigned char *) buf, ETHERNET_HDR_LEN + pack_len); } } } else { if (replica_num > 1) { packet_valid = process_packet(true, frame, frame_len); replicate_packs(frame, frame_len, replica_num); } else { packet_valid = process_packet(false, frame, frame_len); } } } if (p_valid_flag) { *p_valid_flag = (packet_valid == true ? 1 : 0); } return TC_OK; }