2017-05-10 7 views
-1

libpcapライブラリを使用せずにpcapファイルをC++で作成しています。パケット構造は正しい。しかし、私は、IPパケットの長さが間違っていることを知り、残りのプロトコルは表示されません。添付された 'pcap file error image'ファイルにエラーが表示されます。私はlibpcap format wiresharkなどを検索しました...しかし、私は私の問題の解決策を見ません。ここでpcapファイルのIPパケットの長さが正しくない

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 


     } 

答えて

0

どちらもIPやUDP、同じように他の多くのネットワークプロトコル、ビッグエンディアンバイト順を使用しています。そして、おそらくこのコードをip_header_s.ip_lenudp_header_s.lengthで書かれたリトルエンディアンのマシン値で実行すると間違っています。短い値をホストからネットワークバイトオーダに変換するには、htons関数を使用する必要があります。

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

別にバイト順から、あなたは、構造体の実際の大きさをチェックし、マジックナンバーを取り払うことで、あなたのコードを向上させることができます。また、あなたのコードは完全にCで書かれています、なぜあなたはC++タグを追加しましたか?

+0

ありがとうございます。私はそれを動作させるためにntohsを使用しなければならなかったが!!タグについては、プログラムで使用しているクラスなどを省略して貼り付けただけです。デザインはもともとC++で書かれていますが、ここでは重要ではありません:) – AswathyPrasad

関連する問題