static int tc_process_raw_socket_packet(tc_event_t *rev) { int recv_len, frame_len; unsigned char frame[ETHERNET_HDR_LEN + IP_RECV_BUF_SIZE]; for ( ;; ) { recv_len = recvfrom(rev->fd, frame + ETHERNET_HDR_LEN, IP_RECV_BUF_SIZE, 0, NULL, NULL); if (recv_len == -1) { if (errno == EAGAIN) { return TC_OK; } tc_log_info(LOG_ERR, errno, "recvfrom"); return TC_ERROR; } if (recv_len == 0) { tc_log_info(LOG_ERR, 0, "recv len is 0"); return TC_ERROR; } frame_len = ETHERNET_HDR_LEN + recv_len; if (dispose_packet(frame, frame_len, recv_len, NULL) == TC_ERROR) { return TC_ERROR; } } return TC_OK; }
static int tc_process_raw_socket_packet(tc_event_t *rev) { int recv_len; char recv_buf[RECV_BUF_SIZE]; for ( ;; ) { recv_len = recvfrom(rev->fd, recv_buf, RECV_BUF_SIZE, 0, NULL, NULL); if (recv_len == -1) { if (errno == EAGAIN) { return TC_OK; } tc_log_info(LOG_ERR, errno, "recvfrom"); return TC_ERROR; } if (recv_len == 0) { tc_log_info(LOG_ERR, 0, "recv len is 0"); return TC_ERROR; } if (dispose_packet(recv_buf, recv_len, NULL) == TC_ERROR) { return TC_ERROR; } } return TC_OK; }
static void pcap_retrieve(unsigned char *args, const struct pcap_pkthdr *pkt_hdr, unsigned char *packet) { int l2_len, ip_pack_len; pcap_t *pcap; unsigned char *ip_data; struct ethernet_hdr *ether; if (pkt_hdr->len < ETHERNET_HDR_LEN) { tc_log_info(LOG_ERR, 0, "recv len is less than:%d", ETHERNET_HDR_LEN); return; } ether = (struct ethernet_hdr *) packet; if (ntohs(ether->ether_type) != ETH_P_IP) { return; } pcap = (pcap_t *)args; ip_data = get_ip_data(pcap, packet, pkt_hdr->len, &l2_len); ip_pack_len = pkt_hdr->len - l2_len; dispose_packet((char *) ip_data, ip_pack_len, NULL); }
static void send_packets_from_pcap(int first) { int l2_len, ip_pack_len, p_valid_flag = 0; bool stop; pcap_t *pcap; unsigned char *pkt_data, *ip_data; struct pcap_pkthdr pkt_hdr; pcap = clt_settings.pcap; if (pcap == NULL || read_pcap_over) { return; } gettimeofday(&cur_time, NULL); stop = check_read_stop(); while (!stop) { pkt_data = (u_char *) pcap_next(pcap, &pkt_hdr); if (pkt_data != NULL) { if (pkt_hdr.caplen < pkt_hdr.len) { tc_log_info(LOG_WARN, 0, "truncated packets,drop"); } else { ip_data = get_ip_data(pkt_data, pkt_hdr.len, &l2_len); if (ip_data != NULL) { ip_pack_len = pkt_hdr.len - l2_len; dispose_packet((char*)ip_data, ip_pack_len, &p_valid_flag); if (p_valid_flag) { tc_log_debug0(LOG_DEBUG, 0, "valid flag for packet"); if (first) { first_pack_time = pkt_hdr.ts; first = 0; } last_pack_time = pkt_hdr.ts; } else { stop = false; tc_log_debug0(LOG_DEBUG, 0, "stop,invalid flag"); } } } stop = check_read_stop(); } else { tc_log_info(LOG_WARN, 0, "stop, null from pcap_next"); stop = true; read_pcap_over = true; } } }
static void pcap_tunnel_retrieve(pcap_t *pcap, const struct pcap_pkthdr *pkt_hdr, unsigned char *frame) { int l2_len = 0, ip_pack_len, frame_len; unsigned char *ip_data, tunnel_frame[ETHERNET_HDR_LEN + IP_RECV_BUF_SIZE]; ip_data = get_ip_data(pcap, frame, pkt_hdr->len, &l2_len); ip_pack_len = pkt_hdr->len - l2_len; memcpy(tunnel_frame + ETHERNET_HDR_LEN, ip_data, ip_pack_len); frame_len = ip_pack_len + ETHERNET_HDR_LEN; dispose_packet(tunnel_frame, frame_len, ip_pack_len, NULL); }
/* * Retrieve raw packets */ static int retrieve_raw_sockets(int sock) { int err, recv_len, p_valid_flag = 0; char recv_buf[RECV_BUF_SIZE]; while (true) { recv_len = recvfrom(sock, recv_buf, RECV_BUF_SIZE, 0, NULL, NULL); if (recv_len < 0) { err = errno; if (EAGAIN == err) { break; } tc_log_info(LOG_ERR, errno, "recvfrom"); } if (0 == recv_len) { tc_log_info(LOG_ERR, 0, "recv len is 0"); break; } raw_packs++; if (recv_len > RECV_BUF_SIZE) { tc_log_info(LOG_ERR, 0, "recv_len:%d ,it is too long", recv_len); break; } if (FAILURE == dispose_packet(recv_buf, recv_len, &p_valid_flag)) { break; } if (p_valid_flag) { valid_raw_packs++; } if (raw_packs % 100000 == 0) { tc_log_info(LOG_NOTICE, 0, "raw packets:%llu, valid :%llu", raw_packs, valid_raw_packs); } } return 0; }
static void pcap_retrieve(unsigned char *args, const struct pcap_pkthdr *pkt_hdr, unsigned char *frame) { int l2_len, ip_pack_len, frame_len; pcap_t *pcap; unsigned char *ip_data; struct ethernet_hdr *ether; if (pkt_hdr->len < ETHERNET_HDR_LEN) { tc_log_info(LOG_ERR, 0, "recv len is less than:%d", ETHERNET_HDR_LEN); return; } pcap = (pcap_t *) args; frame_len = pkt_hdr->len; l2_len = get_l2_len(frame, frame_len, pcap_datalink(pcap)); if (l2_len != ETHERNET_HDR_LEN) { if (l2_len > ETHERNET_HDR_LEN) { ip_data = get_ip_data(pcap, frame, pkt_hdr->len, &l2_len); frame = ip_data - ETHERNET_HDR_LEN; frame_len = frame_len - l2_len + ETHERNET_HDR_LEN; } else if (l2_len == 0) { /* tunnel frames without ethernet header */ pcap_tunnel_retrieve(pcap, pkt_hdr, frame); return; } else { tc_log_info(LOG_WARN, 0, "l2 len is %d", l2_len); return; } } else { ether = (struct ethernet_hdr *) frame; if (ntohs(ether->ether_type) != ETH_P_IP) { return; } } ip_pack_len = pkt_hdr->len - l2_len; dispose_packet(frame, frame_len, ip_pack_len, NULL); }
static int tc_process_pcap_socket_packet(tc_event_t *rev) { int recv_len; char recv_buf[PCAP_RECV_BUF_SIZE], *ip_header; struct ethernet_hdr *ether; for ( ;; ) { recv_len = recvfrom(rev->fd, recv_buf, PCAP_RECV_BUF_SIZE, 0, NULL, NULL); if (recv_len == -1) { if (errno == EAGAIN) { return TC_OK; } tc_log_info(LOG_ERR, errno, "recvfrom"); return TC_ERROR; } if (recv_len == 0 ||recv_len < ETHERNET_HDR_LEN) { tc_log_info(LOG_ERR, 0, "recv len is 0 or less than 16"); return TC_ERROR; } ether = (struct ethernet_hdr *)recv_buf; if (ntohs(ether->ether_type) != 0x800) { return TC_OK; } ip_header = recv_buf + ETHERNET_HDR_LEN; recv_len = recv_len - ETHERNET_HDR_LEN; if (dispose_packet(ip_header, recv_len, NULL) == TC_ERROR) { return TC_ERROR; } } return TC_OK; }
~tcp_packet_t() { dispose_packet(); }
static void send_packets_from_pcap(int first) { int l2_len, ip_pack_len, p_valid_flag = 0; bool stop; pcap_t *pcap; unsigned char *pkt_data, *frame, *ip_data; struct pcap_pkthdr pkt_hdr; pcap = clt_settings.pcap; if (pcap == NULL || read_pcap_over) { return; } gettimeofday(&cur_time, NULL); stop = check_read_stop(); while (!stop) { pkt_data = (u_char *) pcap_next(pcap, &pkt_hdr); if (pkt_data != NULL) { if (pkt_hdr.caplen < pkt_hdr.len) { tc_log_info(LOG_WARN, 0, "truncated packets,drop"); } else { ip_data = get_ip_data(clt_settings.pcap, pkt_data, pkt_hdr.len, &l2_len); if (l2_len < ETHERNET_HDR_LEN) { tc_log_info(LOG_WARN, 0, "l2 len is %d", l2_len); continue; } last_pack_time = pkt_hdr.ts; if (ip_data != NULL) { clt_settings.pcap_time = last_pack_time.tv_sec * 1000 + last_pack_time.tv_usec / 1000; ip_pack_len = pkt_hdr.len - l2_len; tc_log_debug2(LOG_DEBUG, 0, "frame len:%d, ip len:%d", pkt_hdr.len, ip_pack_len); frame = ip_data - ETHERNET_HDR_LEN; dispose_packet(frame, ip_pack_len + ETHERNET_HDR_LEN, ip_pack_len, &p_valid_flag); if (p_valid_flag) { tc_log_debug0(LOG_DEBUG, 0, "valid flag for packet"); if (first) { first_pack_time = pkt_hdr.ts; first = 0; } else { adj_v_pack_diff = timeval_diff(&last_v_pack_time, &last_pack_time); } /* set last valid packet time in pcap file */ last_v_pack_time = last_pack_time; stop = check_read_stop(); } else { tc_log_debug0(LOG_DEBUG, 0, "invalid flag"); } } } } else { tc_log_info(LOG_WARN, 0, "stop, null from pcap_next"); stop = true; read_pcap_over = true; } } }