读取具有特定字节序的libcap文件

时间:2015-05-11 17:01:33

标签: c network-programming endianness tcpdump

我写了一个c-lang程序来读取一个.pcap文件。让我感到惊讶的是,我读到的数据与WireShark有不同的字节顺序。

我正在研究X86 ach,正如我所看到的,它是LittleEndian。

那么,我可以用BigEndian读取.pcap文件吗?怎么样?

代码片段:

/*
 * global header
 */
typedef struct{
    // fileds here
} GlobalHdr;

/*
 * record (packet) header
 */
typedef struct{
    // fileds here
} RecordHdr;

/*
 * IP v4 header
 */
typedef struct{
    // fileds here
    /* the options start here, if tot_len is bigger than 5*/
} Ipv4Hdr;

/*
 * UDP header
 */
typedef struct{
    // fileds here
} UdpHdr;


/*
 * main function
 */
int main(){
    FILE *srcfile = NULL; // the .pcap file
    GlobalHdr g_hdr = {0};
    RecordHdr r_hdr = {0};
    Ipv4Hdr ip_hdr = {0};
    UdpHdr u_hdr  = {0};
    unsigned long fl_len = 0;
    unsigned long index = 0;
    unsigned char sizghdr = sizeof(GlobalHdr);
    unsigned char sizrhdr = sizeof(RecordHdr);
    unsigned char sizihdr = sizeof(Ipv4Hdr);
    unsigned char sizuhdr = sizeof(UdpHdr);

    srcfile = fopen (SRC_FILE, "r");
    if(!srcfile){
        PERR ("source file opening");
    }

    fseek (srcfile, 0, SEEK_END);
    fl_len = ftell (srcfile);
    fseek (srcfile, 0, SEEK_SET);
    printf ("file length: %ld\n", fl_len);

    // read file global header

    CHECK_POSITION (sizghdr);
    if(!fread (&g_hdr, sizghdr, 1, srcfile)){
        PERR ("reading global header");
    }
    print_ghdr (&g_hdr);

    // read blocks

    while(1){
        // read block header
        CHECK_POSITION (sizrhdr);
        if(!fread (&r_hdr, sizrhdr, 1, srcfile)){
            PERR ("reading block header");
        }
        print_rhdr (&r_hdr);

        // read ethernet header
        CHECK_POSITION (LINK_LAYER_LEN);
        fseek (srcfile, index, SEEK_SET);

        // read IP header
        CHECK_POSITION (sizihdr);
        if(!fread (&ip_hdr, sizihdr, 1, srcfile)){
            PERR ("reading ip header");
        }
        print_iphdr (&ip_hdr);

        // read UDP header
        CHECK_POSITION (sizuhdr);
        if(!fread (&u_hdr, sizuhdr, 1, srcfile)){
            PERR ("reading upd header");
        }
        print_udphdr (&u_hdr);

        // read contained data
        CHECK_POSITION (r_hdr.orig_len - sizrhdr
                - LINK_LAYER_LEN - sizihdr - sizuhdr
                );
        fseek (srcfile, index, SEEK_SET);
    }

    // clean up

    puts ("Done!");
    CLEAN_UP;
    return 0;
}

1 个答案:

答案 0 :(得分:0)

  

那么,我可以用BigEndian读取.pcap文件吗?

  

如何?

  1. 使用libpcap / WinPcap,而不是编写自己的代码来读取它,因为libpcap / WinPcap会为你处理字节顺序问题;
  2. 查看幻数以确定文件是否与读取它的主机或字节顺序相反的字节顺序相同,如果是相反的字节顺序,则将字节交换为16位和32位积分数量。
  3. 请注意,数据包数据是(除了某些元数据标头,例如USB元数据),它按字节顺序显示在网络上,字节写入数据的主机的顺序。例如,IP和TCP标头中的16位和32位整数值始终大端,以太网类型字段也是如此。