0

I wrote a c-lang program to read a .pcap file.What fogs me is that the data I read was with a different endianness as to WireShark.

I'm working on X86 ach, as I can see, it's LittleEndian.

So, can I read the .pcap file with BigEndian? How?

Code fragments:

/*
 * 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;
}
Galaxy
  • 1,129
  • 11
  • 27

1 Answers1

0

So, can I read the .pcap file with BigEndian?

Yes.

How?

  1. use libpcap/WinPcap, rather than writing your own code to read it, as libpcap/WinPcap handles byte-order issues for you;
  2. look at the magic number to determine whether the file is in the same byte order as the host reading it or the opposite byte order and, if it's in the opposite byte order, byte-swap the 16-bit and 32-bit integral quantities.

Note that the packet data is (except for some metadata headers, such as USB metadata) in the byte order in which it appears on the network, not the byte order of the host writing the data. For example, 16-bit and 32-bit integral values in IP and TCP headers are always big-endian, as is the Ethernet type field.

  • It seems that all network data captureed into a file is as the endianness they used to be on the network, e.i. BigEndian. Right? – Galaxy May 12 '15 at 02:01
  • Wrong. In, for example, Microsoft's SMB protocol, most multi-byte integer data fields are little-endian, *even though, for SMB-over-TCP, the multi-byte integer data fields in the IP and TCP headers are big-endian*. Some protocols, such as DCE RPC/MS-RPC and X11, use different endiannesses depending on the endianness of the machine at one of the endpoints. So the endianness is protocol-dependent (and a given packet with multiple protocol layers can have *multiple* endiannesses in different layers). –  May 12 '15 at 06:15