Esempio n. 1
0
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;
}
Esempio n. 2
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;
        }
    }
}
static int 
proc_auth(tc_sess_t *s, tc_iph_t *ip, tc_tcph_t *tcp)
{
    uint16_t          size_tcp;
    unsigned char    *p, *payload, pack_number;
    tc_mysql_session *mysql_sess;

    if (!s->sm.rcv_rep_greet) {
        return PACK_STOP;
    }

    mysql_sess = s->data;

    if (!s->sm.fake_syn) {
        
        if (!mysql_sess->req_begin) {
            size_tcp    = tcp->doff << 2;
            payload = (unsigned char *) ((char *) tcp + size_tcp);
            /* skip packet length */
            payload     = payload + 3; 
            pack_number = payload[0];

            if (pack_number == 0) { 
                mysql_sess->req_begin = 1; 
                mysql_sess->old_ps_cleaned = 1;
                tc_log_debug0(LOG_NOTICE, 0, "it has no sec auth packet");
                release_resources(s->hash_key);

            } else if (pack_number == (unsigned char) SEC_AUTH_PACKET_NUM) { 
                /* if it is the second authenticate_user, skip it */
                tc_log_debug0(LOG_NOTICE, 0, "omit sec validation for mysql");
                mysql_sess->req_begin = 1; 
                mysql_sess->seq_diff = s->cur_pack.cont_len;
                mysql_sess->old_ps_cleaned = 1;
                release_resources(s->hash_key);

                return PACK_NEXT;
            }    
        }    

        if (!mysql_sess->req_begin) {
            if (!ctx.fir_auth_pack) {
                p = cp_fr_ip_pack(ctx.pool, ip); 
                ctx.fir_auth_pack = (tc_iph_t *) (p + ETHERNET_HDR_LEN);
                ctx.fir_auth_cont_len = s->cur_pack.cont_len;
                tc_log_info(LOG_NOTICE, 0, "fir auth is set");
            }
        }
    } else {
        if (!mysql_sess->old_ps_cleaned) {
            mysql_sess->old_ps_cleaned = 1;
            release_resources(s->hash_key);
        }
    }
    
    return PACK_CONTINUE;
}
Esempio n. 4
0
/* Update router table */
void
router_update(tc_ip_header_t *ip_header, int len)
{
    void                   *fd;
    uint32_t                size_ip;
    uint64_t                key;
    msg_server_t            msg;
    struct tcphdr          *tcp_header;

    size_ip    = ip_header->ihl << 2;
    tcp_header = (struct tcphdr*)((char *)ip_header + size_ip);

    memcpy(&msg, ip_header, len);

    key = get_key(ip_header->daddr, tcp_header->dest);

    pthread_mutex_lock(&mutex);

    fd  = hash_find(table, key);
    if ( NULL == fd ) {
        tc_log_debug0(LOG_DEBUG, 0, "fd is null");
        delay_table_add(key, &msg);

        pthread_mutex_unlock(&mutex);

        return ;
    }

    pthread_mutex_unlock(&mutex);

    tc_socket_send((int) (long) fd, (char *) &msg, MSG_SERVER_SIZE);
}
Esempio n. 5
0
/* Update router table */
void
router_update(struct iphdr *ip_header)
{
    void                   *fd;
    uint32_t                size_ip;
    uint64_t                key;
    msg_server_t            msg;
    struct tcphdr          *tcp_header;
#if (TCPCOPY_MYSQL_ADVANCED) 
    uint32_t                size_tcp, cont_len, tot_len;
    unsigned char          *payload;
#endif

    if (ip_header->protocol != IPPROTO_TCP) {
        tc_log_info(LOG_INFO, 0, "this is not a tcp packet");
        return;
    }

    size_ip = ip_header->ihl << 2;
    tcp_header = (struct tcphdr*)((char *)ip_header + size_ip);

    memset(&msg, 0, sizeof(struct msg_server_s));
    memcpy((void *) &(msg.ip_header),  ip_header,  sizeof(struct iphdr));
    memcpy((void *) &(msg.tcp_header), tcp_header, sizeof(struct tcphdr));

#if (TCPCOPY_MYSQL_ADVANCED) 
    tot_len  = ntohs(ip_header->tot_len);
    size_tcp = tcp_header->doff << 2;
    cont_len = tot_len - size_ip - size_tcp;
    if (cont_len > 0) {
        payload = (unsigned char*)((char*)tcp_header + size_tcp);
        if (cont_len <= MAX_PAYLOAD_LEN) {
            /*
             * Only transfer payload if content length is less
             * than MAX_PAYLOAD_LEN
             */
            memcpy((void *) &(msg.payload), payload, cont_len);
        }
    }
#endif

    key = get_key(ip_header->daddr, tcp_header->dest);
    fd  = hash_find(table, key);
    if ( NULL == fd ) {
        tc_log_debug0(LOG_DEBUG, 0, "fd is null");
        delay_table_add(key, &msg);
        return ;
    }

    tc_socket_send((int) (long) fd, (char *) &msg, MSG_SERVER_SIZE);
}
Esempio n. 6
0
/* Receive a server message */
struct msg_server_s *
msg_client_recv(int sock)
{
    size_t  len = 0;
    ssize_t ret;
    while (len != sizeof(struct msg_server_s)) {
        ret = recv(sock, (char *)&s_msg + len,
                sizeof(struct msg_server_s) - len, 0);
        if (0 == ret) {
            tc_log_debug0(LOG_DEBUG, 0, "recv zero len in msg_client_recv");
            (void)close(sock);
            return NULL;
        } else if (-1 == ret) {
            continue;
        } else {
            len += ret;
        }
    }
    return &s_msg;
}
static bool
check_renew_session(tc_iph_t *ip, tc_tcph_t *tcp)
{
    uint16_t        size_ip, size_tcp, tot_len, cont_len;
    unsigned char  *payload, command, pack_number;

    if (ctx.fir_auth_pack == NULL) {
        tc_log_debug0(LOG_DEBUG, 0, "fir auth packet is null");
        return false;
    }

    size_ip  = ip->ihl << 2;
    size_tcp = tcp->doff << 2;
    tot_len  = ntohs(ip->tot_len);
    cont_len = tot_len - size_tcp - size_ip;

    if (cont_len > 0) {
        payload = (unsigned char *) ((char *) tcp + size_tcp);
        /* skip packet length */
        payload = payload + 3;
        /* retrieve packet number */
        pack_number = payload[0];
        /* if it is the second authenticate_user, skip it */
        if (pack_number != 0) {
            return false;
        }
        /* skip packet number */
        payload = payload + 1;

        command = payload[0];
        tc_log_debug1(LOG_DEBUG, 0, "mysql command:%u", command);
        if (command == COM_QUERY || command == COM_STMT_EXECUTE) {
            return true;
        }
    }

    return false;
}
Esempio n. 8
0
/* Dispose one event*/
void
dispose_event(int fd)
{
    struct msg_server_s *msg;

    if (fd == raw_sock) {
        retrieve_raw_sockets(fd);
    } else {

        msg = msg_client_recv(fd);
        if (NULL == msg ) {
            fprintf(stderr, "NULL msg :\n");
            tc_log_info(LOG_ERR, 0, "NULL msg from msg_client_recv");
            exit(EXIT_FAILURE);
        }
        process((char*)msg, REMOTE);
    }
#if (TCPCOPY_OFFLINE)
    if (!read_pcap_over) {
        tc_log_debug0(LOG_DEBUG, 0, "send_packets_from_pcap");
        send_packets_from_pcap(0);
    }
#endif
}
Esempio n. 9
0
void
buffer_and_send(int mfd, int fd, msg_server_t *msg)
{
    int                  ret = TC_OK, is_send = 0, bytes;
    unsigned char       *p;
    aggregation_t       *aggr;

#if (TCPCOPY_SINGLE)
    if (mfd == 0) {
        return;
    }
#endif

    if (fd > max_fd) {
        max_fd = fd;
    }

    if (max_fd > MAX_FD_VALUE) {
        tc_log_info(LOG_WARN, 0, "fd is too large:%d", max_fd);
        max_fd = MAX_FD_VALUE;
        return;
    }

    if (!fd_valid[fd]) {
        tc_log_debug1(LOG_DEBUG, 0, "fd is not valid:%d", fd);
        return;
    }

    aggr = combined[fd];
    if (!aggr) {
        aggr = (aggregation_t *) malloc(sizeof(aggregation_t));
        if (aggr == NULL) {
            tc_log_info(LOG_ERR, errno, "can't malloc memory");
        } else {
            tc_log_info(LOG_INFO, 0, "malloc memory for fd:%d", fd);
            memset(aggr, 0, sizeof(aggregation_t));
            aggr->cur_write = aggr->aggr_resp;
            combined[fd] = aggr;
        }
    }

    if (aggr) {
        if (msg != NULL) {
            p = aggr->cur_write;
            memcpy((char *) p, (char *) msg, MSG_SERVER_SIZE); 
            aggr->cur_write = p + MSG_SERVER_SIZE;
            aggr->num = aggr->num + 1;
        } else {
            if (aggr->num == 0) {
                tc_log_debug0(LOG_DEBUG, 0, "combined num is zero");
                return;
            }
        }

        if (aggr->num == COMB_MAX_NUM) {
            is_send = 1;
        } else if (aggr->access_time < tc_current_time_sec) {
            is_send = 1;
        } else if (aggr->access_time == tc_current_time_sec) {
            if (aggr->access_msec != tc_current_time_msec) {
                is_send = 1;
            }
        }

        if (is_send) {
            tc_log_debug1(LOG_DEBUG, 0, "combined send:%d", aggr->num);
            aggr->num = htons(aggr->num);
            p = (unsigned char *) (&(aggr->num));
            bytes = aggr->cur_write - aggr->aggr_resp + sizeof(aggr->num);
            tc_log_debug1(LOG_DEBUG, 0, "send bytes:%d", bytes);
#if (!TCPCOPY_SINGLE)
            ret = tc_socket_send(fd, (char *) p, bytes);
#else
            ret = tc_socket_send(mfd, (char *) p, bytes);
#endif
            aggr->num = 0;
            aggr->cur_write = aggr->aggr_resp;
        } 

        aggr->access_time = tc_current_time_sec;
        aggr->access_msec = tc_current_time_msec;

        if (ret == TC_ERROR) {
            fd_valid[fd] = false;
            free(combined[fd]);
            combined[fd] = NULL;
        }
    }
}
Esempio n. 10
0
void
router_update(int main_router_fd, tc_ip_header_t *ip_header)
{
#if (!TCPCOPY_SINGLE)
    void                   *fd;
    uint64_t                key;
#endif
    uint32_t                size_ip, size_tcp, new_size_tcp;
    msg_server_t            msg;
    tc_tcp_header_t        *tcp_header;
#if (TCPCOPY_MYSQL_ADVANCED)
    uint32_t                cont_len, tot_len, new_tot_len;
    unsigned char          *payload, *p;
#endif

#if (TCPCOPY_SINGLE)
    if (main_router_fd == 0) {
        return;
    }
#endif
    if (ip_header->protocol != IPPROTO_TCP) {
        tc_log_info(LOG_INFO, 0, "this is not a tcp packet");
        return;
    }

    size_ip = ip_header->ihl << 2;
    tcp_header = (tc_tcp_header_t *) ((char *) ip_header + size_ip);
    size_tcp = tcp_header->doff << 2;
#if (TCPCOPY_MYSQL_ADVANCED)
    tot_len  = ntohs(ip_header->tot_len);
#endif

    memset(&msg, 0, sizeof(struct msg_server_s));

    new_size_tcp = size_tcp;
    if (size_tcp > TCP_HEADER_MIN_LEN) {
        set_wscale(tcp_header);
        new_size_tcp = tcp_header->doff << 2;
#if (TCPCOPY_MYSQL_ADVANCED)
        new_tot_len = tot_len - (size_tcp - new_size_tcp);
        ip_header->tot_len = htons(new_tot_len);
#endif
    }
    memcpy((void *) &(msg.ip_header), ip_header, sizeof(tc_ip_header_t));
    memcpy((void *) &(msg.tcp_header), tcp_header, new_size_tcp);

#if (TCPCOPY_MYSQL_ADVANCED)
    cont_len = tot_len - size_ip - size_tcp;
    if (cont_len > 0) {
        payload = (unsigned char *) ((char *) tcp_header + size_tcp);
        if (cont_len <= MAX_PAYLOAD_LEN) {
            p = ((unsigned char *) &(msg.tcp_header)) + new_size_tcp;
            /*
             * only transfer payload if content length is less
             * than MAX_PAYLOAD_LEN
             */
            memcpy((void *) p, payload, cont_len);
        }
    }
#endif
#if (!TCPCOPY_SINGLE)
    key = get_key(ip_header->daddr, tcp_header->dest);
    fd  = hash_find(table, key);
    if (fd == NULL) {
        if (!tcp_header->syn) {
            tc_log_info(LOG_NOTICE, 0, "fd is null after session is created");
            tc_log_trace(LOG_NOTICE, 0,  BACKEND_FLAG, ip_header, tcp_header);
        }
        tc_log_debug0(LOG_DEBUG, 0, "fd is null");
        fd_null_cnt++;
        delay_table_add(key, &msg);
        return ;
    }
#endif

    tc_log_debug_trace(LOG_NOTICE, 0,  BACKEND_FLAG, ip_header, tcp_header);

#if (INTERCEPT_COMBINED)

#if (!TCPCOPY_SINGLE)
    buffer_and_send(main_router_fd, (int) (long) fd, &msg);
#else
    buffer_and_send(main_router_fd, main_router_fd, &msg);
#endif

#else

#if (!TCPCOPY_SINGLE)
    tc_socket_send((int) (long) fd, (char *) &msg, MSG_SERVER_SIZE);
#else
    tc_socket_send(main_router_fd, (char *) &msg, MSG_SERVER_SIZE);
#endif

#endif

}
Esempio n. 11
0
/* update router table */
void
router_update(int main_router_fd, tc_ip_header_t *ip_header, int len)
{
#if (!TCPCOPY_SINGLE)
    void                   *fd;
    uint64_t                key;
#endif
    uint32_t                size_ip;
    msg_server_t            msg;
    tc_tcp_header_t        *tcp_header;

#if (TCPCOPY_SINGLE)
    if (main_router_fd == 0) {
        return;
    }
#endif
    if (ip_header->protocol != IPPROTO_TCP) {
        tc_log_info(LOG_INFO, 0, "this is not a tcp packet");
        return;
    }

    size_ip    = ip_header->ihl << 2;
    tcp_header = (tc_tcp_header_t *) ((char *) ip_header + size_ip);

    tc_log_debug1(LOG_DEBUG, 0, "router update:%u", ntohs(tcp_header->source));
    memcpy(&msg, ip_header, len);

#if (!TCPCOPY_SINGLE)
    key = get_key(ip_header->daddr, tcp_header->dest);
    pthread_mutex_lock(&mutex);

    fd  = hash_find(table, key);
    if (fd == NULL) {
        if (!tcp_header->syn) {
            tc_log_info(LOG_NOTICE, 0, "fd is null after session is created");
            tc_log_trace(LOG_NOTICE, 0,  BACKEND_FLAG, ip_header, tcp_header); 
        }
        tc_log_debug0(LOG_DEBUG, 0, "fd is null");
        fd_null_cnt++;
        delay_table_add(key, &msg);

        pthread_mutex_unlock(&mutex);

        return ;
    }

    pthread_mutex_unlock(&mutex);
#endif

    tc_log_debug_trace(LOG_NOTICE, 0,  BACKEND_FLAG, ip_header, tcp_header);

#if (INTERCEPT_COMBINED)

#if (!TCPCOPY_SINGLE)
    buffer_and_send(main_router_fd, (int) (long) fd, &msg);
#else
    buffer_and_send(main_router_fd, main_router_fd, &msg);
#endif

#else

#if (!TCPCOPY_SINGLE)
    tc_socket_send((int) (long) fd, (char *) &msg, MSG_SERVER_SIZE);
#else
    tc_socket_send(main_router_fd, (char *) &msg, MSG_SERVER_SIZE);
#endif

#endif

}
Esempio n. 12
0
void process_outgress(unsigned char *packet)
{
    uint16_t           size_ip, size_tcp, tot_len, cont_len;
    uint32_t           seq, ack_seq;
    uint64_t           key;
    tc_user_t         *u;
    tc_ip_header_t    *ip_header;
    tc_tcp_header_t   *tcp_header;

    last_resp_time = tc_time();
    resp_cnt++;
    ip_header  = (tc_ip_header_t *) packet;
    size_ip    = ip_header->ihl << 2;
    tcp_header = (tc_tcp_header_t *) ((char *) ip_header + size_ip);


    key = tc_get_key(ip_header->daddr, tcp_header->dest);
    tc_log_debug1(LOG_DEBUG, 0, "key from bak:%llu", key);
    u = tc_retrieve_user(key);

    if (u != NULL) {

        tc_log_debug_trace(LOG_DEBUG, 0, BACKEND_FLAG, ip_header, tcp_header);
        u->srv_window = ntohs(tcp_header->window);
        if (u->wscale) {
            u->srv_window = u->srv_window << (u->wscale);
            tc_log_debug1(LOG_DEBUG, 0, "window size:%u", u->srv_window);
        }
        if (u->state.timestamped) {
            retrieve_options(u, REMOTE, tcp_header);
        }
        size_tcp = tcp_header->doff << 2;
        tot_len  = ntohs(ip_header->tot_len);
        cont_len = tot_len - size_tcp - size_ip;

        if (ip_header->daddr != u->src_addr || tcp_header->dest!= u->src_port) {
            tc_log_info(LOG_NOTICE, 0, " key conflict");
        }
        seq = ntohl(tcp_header->seq);
        u->exp_seq = tcp_header->ack_seq;
        ack_seq = ntohl(tcp_header->ack_seq);

        if (u->last_seq == seq && u->last_ack_seq == ack_seq) {
            u->fast_retransmit_cnt++;
            if (u->fast_retransmit_cnt == 3) {
                fast_retransmit(u, ack_seq);
                return;
            }
        } else {
            update_ack_packets(u, ack_seq);
            u->fast_retransmit_cnt = 0;
        }

        u->last_ack_seq =  ack_seq;
        u->last_seq =  seq;


        if (cont_len > 0) {
            u->last_recv_resp_cont_time = tc_milliscond_time();
            resp_cont_cnt++;
            u->state.resp_waiting = 0;   
            u->exp_ack_seq = htonl(seq + cont_len);
            send_faked_ack(u);
        } else {
            u->exp_ack_seq = tcp_header->seq;
        }
        
        if (tcp_header->syn) {
            tc_log_debug1(LOG_DEBUG, 0, "recv syn from back:%u", 
                    ntohs(u->src_port));
            u->exp_ack_seq = htonl(ntohl(u->exp_ack_seq) + 1);
            if (!u->state.resp_syn_received) {
                conn_cnt++;
                active_conn_cnt++;
                u->state.resp_syn_received = 1;
                u->state.status |= SYN_CONFIRM;
                tc_log_debug2(LOG_DEBUG, 0, "exp ack seq:%u, p:%u",
                        ntohl(u->exp_ack_seq), ntohs(u->src_port));
                if (size_tcp > TCP_HEADER_MIN_LEN) {
                    retrieve_options(u, REMOTE, tcp_header);
                    if (u->wscale > 0) {
                        tc_log_debug2(LOG_DEBUG, 0, "wscale:%u, p:%u",
                                u->wscale, ntohs(u->src_port));
                    }
                }
                process_user_packet(u);

            } else {
                tc_log_debug1(LOG_DEBUG, 0, "syn, but already syn received:%u",
                    ntohs(u->src_port));
            }
        } else if (tcp_header->fin) {
            tc_log_debug1(LOG_DEBUG, 0, "recv fin from back:%u", 
                    ntohs(u->src_port));
            u->exp_ack_seq = htonl(ntohl(u->exp_ack_seq) + 1);
            u->state.status  |= SERVER_FIN;
            send_faked_ack(u);
            process_user_packet(u);
            fin_recv_cnt++;

        } else if (tcp_header->rst) {
            tc_log_info(LOG_NOTICE, 0, "recv rst from back:%u", 
                    ntohs(u->src_port));
            rst_recv_cnt++;
            if (u->state.status == SYN_SENT) {
                if (!u->state.over) {
                    conn_reject_cnt++;
                }
            }

            u->state.over = 1;
            u->state.status  |= SERVER_FIN;
        }

    } else {
        tc_log_debug_trace(LOG_DEBUG, 0, BACKEND_FLAG, ip_header,
                tcp_header);
        tc_log_debug0(LOG_DEBUG, 0, "no active session for me");
    }

}
Esempio n. 13
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;
        }
    }
}
Esempio n. 14
0
void
router_update(int old, int main_router_fd, tc_ip_header_t *ip_header)
{
#if (!TCPCOPY_SINGLE)
    int                     fd;
    uint32_t                key;
#endif
    uint32_t                size_ip, size_tcp, tot_len;
    msg_server_t            msg;
    tc_tcp_header_t        *tcp_header;
#if (TCPCOPY_MYSQL_ADVANCED)
    uint32_t                cont_len;
    unsigned char          *payload, *p;
#endif
#if (TCPCOPY_SINGLE)
    if (main_router_fd == 0) {
        return;
    }
#endif
    if (ip_header->protocol != IPPROTO_TCP) {
        tc_log_info(LOG_INFO, 0, "this is not a tcp packet");
        return;
    }

    size_ip = ip_header->ihl << 2;
    tcp_header = (tc_tcp_header_t *) ((char *) ip_header + size_ip);
    size_tcp = tcp_header->doff << 2;
    tot_len  = ntohs(ip_header->tot_len);

    memset(&msg, 0, sizeof(struct msg_server_s));
    memcpy((void *) &(msg.ip_header), ip_header, sizeof(tc_ip_header_t));
    memcpy((void *) &(msg.tcp_header), tcp_header, size_tcp);

#if (TCPCOPY_MYSQL_ADVANCED)
    cont_len = tot_len - size_ip - size_tcp;
    if (cont_len > 0) {
        payload = (unsigned char *) ((char *) tcp_header + size_tcp);
        if (cont_len <= MAX_PAYLOAD_LEN) {
            p = ((unsigned char *) &(msg.tcp_header)) + size_tcp;
            memcpy((void *) p, payload, cont_len);
        }
    }
#endif 
#if (!TCPCOPY_SINGLE)
    key = get_route_key(old, ip_header->daddr, tcp_header->dest, 
            ip_header->saddr, tcp_header->source);
    fd  = router_get(key);
    if (fd <= 0) {
        if (tcp_header->syn || tcp_header->rst) {
            if (tcp_header->rst) {
                tc_log_info(LOG_NOTICE, 0, "reset from tcp");
            } 
            tc_log_debug0(LOG_DEBUG, 0, "fd is null");
            delay_table_add(key, &msg);
            return ;
        } else {
            tc_log_info(LOG_NOTICE, 0, "fd is null after session is created");
            tc_log_trace(LOG_NOTICE, 0,  BACKEND_FLAG, ip_header, tcp_header);
            return;
        }
    }
#endif

    tc_log_debug_trace(LOG_NOTICE, 0,  BACKEND_FLAG, ip_header, tcp_header);

#if (INTERCEPT_COMBINED)

#if (!TCPCOPY_SINGLE)
    buffer_and_send(main_router_fd, (int) (long) fd, &msg);
#else
    buffer_and_send(main_router_fd, main_router_fd, &msg);
#endif                       
#else

#if (!TCPCOPY_SINGLE)
    tc_socket_send((int) (long) fd, (char *) &msg, MSG_SERVER_SIZE);
#else
    tc_socket_send(main_router_fd, (char *) &msg, MSG_SERVER_SIZE);
#endif

#endif

}