zoukankan      html  css  js  c++  java
  • tcprstat源码分析之tcp数据包分析

    tcprstat是percona用来监测mysql响应时间的。不过对于任何运行在TCP协议上的响应时间,都可以用。

    tcprstat和tcpdump一样,使用libpcap库进行抓包,然后再通过程序对抓取的tcp包进行分析。

    1、通过分析来源ip和目标ip,看那个ip是本地ip,来判断是进来的包(请求包)还是出去的包(响应包)。
    2、如果包的数据大小为0,那么就跳过,不再处理。数据大小为0的视为tcp控制包。
    3、如果数据包为进来的包(请求包),则插入一条记录到哈希表。
    4、如果数据包为出去的包(响应包),则用现在的包和之前插入哈希表中的响应包做时间差计算。并把之前的包在哈希表中删除。

    数据包分析的代码在process-packet.c文件中,方法如下:

    int process_ip(pcap_t *dev, const struct ip *ip, struct timeval tv) {
        char src[16], dst[16], *addr;
        int incoming;
        unsigned len;
        
        addr = inet_ntoa(ip->ip_src);
        strncpy(src, addr, 15);
        src[15] = '';
        
        addr = inet_ntoa(ip->ip_dst);
        strncpy(dst, addr, 15);
        dst[15] = '';
        
        if (is_local_address(ip->ip_src))
            incoming = 0;
        else if (is_local_address(ip->ip_dst))
            incoming = 1;
        else
            return 1;
        
        len = htons(ip->ip_len);
        
        switch (ip->ip_p) {
            struct tcphdr *tcp;
            uint16_t sport, dport, lport, rport;
            unsigned datalen;
        
        case IPPROTO_TCP:
            tcp = (struct tcphdr *) ((unsigned char *) ip + sizeof(struct ip));
            
    #if defined(__FAVOR_BSD)
            sport = ntohs(tcp->th_sport);
            dport = ntohs(tcp->th_dport);
            datalen = len - sizeof(struct ip) - tcp->th_off * 4;    // 4 bits offset 
    #else
            sport = ntohs(tcp->source);
            dport = ntohs(tcp->dest);
            datalen = len - sizeof(struct ip) - tcp->doff * 4;
    #endif
    
            // Capture only "data" packets, ignore TCP control
            if (datalen == 0)
                break;
    
            if (incoming) {
                lport = dport;
                rport = sport;
                
                inbound(tv, ip->ip_dst, ip->ip_src, lport, rport);
                
            }
            else {
                lport = sport;
                rport = dport;
                
                outbound(tv, ip->ip_src, ip->ip_dst, lport, rport);
                
            }
    
            break;
            
        default:
            break;
            
        }
        
        return 0;
        
    }
    

    ps:在这个文件中,process_packet 方法用户获取头信息。

  • 相关阅读:
    学习网站
    Windows下python安装运行
    Python学习
    ES学习
    Eclipse安装lombok及常用注解
    Spark学习资料
    Spring Cloud学习资料
    使用Excel过滤重复数据
    Excel根据字符串截取单元格部分内容
    Spring中@Transactional(rollbackFor = Exception.class)的作用
  • 原文地址:https://www.cnblogs.com/yuyue2014/p/5302812.html
Copyright © 2011-2022 走看看