来自pcap文件的IP数据包显示错误的长度

时间:2017-05-10 07:17:23

标签: c++ pcap

我在不使用libpcap库的情况下用c ++编写pcap文件。数据包结构是正确的。但我发现IP数据包的长度是错误的,因此其余的协议都没有显示出来。错误显示在附加的'pcap file error image'文件中。我搜索了libpcap format wireshark等等......但是我没有找到解决问题的方法。

pcap file error image

这是我的代码

 int iWritePcapHeader(){  


        pcap_global_header_s.magic_number =  0xa1b2c3d4 ;
        pcap_global_header_s.version_major = PCAP_VERSION_MAJOR ;
        pcap_global_header_s.version_minor = PCAP_VERSION_MINOR;
        pcap_global_header_s.thiszone = 0; // check here if timestamps of packets are not correct
        pcap_global_header_s.sigfigs = 0;
        pcap_global_header_s.snaplen = 65535;
        pcap_global_header_s.network = 1;   //Ethernet          

        return 0;
    }

    uint16_t uiIPHeader_Checksum(void *data, int len)
    {
        uint32_t sum=0;
        size_t i;
        for (i=0; i < len/2; ++i)
            sum += ntohs(((uint16_t*)data)[i]);
        while (sum & 0xFFFF0000)
            sum = (sum & 0xFFFF)+(sum >> 16);
        return ((uint16_t) ~sum);
    }

    int iWrite(
        const CString &rcsSrcAddress, unsigned long ulSrcPort,
        const CString &rcsDestAddress, unsigned long ulDestPort, 
        enum E_PROTOCOL_TYPE eProtocolType,
        const unsigned char *pucBytes, unsigned long ulNofBytes)
    {
        printf("iWrite %ul\n" , ulNofBytes);

        iWritePcapHeader();

        //PCAP header for each data packet  
        SYSTEMTIME timews;
        GetSystemTime(&timews);
        PCAP_PKT_HEADER pcap_pkt_header_s ;
        pcap_pkt_header_s.ts_sec = time(NULL);
        pcap_pkt_header_s.ts_usec =  (timews.wMilliseconds * 1000);
        pcap_pkt_header_s.incl_len = ulNofBytes + sizeof(UDP_HEADER) + sizeof(IP_HEADER) + sizeof(ETHERNET_HEADER);
        pcap_pkt_header_s.orig_len = ulNofBytes + sizeof(UDP_HEADER) + sizeof(IP_HEADER) + sizeof(ETHERNET_HEADER);

        //Ethernet Header
        ETHERNET_HEADER ethernet_header_s;
        unsigned char macAddress[6] = {0x00,0x00,0x00,0x00,0x00,0x00};      // no mac available for now. Hence just fill in dummy data
        memcpy(ethernet_header_s.dst,macAddress,6);
        memcpy(ethernet_header_s.src,macAddress,6);
        ethernet_header_s.type = 0x0800;


        //IP_Header   
        IP_HEADER ip_header_s;
        ip_header_s.ip_v = IPVERSION;
        ip_header_s.ip_hl = 5;
        ip_header_s.ip_tos = 0;
        ip_header_s.ip_len = (uint16_t)(ulNofBytes + sizeof(UDP_HEADER) + sizeof(IP_HEADER));
        ip_header_s.ip_id =   0;
        ip_header_s.ip_off = IP_DF;
        ip_header_s.ip_ttl =  0x40;  // 40(hex) = 64 , 80(hex) = 128
        ip_header_s.ip_p = 0x11;                                                                   
        ip_header_s.ip_src = inet_addr(rcsSrcAddress);
        ip_header_s.ip_dst = inet_addr(rcsDestAddress);        
        ip_header_s.ip_sum = (uint16_t)(uiIPHeader_Checksum(&ip_header_s, sizeof(IP_HEADER)));   

        //UDP Header
        UDP_HEADER udp_header_s; 
        udp_header_s.srcPort = ulSrcPort;
        udp_header_s.dstPort = ulDestPort;
        udp_header_s.length =  (uint16_t)(ulNofBytes + sizeof(UDP_HEADER));

        if (eProtocolType == E_UDP) {
            //UDP Header
            UDP_HEADER udp_header_s;
            udp_header_s.srcPort = ulSrcPort;
            udp_header_s.dstPort = ulDestPort;
            udp_header_s.length = (uint16_t)(ulNofBytes + sizeof(UDP_HEADER));

            //  wiresharkPkt = pcap_pkt_header_s + ethernet_header_s + ip_header_s + udp_header_s + pucBytes ;
            WIRESHARK_UDP_PKT_HEADER wireshark_udp_pkt_header;
            wireshark_udp_pkt_header.pcap_pkt_header = pcap_pkt_header_s;
            wireshark_udp_pkt_header.l2l3UDP_header.ethernet_header = ethernet_header_s;
            wireshark_udp_pkt_header.l2l3UDP_header.ip_header = ip_header_s;
            wireshark_udp_pkt_header.l2l3UDP_header.udp_header = udp_header_s;

            fwrite(&pcap_global_header_s, sizeof(PCAP_GLOBAL_HEADER), 1, mpFile);
            fwrite(&wireshark_udp_pkt_header, sizeof(WIRESHARK_UDP_PKT_HEADER), 1, mpFile);
            fwrite(pucBytes, ulNofBytes, 1, mpFile);
        }
        else if (eProtocolType == E_TCP)
        {
            //TCP Header


        }

1 个答案:

答案 0 :(得分:0)

IP和UDP,与许多其他网络协议一样,都使用大端字节顺序。由于您可能在使用ip_header_s.ip_lenudp_header_s.length编写的little-endian机器值上运行此代码,因此不正确。您应该使用htons函数将短值从主机转换为网络字节顺序。

ip_header_s.ip_len = htons((uint16_t)(ulNofBytes + sizeof(UDP_HEADER) + sizeof(IP_HEADER)));

除了字节顺序之外,您还可以通过检查结构的实际大小并消除幻数来改进代码。你的代码也是用C语言编写的,你为什么要添加C ++标签?