Thread: Read data from a binary file using a pointer

  1. #16
    Registered User
    Join Date
    Feb 2013
    Location
    Sweden
    Posts
    171
    Thanks to all previous replies . I've proceeded with the assignment and can now read the payload package from the binary file called TCPdump ( My Files ).
    1. The first line of the TCPdump file is the size of the package in bytes.
    2. The package comes after that line.
    I've already fixed 1 and 2 above.

    What I've not fixied is reading all the sentences in the TCPdump file. I only
    read one sentence but if I open the TCPdump file I see that there serveral
    sentences that the program should be able to read. So I guess I need to
    use a pointer somehow to point to the other sentences also.

    Ethernet-|-IP------------ |-TCP-------------|-payload
    14 bytes-|-IP_HL bytes--|-TH_OFF bytes-| contents

    I'm reading the payload using a char pointer and then
    a while-loop like this:

    Programming with pcap
    Code:
    Payload (getPayload) | X + SIZE_ETHERNET + {IP header length} + {TCP header length}
    Code:
    
    

    Code:
            // getPayload is type struct *tcp_hdr
    Code:
    unsigned char *str = (unsigned char*)getPayload;
            // SIZE_BUFFER is 1000
        int k = 0;
        while (fgets(buffer, SIZE_BUFFER, file) != NULL) {
            printf("%s\n", str); 
            k++;
        }


    Output from while-loop:
    "
    I'm dreaming of a white Christmas"
    "I'm dreaming of a white Christmas"
    "I'm dreaming of a white Christmas"
    ...

  2. #17
    Registered User
    Join Date
    Feb 2013
    Location
    Sweden
    Posts
    171
    Thanks to all previous replies . I've proceeded with the assignment and can now read the payload package from the binary file called TCPdump ( My Files the code for main.c (Laboration3.c is the old file).
    1. The first line of the TCPdump file is the size of the package in bytes.
    2. The package comes after that line.
    I've already fixed 1 and 2 above.


    What I've not fixied is reading all the sentences in the TCPdump file. I only
    read one sentence but if I open the TCPdump file I see that there serveral
    sentences that the program should be able to read. So I guess I need to
    use a pointer somehow to point to the other sentences also.


    Ethernet-|-IP------------ |-TCP-------------|-payload
    14 bytes-|-IP_HL bytes--|-TH_OFF bytes-| contents


    I'm reading the payload using a char pointer and then
    a while-loop like this:


    Programming with pcap (I'm not actually using all of this, just a modified framehdr.h file.)
    Code:
    Payload (getPayload) | X + SIZE_ETHERNET + {IP header length} + {TCP header length}
    Code:
            // getPayload is type struct *tcp_hdr
    Code:
    unsigned char *str = (unsigned char*)getPayload;
            // SIZE_BUFFER is 1000
        int k = 0;
        while (fgets(buffer, SIZE_BUFFER, file) != NULL) {
            printf("%s\n", str); 
            k++;
        }

    Output from while-loop:
    "I'm dreaming of a white Christmas"
    "I'm dreaming of a white Christmas"
    "I'm dreaming of a white Christmas"
    ...
    Last edited by DecoratorFawn82; 12-15-2017 at 08:21 PM.

  3. #18
    Registered User
    Join Date
    May 2010
    Posts
    4,633
    Please post your code, inside code tags, within a post.

    Your .c file.
    Code:
    #include <stdio.h>
    #include "framehdr.h"
    
    #define SIZE_ETHERNET 14
    
    int main() {
    	
    	FILE *file = fopen("TCPdump", "rb");
    	
    	if (file == NULL)
    		printf("Error");
    	
    	printf("--- Ethernet ---\t");
    	printf("--- IP ---");
    	printf("\t\t--- TCP ---\n");
    	
    	// Why doesn't this work?
    	struct ethernet_hdr* getEthernet;	
    	fread((struct ethernet_hdr*)&getEthernet, sizeof(struct ethernet_hdr), 1, file);
    	printf("\ndhost: %s", getEthernet->dhost);
    	printf("shost: %s", getEthernet->shost);
    
    	struct ip_hdr getIP;
    	fread((struct ip_hdr*)&getIP, sizeof(struct ip_hdr), 1, file); 
    	
    	struct tcp_hdr getTCP;
    	fread((struct tcp_hdr*)&getTCP, sizeof(struct tcp_hdr), 1, file); 
    	
    	printf("\t\t  vhl: %c", getIP.vhl);				//printf("\t\t  th_sport: %hd", getTCP.th_sport);
    	printf("\n\t\t\t tos: %c", getIP.tos); 			//printf("\t\t th_dport: %hd", getTCP.th_sport);
    	printf("\n\t\t\t len: %hd", getIP.len);			//printf("\t\t\tth_seq:   %d", getTCP.th_sport);
    	printf("\n\t\t\t id: %hd", getIP.id);		    printf("\t\t\tth_ack:   %d", getTCP.ack);
    	printf("\n\t\t\t off: %hd", getIP.off);			printf("\t\tth_offx2: %c", getTCP.offx2);
    	printf("\n\t\t\t ttl: %c", getIP.ttl);			printf("\t\t\tth_flags: %c", getTCP.flags);
    	printf("\n\t\t\t p: %c", getIP.p);				printf("\t\t\tth_win:   %hd", getTCP.win);
    	printf("\n\t\t\t ip_sum: %hd", getIP.ip_sum);	printf("\t\tth_sum:   %hd", getTCP.sum);
    	printf("\n\t\t\t src: %d", getIP.src);			printf("\tth_urp:   %hd", getTCP.urp);
    	printf("\n\t\t\t dst: %d", getIP.dst);			
    	fclose(file);
    	
    	return 0;
    }
    Where are you allocating memory for getEthernet?

    Do you actually need the pointer, can't you just use a "normal" non-pointer instance like you did with your ip_hdr instance?


    Code:
    	FILE *file = fopen("TCPdump", "rb");
    	
    	if (file == NULL)
    		printf("Error");
    Why are you continuing with the program if the file doesn't open?

  4. #19
    Registered User
    Join Date
    Feb 2013
    Location
    Sweden
    Posts
    171
    Notice that this now is the correct and modified file.
    So I need help to print every sentence in the file (TCPdump) and not
    just the first one ("I'm dreaming of a white Christmas").

    Download the TCPdump file and code (postedCode.c) from
    TCPdump and postedCode (You will also need framehdr to run the program)
    Sorry, about not posting the code, but here it is.

    Link to the whole folder with all files:
    My Files
    Last edited by DecoratorFawn82; 12-16-2017 at 12:29 PM.

  5. #20
    Registered User
    Join Date
    May 2010
    Posts
    4,633
    Sorry, about not posting the code, but here it is.
    Where is it? Post the code in a post, not in some random link!

  6. #21
    Registered User
    Join Date
    Feb 2013
    Location
    Sweden
    Posts
    171
    Code:
    #include <stdio.h>
    #include <stdlib.h>
    #include "framehdr.h"
    
    
    #define SIZE_ETHERNET 14
    #define SIZE_BUFFER 1000
    
    
    int main() {
            
        char buffer[SIZE_BUFFER];
        FILE *file = fopen("TCPdump", "rb");
        
        // Get total length of package in bytes
        int totLenPkg; 
        fscanf(file, "%d", &totLenPkg);
        printf("Total length of package: %d", totLenPkg);
        
        // Read the package only
        fgets(buffer, SIZE_BUFFER, file);
        
        if (file == NULL) {
            printf("Error");
            exit(1);    
        }
            
        void* packet = malloc(totLenPkg);
        
        printf("\n\n");
        printf("--- Ethernet ---\t");
        printf("--- IP ---");
        printf("\t\t--- TCP ---\n");
    
    
        // Convert void* pointer to ethernet_hdr* pointer
        struct ethernet_hdr* getEthernet = (struct ethernet_hdr*)packet;
        fread(packet, totLenPkg, 1, file);
    
    
        // Convert void* pointer to ip_hdr* pointer and get IP-package
        struct ip_hdr *getIP = (struct ip_hdr*)(packet + SIZE_ETHERNET);
         
        unsigned char *srcAdress = (unsigned char*)&getIP->src;
        unsigned char *dstAdress = (unsigned char*)&getIP->dst;
            
        // Size of IP
        int sizeIP = IP_HL(getIP);
        printf("\nsizeIP: %d\n", sizeIP);
        
        // The source adress
        printf("\nsrc: ");
        int i; 
        for (i = 0; i < 4; i++) {
            printf("%d.", srcAdress[i]);
        }
        
        // The destination adress
        printf("\ndst: ");
        int j;
        for (j = 0; j < 4; j++) {
            printf("%d.", dstAdress[j]);
        }
        
        // TCP-package
        struct tcp_hdr* getTCP = (struct tcp_hdr*)(packet + SIZE_ETHERNET + sizeIP);
        
        int sizeTCP = TH_OFF(getTCP);
        printf("\nsizeTCP: %d", sizeTCP);
        
        // Payload-package
        struct tcp_hdr* getPayload = (struct tcp_hdr*)(packet + SIZE_ETHERNET + sizeIP + sizeTCP);
        
        unsigned char *str = (unsigned char*)getPayload;
        
        printf("\n");
    
    
        int k = 0;
        int size = ftell(file);
        printf("\nftell: %d\n", size);
        while (fgets(buffer, SIZE_BUFFER, file) != NULL) {
            printf("\nftell: %d\n", size);
            printf("%s\n", str);
            
            if (*buffer == '\n') { // *buffer == '\n' fgets(buffer, SIZE_BUFFER, file) == '\0'
                size = ftell(file);
                fseek(file, size, SEEK_CUR);
                printf("SEEK_CUR: %d", SEEK_CUR);
                
                printf("\nftell: %d\n", size);
                //*str += size;
            }
            
            /*
            if (fgets(buffer, SIZE_BUFFER, file) == NULL) {
                fseek(file, 123*sizeof(char*), SEEK_CUR);
            }*/
            k++;
        }
        
        /*fseek(file, sizeof(char*), SEEK_CUR);
        
        int h = 0;
        while (fgets(buffer, SIZE_BUFFER, file) != NULL) {
            printf("%s\n", str);
            h++;
        }*/
        
        free(packet);
        fclose(file);
        
        return 0;
    }
    framehdr.h
    Code:
    /*
    * Credit to Tim Carstens for the contents of this file
    * http://www.tcpdump.org/pcap.html
    */
    
    
    #ifndef FRAMEHDR_H
    #define FRAMEHDR_H
    
    
    /* Ethernet addresses are 6 bytes */
    #define ETHER_ADDR_LEN   6
    
    
    /* Ethernet header */
    struct ethernet_hdr {
    	unsigned char  dhost[ETHER_ADDR_LEN];  /* Destination host address */
    	unsigned char  shost[ETHER_ADDR_LEN];  /* Source host address */
    	unsigned short type;                   /* IP? ARP? RARP? etc */
    };
    
    
    /* IP header */
    struct ip_hdr {
    	unsigned char vhl;            /* Version and header length */
    	unsigned char tos;            /* Type of service */
    	unsigned short len;           /* Total length */
    	unsigned short id;            /* Identification */
    	unsigned short off;           /* Fragment offset field */
    	unsigned char ttl;            /* Time to live */
    	unsigned char p;              /* Protocol */
    	unsigned short ip_sum;        /* Checksum */
    	unsigned int src, dst;         /* Source and dest address */
    };
    #define IP_HL(ip)      ((((ip)->vhl) & 0x0f) * 4)  /* Gets length of the IP header, use with (ip_hdr *) */
    
    
    /* TCP header */
    typedef unsigned int tcp_seq;
    
    
    struct tcp_hdr {
    	unsigned short sport;   /* Source port */
    	unsigned short dport;   /* Destination port */
    	tcp_seq seq;            /* Sequence number */
    	tcp_seq ack;            /* Acknowledgement number */
    	unsigned char offx2;    /* Data offset, rsvd */
    
    
    	unsigned char flags;
    	unsigned short win;      /* Window */
    	unsigned short sum;      /* Checksum */
    	unsigned short urp;      /* Urgent pointer */
    };
    #define TH_OFF(th)   ((((th)->offx2 & 0xf0) >> 4) * 4)	/* Gets length of the TCP header, use with (tcp_hdr *) */
    #endif

  7. #22
    Banned
    Join Date
    Aug 2017
    Posts
    861
    I do not know what your dumpfile looks like inside of it but make this chagnce to see what you're getting. you where trying to print out str when it has nothing in it.
    Code:
    printf("\nftell: %d\n", size); 
         
        rewind(file); 
         
        while (fgets(buffer, SIZE_BUFFER, file) != NULL)  
        { 
            puts(buffer); 
              
            
             
           // printf("%s\n",str); 
              
            printf("\nftell: %ld\n", ftell(file)); 
             /* 
            if (buffer == '\n') { // *buffer == '\n' fgets(buffer, SIZE_BUFFER, file) == '\0' 
                size = ftell(file); 
                fseek(file, size, SEEK_CUR); 
                printf("SEEK_CUR: %d", SEEK_CUR); 
                  
                printf("\nftell: %d\n", size); 
                //*str += size; 
            } 
            */ 
              
            /* 
            if (fgets(buffer, SIZE_BUFFER, file) == NULL) { 
                fseek(file, 123*sizeof(char*), SEEK_CUR); 
            }*/ 
        //    k++; 
        }

  8. #23
    Registered User
    Join Date
    Feb 2013
    Location
    Sweden
    Posts
    171
    I have the TCPdump file uploaded to this link so that you can see it.
    TCPdump

    Notice that the first line of the file is the size of the package in bytes!
    The package comes thereafter.

    So I guess we can't use rewind() since it goes to the beginning of the file,
    right? Since the package begins at the second line of the file.

    So I tried doing:
    Code:
    
        int k; 
        while (fgets(buffer, SIZE_BUFFER, file) != NULL) {
            
            //if (fgets(buffer, SIZE_BUFFER, file))
                //fgets(buffer, SIZE_BUFFER, file);
                printf("%s\n", buffer);
            k++;
        }
    But it is not only printing the sentences (strings).
    It is also printing some data that I don't want it to
    print. I tried your version and it did something
    similar.

  9. #24
    Registered User
    Join Date
    May 2010
    Posts
    4,633
    You opened the file in binary mode so you should probably be reading the file with read() for everything.

    By the way:

    Code:
        FILE *file = fopen("TCPdump", "rb");
         
        // Get total length of package in bytes
        int totLenPkg; 
        fscanf(file, "%d", &totLenPkg);
        printf("Total length of package: %d", totLenPkg);
         
        // Read the package only
        fgets(buffer, SIZE_BUFFER, file);
         
        if (file == NULL) {
            printf("Error");
            exit(1);    
        }
    You're doing the check of the file too late, you need to do this check before you try first to use the FILE pointer not after.

  10. #25
    Banned
    Join Date
    Aug 2017
    Posts
    861
    Quote Originally Posted by DecoratorFawn82 View Post
    I have the TCPdump file uploaded to this link so that you can see it.
    TCPdump

    Notice that the first line of the file is the size of the package in bytes!
    The package comes thereafter.

    So I guess we can't use rewind() since it goes to the beginning of the file,
    right? Since the package begins at the second line of the file.

    So I tried doing:
    Code:
    
        int k; 
        while (fgets(buffer, SIZE_BUFFER, file) != NULL) {
            
            //if (fgets(buffer, SIZE_BUFFER, file))
                //fgets(buffer, SIZE_BUFFER, file);
                printf("%s\n", buffer);
            k++;
        }
    But it is not only printing the sentences (strings).
    It is also printing some data that I don't want it to
    print. I tried your version and it did something
    similar.
    yeah, and I am getting major warnings for your pointers , and what is the k++ for???
    just take out the rewind, I was fiddling with it and forgot that one.
    Last edited by userxbw; 12-16-2017 at 02:53 PM.

  11. #26
    Lurking whiteflags's Avatar
    Join Date
    Apr 2006
    Location
    United States
    Posts
    9,613
    Part of the problem is that there are multiple packets in this file. Each packet seems to be one line of the song. So you will have to loop the packet reading part, not necessarily whatever this is supposed to be
    Code:
    int k; 
    
    while (fgets(buffer, SIZE_BUFFER, file) != NULL) {
    
         
    
        //if (fgets(buffer, SIZE_BUFFER, file))
    
            //fgets(buffer, SIZE_BUFFER, file);
    
            printf("%s\n", buffer);
    
        k++;
    
    }
    @OP: Actually it looks like you called them TCP packages, but that is what I mean... you need to read multiple packages to get the whole song. Just to be clear.
    Last edited by whiteflags; 12-16-2017 at 02:50 PM.

  12. #27
    Registered User
    Join Date
    Feb 2013
    Location
    Sweden
    Posts
    171
    whiteflags - Yes, that is what I need to do but don't know how to do that.
    Which part do you mean as "loop the packet reading part"? Don't I also
    need the size for the packages somehow to be able to read them correctly?

  13. #28
    Banned
    Join Date
    Aug 2017
    Posts
    861
    you need to know what you're looking for in the order you're looking for it so you can scan it in the same order using the proper data types to get it.
    or using delimiter strtok to find key words then get what you need.

    EDIT: is that a read tcp dump file?

    Code:
    userx@slackwhere:~/bin
    $ tcpdump -qns 0 -X -r  TCPdump
    tcpdump: unknown file format
    userx@slackwhere:~/bin
    $ tcpdump -qns 0 -A -r  TCPdump
    tcpdump: unknown file format
    
    
    userx@slackwhere:~/bin
    $ cat TCPdump
    100
    hE}@@FT/$#P*Dе
                                           
     xVI'm dreaming of a white Christmas
    100
    hENs7#/$PDе*ŀE
    xV Just like the ones I used to know
    94
    hE}_@@8/$#P*Vzʔ
    !yߚWhere the tree tops glisten
    86
    hENl7#/$PԣVzs
    ߚ*!yAnd children listen
    99
    2hE}@@t$/$#P..vI
    "uLfTo hear sleigh bells in the snow
    100
    ..hN;7#/$P՚I
    Lf"uI'm dreaming of a white Christmas
    100
    hE}@@FT/$#P*Dе
                                           
     xVWith every Christmas card I write
    100
    hE}@@FT/$#P*Dе
                                           
     xVMay your days be merry and bright
    78
    hENs7#/$PDе*ŀE
    xV And may all
    92
    hE}_@@8/$#P*Vzʔ
    !yߚYour Christmases be white
    Last edited by userxbw; 12-16-2017 at 03:39 PM.

  14. #29
    Lurking whiteflags's Avatar
    Join Date
    Apr 2006
    Location
    United States
    Posts
    9,613
    Quote Originally Posted by DecoratorFawn82 View Post
    whiteflags - Yes, that is what I need to do but don't know how to do that.
    Which part do you mean as "loop the packet reading part"? Don't I also
    need the size for the packages somehow to be able to read them correctly?
    In general, the answers to your question are all yes.

    Have you looked at your file in a hex editor, or a good text editor? There is a package length before each actual package. Since you figured out how to read one package in this part:
    Code:
        // Get total length of package in bytes
        int totLenPkg; 
        fscanf(file, "%d", &totLenPkg);
        printf("Total length of package: %d", totLenPkg);
         
        // Read the package only
        //fgets(buffer, SIZE_BUFFER, file);
         
        if (file == NULL) {
            printf("Error");
            exit(1);    
        }
             
        void* packet = malloc(totLenPkg);
         
        printf("\n\n");
        printf("--- Ethernet ---\t");
        printf("--- IP ---");
        printf("\t\t--- TCP ---\n");
     
     
        // Convert void* pointer to ethernet_hdr* pointer
        struct ethernet_hdr* getEthernet = (struct ethernet_hdr*)packet;
        fread(packet, totLenPkg, 1, file);
     
     
        // Convert void* pointer to ip_hdr* pointer and get IP-package
        struct ip_hdr *getIP = (struct ip_hdr*)(packet + SIZE_ETHERNET);
          
        unsigned char *srcAdress = (unsigned char*)&getIP->src;
        unsigned char *dstAdress = (unsigned char*)&getIP->dst;
             
        // Size of IP
        int sizeIP = IP_HL(getIP);
        printf("\nsizeIP: %d\n", sizeIP);
         
        // The source adress
        printf("\nsrc: ");
        int i; 
        for (i = 0; i < 4; i++) {
            printf("%d.", srcAdress[i]);
        }
         
        // The destination adress
        printf("\ndst: ");
        int j;
        for (j = 0; j < 4; j++) {
            printf("%d.", dstAdress[j]);
        }
         
        // TCP-package
        struct tcp_hdr* getTCP = (struct tcp_hdr*)(packet + SIZE_ETHERNET + sizeIP);
         
        int sizeTCP = TH_OFF(getTCP);
        printf("\nsizeTCP: %d", sizeTCP);
         
        // Payload-package
        struct tcp_hdr* getPayload = (struct tcp_hdr*)(packet + SIZE_ETHERNET + sizeIP + sizeTCP);
         
        unsigned char *str = (unsigned char*)getPayload;
         
        printf("\n");
    It is just a matter of repeating this enough times to get the whole song. There are lots of ways to achieve that, like looping until a read function fails. So, check the return values of fscanf and fread.

    I could be wrong but think the payload in the packet is the song lyric, by the way, so fgets() should be unnecessary.
    Last edited by whiteflags; 12-16-2017 at 03:49 PM.

  15. #30
    Banned
    Join Date
    Aug 2017
    Posts
    861
    Linux tcp dump file.
    Code:
    $ sudo tcpdump -c 3  -w dumpTCP -i wlan0
    tcpdump: listening on wlan0, link-type EN10MB (Ethernet), capture size 262144 bytes
    3 packets captured
    272 packets received by filter
    0 packets dropped by kernel
    userx@slackwhere:~
    $ tcpdump -qns 0 -X -r dumpTCP
    reading from file dumpTCP, link-type EN10MB (Ethernet)
    15:44:14.805120 IP 146.199.108.87.45406 > 172.31.99.123.51648: UDP, length 1422
        0x0000:  4500 05aa 2071 0000 6b11 1b19 92c7 6c57  E....q..k.....lW
        0x0010:  ac1f 637b b15e c9c0 0596 c587 0100 584c  ..c{.^........XL
        0x0020:  0a3c 33d4 555e 58b6 0000 c350 2ffa 66a5  .<3.U^X....P/.f.
        0x0030:  0a38 9965 02d9 bade 6450 6562 1c15 1b85  .8.e....dPeb....
        0x0040:  a4ef 6c46 ca84 4fe2 ff03 0e59 0c55 8786  ..lF..O....Y.U..
        0x0050:  6d0a 2b16 a0ec 8d81 ac79 957b 8827 605e  m.+......y.{.'`^
        0x0060:  fca8 e308 219d 9fe6 273c b1ce 84c4 b2aa  ....!...'<......
        0x0070:  7b33 b252 1ba6 181d 40d5 ddc0 5781 36d2  {[email protected].
        0x0080:  7873 8379 fb73 d85b 5078 e4dc c166 7c35  xs.y.s.[Px...f|5
    
    chopped off by me
    so I suppose you're suppose to be looking at something like that but it is formatted output by tcpdump program in Linux.

    this being "raw data"
    Code:
    cat dumpTCP
    ò“5Z9BB$ždrXE(4‡@+%|c{n‘ZŽ€L\
    .Š0J‚“5Z9drX@$žEQ@@10c{%|nŽ8‘Z€cOD
    0K.ŠN™OҹT‰9‡|"a4ӷ‡z~D“J#7Q.…
    ‰N5>+D75Šp^͸%˜<@+š@QC~~yo‡#+ʻ!…‰20p#x....)m=..,-
    Last edited by userxbw; 12-16-2017 at 03:53 PM.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Replies: 1
    Last Post: 04-09-2017, 01:24 AM
  2. Read data from binary file with condition
    By tawawogita in forum C Programming
    Replies: 11
    Last Post: 06-01-2015, 03:25 PM
  3. Replies: 4
    Last Post: 12-07-2013, 04:33 PM
  4. Replies: 6
    Last Post: 12-06-2013, 11:39 PM
  5. Replies: 21
    Last Post: 11-03-2007, 02:56 PM

Tags for this Thread