예제 #1
0
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;
}
예제 #2
0
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;
}
예제 #3
0
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);
}
예제 #4
0
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;
        }
    }
}
예제 #5
0
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);
}
예제 #6
0
파일: manager.c 프로젝트: chijiao/tcpcopy
/*
 * 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;
}
예제 #7
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);
}
예제 #8
0
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;
}
예제 #9
0
 ~tcp_packet_t() {
     dispose_packet();
 }
예제 #10
0
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;
        }
    }
}