2016-11-12 58 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); 
} 

这里是一个样本捕获(一切似乎好,除了有效载荷长度):

分组编号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 | Checksum = 11794

+2

是提供代码请! –

+0

更有用的将是一个有负载长度的数据包的例子。 – user3386109

+0

我已经上传了代码。另外,我已经上传了带有负载的样本采集包。谢谢! –

回答

2

TCP Header Length = 52你的输出对我来说很奇怪。 TCP标头通常没有选项,TCP标头长度为20字节,没有选项。

我没有写C持续很长一段时间,所以我真的不知道,但可能tcp_header_length = ((*(tcp_header) + 12) & 0xF0) >> 4;是错误的。 它应该是:

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

而且,你应该使用hdr->len,而不是hdr->caplen总是得到一个捕获数据包的实际长度为评论指出。