2016-07-13 133 views
-2

我发布了主函数,struct头是正常的。运行这个程序后,它经常停在某个数据包,不同的数据包停在不同的位置,但某个pcap总是停在某个位置。它打印“pcap文件的读取结束”,我不确定某个指针是否有错。一个简单的C程序来分析pcap文件,但它不能读取整个pcap文件

int main() 
{ 
    struct pcap_file_header *file_header; 
    struct pcap_pkthdr *ptk_header; 
    IPHeader_t *ip_header; 
    TCPHeader_t *tcp_header; 
    FILE *fp, *output,*testfile; 
    int i=0; 
    long pkt_offset; 
    long testtime; 
    int ip_len, http_len, ip_proto; 
    int src_port, dst_port, tcp_flags; 
    char buf[BUFSIZE], my_time[20],my_time1[20],my_time2[10]; 
    char src_ip[STRSIZE], dst_ip[STRSIZE]; 
    char host[STRSIZE], uri[BUFSIZE]; 
    file_header = (struct pcap_file_header *)malloc(sizeof(struct pcap_file_header)); 
    ptk_header = (struct pcap_pkthdr *)malloc(sizeof(struct pcap_pkthdr)); 
    ip_header = (IPHeader_t *)malloc(sizeof(IPHeader_t)); 
    tcp_header = (TCPHeader_t *)malloc(sizeof(TCPHeader_t)); 
    memset(buf, 0, sizeof(buf)); 

    if((fp = fopen("f:\\1.pcap","r")) == NULL) 
    { 
     printf("error: can not open pcap file\n"); 
     exit(0); 
    } 
    if((output = fopen("output.txt","w+")) == NULL) 
    { 
     printf("error: can not open output file\n"); 
     exit(0); 
    } 
    if((testfile = fopen("test.txt","w+")) == NULL) 
    { 
     printf("error: can not open test file\n"); 
     exit(0); 
    } 

    pkt_offset = 24; //pcap head 
    while(fseek(fp, pkt_offset, SEEK_SET) == 0) 
    { 
     i++; 
     //pcap_pkt_header 16 byte 
     if(fread(ptk_header, 16, 1, fp) == 0) //read pcap packet head 
     { 
      fprintf(testfile,"%d-%ld-",i,pkt_offset); 
      fprintf(testfile,"\nread end of pcap file\n"); 
      break; 
     } 
     pkt_offset += 16 + ptk_header->caplen; 
     fprintf(testfile,"%d-%ld-",i,pkt_offset); 
     fprintf(testfile,"%ld",ptk_header->caplen); 
     fprintf(testfile,"\n"); 

     //extract timestamp 
     itoa(ptk_header->ts.tv_sec,my_time,10); 
     itoa(ptk_header->ts.tv_usec,my_time1,10); 
     strcat(my_time,"."); 
     strncpy(my_time2,my_time1,4); 
     my_time2[4] = '\0'; 
     strcat(my_time,my_time2); 
     printf("%d: %s\n", i, my_time); 
     fwrite(&my_time[0],16,1,output); 
     fprintf(output,"\n"); 
    } // end while 
    fclose(fp); 
    fclose(output); 
    fclose(testfile); 
    return 0; 
} 
+1

使用'的fopen(..., “RB”)'(b代表二进制)。 –

+1

无关(1)[不要投出malloc结果](http://stackoverflow.com/questions/605845/do-i-cast-the-result-of-malloc)(2)免费你malloc(3)你不需要*动态分配所有这些头文件,自动变量将会很好。 –

+0

确实。 ''rb''中的'b'可能会阻止CRLF转换为LF,这将消除对'fseek'的需求。这里的'fseek'看起来像一个肮脏的黑客,以达到与'b'相同的结果,除了它不能解决整个问题并掩盖它不能解决的部分。您是否注意到您的程序正在丢失\ n字符? – Sebivor

回答

-1

您使用在同一回路中的fread沿fseek。每次调用fread时,文件指针都会增加读取的值。您也不需要调用fseek来设置文件指针。

更改while循环这样

while(fread(ptk_header, 16, 1, fp) > 0) //read pcap packet head 
{ 
    i++; 
    //pcap_pkt_header 16 byte 
    pkt_offset += 16 + ptk_header->caplen; 
    fprintf(testfile,"%d-%ld-",i,pkt_offset); 
    fprintf(testfile,"%ld",ptk_header->caplen); 
    fprintf(testfile,"\n"); 

    // further code below 
} 
+0

您确实需要'fseek'来跳过此代码所执行的部分文件。 – interjay

+0

OP说'我不确定某个指针是否有错。'所以我猜他不想读取16个字节,然后跳过16个字节。 –

+0

他跳过超过16个字节的代码显示,读取数据包标头并跳过数据包内容。 – interjay