2016-11-12 3 views
1

私はpcapライブラリを使ってCでパケットスニファを書いていましたが、私のパケットのいくつかが負のペイロード長を持っていることに気付きました。C - pcapライブラリを使用した負のペイロード長

IPとMAC​​とチェックサムとそのすべてが問題ないようですが、一部のパケット(すべてではない)が負のペイロードを持っているようです。

私はこのようにします:私は、パケットの開始点(u_char)を指すポインタを持っています。私はポインタを右に動かす(L2,3,4ヘッダを越えて)。このプロセスでは、ヘッダーも印刷します(送信元MAC、送信先MAC、送信元IPなど)。ヘッダーは整然としているように見えますが、なぜ私が負のペイロードを得るのか分かりません。

必要に応じて、コードを提供できます。

ありがとうございました!

void got_packet(u_char* args, struct pcap_pkthdr* hdr, const u_char* packet) { 

    FILE* f = fopen("/home/bogdan/C_Stuff/log.txt", "w+"); 
    static int packet_counter = 1; 
    printf("\n\n"); 
    printf("PACKET NUMBER %i\n", packet_counter); 

    int ethernet_header_length = 14; 
    int ip_header_length; 
    int tcp_header_length; 
    int payload_length; 

    const u_char* ip_header; 
    const u_char* tcp_header; 
    const u_char* payload; 

    ip_header = packet + ethernet_header_length; 

    /* The second part of the IP Header contains 
     the length of the IP Header */ 
    ip_header_length = ((*ip_header) & 0x0F); 
    ip_header_length = ip_header_length * 4;  

    printf("IP Header Length = %i\n", ip_header_length); 
    /* At the 10th byte we find info about TCP/UDP stuff */ 
    if(*(ip_header + 9) == IPPROTO_TCP) { 
     printf("TCP Packet\n"); 
    } 

    tcp_header = ip_header + ip_header_length; 
    tcp_header_length = ((*(tcp_header) + 12) & 0xF0) >> 4; 
    tcp_header_length *= 4; 
    printf("TCP Header Length = %i\n", tcp_header_length); 

    // Total header size 
    int total_header_size = ethernet_header_length + ip_header_length + tcp_header_length; 
    payload = packet + total_header_size; 
    payload_length = hdr->caplen - total_header_size; 
    printf("Payload Length = %i\n", payload_length); 

    if(payload_length > 0) { 
     int i; 
     printf("\n**************************************************"); 
     printf("\nPAYLOAD:\n"); 
     for(i = 0; i < payload_length; i++) { 
      printf("%i ", payload[i]); 
      if(i % 10 == 0) { 
       printf("\n"); 
      } 
     } 
     printf; 
     printf("\n"); 
    } 


    struct ether_header* eptr; 
    eptr = (struct ether_header*)packet;  

    if(ntohs(eptr->ether_type) == ETHERTYPE_IP) { 
     printf("IP PACKET\n"); 
    } else if(ntohs(eptr->ether_type) == ETHERTYPE_ARP) { 
     printf("ARP PACKET\n"); 
    } 

    struct ip* ip; 
     ip = (struct ip*)(packet + sizeof(struct ether_header)); 

    printf("Source MAC:  %02x:%02x:%02x:%02x:%02x:%02x\n", eptr->ether_shost[0], eptr->ether_shost[1], eptr->ether_shost[2], eptr->ether_shost[3], eptr->ether_shost[4], eptr->ether_shost[5]); 

    printf("Destination MAC: %02x:%02x:%02x:%02x:%02x:%02x\n", eptr->ether_dhost[0], eptr->ether_dhost[1], eptr->ether_dhost[2], eptr->ether_dhost[3], eptr->ether_dhost[4], eptr->ether_dhost[5]); 

    printf("Source IP: %s (IPv%i) | Total length = %i |\nTTL = %i | Checksum = %i\n", inet_ntoa(ip->ip_src), ip->ip_v, ip->ip_len, ip->ip_ttl, ip->ip_sum); 

    printf("Destination IP: %s (IPv%i) | Total length = %i |\nTTL= %i | Checksum = %i\n", inet_ntoa(ip->ip_dst), ip->ip_v, ip->ip_len, ip->ip_ttl, ip->ip_sum); 

    printf("\n====================================================\n"); 

    fprintf(f, "%s", inet_ntoa(ip->ip_dst)); 

    fflush(stdout); 
    packet_counter++; 

    fclose(f); 
} 

そして、ここでのサンプルのキャプチャである(すべてはペイロード長を除いて、大丈夫そうです):

PACKET NUMBER 9 IPヘッダ長= 20 TCPパケットのTCPヘッダ長= 52ペイロード長= -20 IPパケット送信元MAC:
24:0a:64:22:a2:39宛先MAC:78:d7:52:29:06:dbソースIP: 192.168.100.10(IPv4)|全長= 13312 | TTL = 64 |チェックサム= 11794宛先IP:216.58.209.165(IPv4)|全長= 13312 | TTL = 64 |チェックサム= 11794

+2

はいコードを入力してください! –

+0

もっと有用なのは、負のペイロード長を持つパケットの例です。 – user3386109

+0

私はコードをアップロードしました。また、負のペイロードを持つサンプルキャプチャされたパケットをアップロードしました。ありがとうございました! –

答えて

2

TCP Header Length = 52出力が奇妙に見えます。 TCPヘッダーは通常オプションなしであり、TCPヘッダーはオプションなしの20バイト長です。

私は長い間Cを書いていないので、確かに確信していませんが、おそらくtcp_header_length = ((*(tcp_header) + 12) & 0xF0) >> 4;が間違っています。あなたはコメントで指摘したように、常にキャプチャしたパケットの実際の長さを取得するためにhdr->lenの代わりhdr->caplenを使用する必要があり、

tcp_header_length = (*(tcp_header + 12) & 0xF0) >> 4; 

そして: それはする必要があります。

関連する問題