• 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 方法用户获取头信息。

  • 相关阅读:
    记一次数据库查询超时的原因 Timeout expired. The timeout period elapsed prior to completion of the operation or the server is not responding. The statement has been terminated Felix
    RSA 算法流程 Felix
    linux shell 比较文件相同部分comm命令和不同部分diff命令 按行读取 文件
    jekins vue 发布脚本 shell
    android 自动化测试参考资料(待验证)
    centos7 redis安装
    技术比赛之转件存储设计
    YD设计架构
    LS项目相关图形
    关于公司开放平台的初期计划
  • 原文地址:https://www.cnblogs.com/yuyue2014/p/5302812.html
Copyright © 2020-2023  润新知