2016-07-13 8 views
-2

Я отправляю основную функцию, заголовок структуры является нормальным. После запуска этой программы она часто останавливается на каком-то пакете, разные пакеты останавливаются в разных положениях, но определенный pcap всегда останавливается в определенной позиции. Он печатает «read end pcap file», я не уверен, что какой-то указатель ошибочен.Простая программа 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 (..., "гь")' (б для бинарного). –

+1

Несвязанный (1) [не набирать результат malloc] (http://stackoverflow.com/questions/605845/do-i-cast-the-result-of-malloc) (2) бесплатно, что вы malloc (3) вам не нужно * динамически выделять все эти заголовки, автоматические переменные будут делать все отлично. –

+0

Действительно. 'B' в' 'rb" ', вероятно, предотвратит перевод CRLF в LF, что избавит от необходимости использовать' fseek'. «Fseek» здесь кажется грязным взломом для достижения того же результата, что и «b», за исключением того, что он не решает всю проблему и маскирует ту часть, которую она не решает. Вы заметили, что ваша программа теряла символы '\ n'? – Sebivor

ответ

-1

Вы используете fseek вместе с fread в том же цикле. Каждый раз, когда вы вызываете fread, указатель файла увеличивается на считанное значение. Вам также не нужно вызывать fseek, чтобы установить указатель файла.

Изменения во время цикла, как этого

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