Thread: Read data from a binary file using a pointer

  1. #31
    Lurking whiteflags's Avatar
    Join Date
    Apr 2006
    Location
    United States
    Posts
    9,616
    Yeah the whole point is that you can see there are multiple packages in the file if you just look at it in another program.

  2. #32
    Banned
    Join Date
    Aug 2017
    Posts
    861
    from that other program I used it is not a valid tcpdump file, and still if binary one still needs to know what order to get the information. Yes/?/
    Last edited by userxbw; 12-16-2017 at 04:03 PM.

  3. #33
    Lurking whiteflags's Avatar
    Join Date
    Apr 2006
    Location
    United States
    Posts
    9,616
    I don't know if it's a valid anything. I don't even really want to argue if it is or isn't valid. I just want to point out what I saw.

    I'll attach a picture since it's really the best that I can do.

    Read data from a binary file using a pointer-capture-jpg

    I think just seeing this, you can see what the OP is trying to do with the code he has, and it is sort of working. It's just not one big packet... it's one packet per song lyric.

  4. #34
    Banned
    Join Date
    Aug 2017
    Posts
    861
    yeah just a bunch of "raw data" and text. I thought I was doing something wrong until I cat the file. Normally one could do something like this.but WE have no real idea of the format in the file

    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"); 
      
        //Notes 
        /* 
         *    IP header  
            struct ip_hdr { 
                unsigned char vhl;             
                unsigned char tos;            
                unsigned short len;             
                unsigned short id;            
                unsigned short off;             
                unsigned char ttl;              
                unsigned char p;              
                unsigned short ip_sum;         
                unsigned int src, dst;          
            }; 
            */ 
        struct ip_hdr getPayload; 
       while (  fread(&getPayload, sizeof(getPayload),10, file) == 10  ) 
        { 
     
             
             
            printf("\n%c %c %hu %hu %hu %c %c %hu %d %d\n",  
            getPayload.vhl, getPayload.tos, getPayload.len, getPayload.id, 
             getPayload.off, getPayload.ttl, getPayload.p, getPayload.ip_sum,getPayload.src,getPayload.dst); 
        } 
        free(packet); 
        fclose(file); 
          
        return 0; 
    }
    output
    Code:
    userx@slackwhere:~/bin
    $ ./Laboration3
    Total length of package: 100
    
    --- Ethernet ---    --- IP ---        --- TCP ---
    
    sizeIP: 20
    
    src: 194.47.143.36.
    dst: 172.217.17.35.
    
    
     1 12336 32778 62086 h  177 285203216 1157629952
    
    e n 2560 13880 32778 †  57448 -619708239 134222079
    
    
     € 62086 57448 177   4351 1157629952 -330432000
    
    w r 29801 101 12554 0 0 10 285203216 -226066432
    that is just using the one other struct he has, so I have no idea what to grab and when to grab it and when to change it to another struct to get that filled. and why pointers?

    Code:
    Laboration3.c:45:52: warning: pointer of type 'void *' used in arithmetic [-Wpointer-arith]
         struct ip_hdr *getIP = (struct ip_hdr*)(packet + SIZE_ETHERNET);
    the struct and names used may have been changed to protect the innocent.
    Last edited by userxbw; 12-16-2017 at 04:29 PM.

  5. #35
    Lurking whiteflags's Avatar
    Join Date
    Apr 2006
    Location
    United States
    Posts
    9,616
    Just saying, it may be awkward, but I think the pointer arithmetic you commented out is important. Besides, after that the song lyric should be in str. Maybe!
    Last edited by whiteflags; 12-16-2017 at 04:30 PM.

  6. #36
    Registered User
    Join Date
    Dec 2017
    Posts
    1,068
    The structure of the file is given by the OPs program. Here's a look at the first part of the data:
    Code:
    00000000  31 30 30 0a 00 10 db ff  10 00 80 86 f2 68 e0 b1  |100..........h..|
    00000010  08 00 45 00 00 7d e4 d6  40 00 40 06 46 54 c2 2f  |..E..}..@.@.FT./|
    00000020  8f 24 ac d9 11 23 8d d3  00 50 07 2a c4 ce 44 b3  |.$...#...P.*..D.|
    00000030  d0 b5 80 18 00 e5 0c 98  00 00 01 01 08 0a 06 ed  |................|
    00000040  20 1e 84 78 56 d9 49 27  6d 20 64 72 65 61 6d 69  | ..xV.I'm dreami|
    00000050  6e 67 20 6f 66 20 61 20  77 68 69 74 65 20 43 68  |ng of a white Ch|
    00000060  72 69 73 74 6d 61 73 00  0a 31 30 30 0a 80 86 f2  |ristmas..100....|
    00000070  68 e0 b1 00 10 db ff 10  00 08 00 45 00 02 4e 8e  |h..........E..N.|
    00000080  73 00 00 37 06 e3 e6 ac  d9 11 23 c2 2f 8f 24 00  |s..7......#./.$.|
    00000090  50 8d d3 44 b3 d0 b5 07  2a c5 17 80 18 00 a6 45  |P..D....*......E|
    000000a0  d1 00 00 01 01 08 0a 84  78 56 f5 06 ed 20 1e 4a  |........xV... .J|
    000000b0  75 73 74 20 6c 69 6b 65  20 74 68 65 20 6f 6e 65  |ust like the one|
    000000c0  73 20 49 20 75 73 65 64  20 74 6f 20 6b 6e 6f 77  |s I used to know|
    000000d0  00 0a 39 34 0a 00 10 db  ff 10 00 80 86 f2 68 e0  |..94..........h.|
    etc...
    For each "packet" there is a text integer followed by a newline. That tells you how many bytes are in the rest of the message.
    The message structure is:

    • ethernet_hdr
    • ip_hdr
    • tcp_hdr
    • extra crap
    • the text message


    The macro IP_HL gives the size of ip_hdr.
    The macro TH_OFF gives the size of tcp_hdr and the extra crap together.

    Using all that info, you can find the position and length of the text message.

    The OP is actually pretty close, but has gone off the rails at the end.
    He basically just needs a loop controlled by his initial fscanf.
    Philosophy is a battle against the bewitchment of our intelligence by means of language. - Wittgenstein

  7. #37
    Lurking whiteflags's Avatar
    Join Date
    Apr 2006
    Location
    United States
    Posts
    9,616
    Someone gets it!!

  8. #38
    Registered User
    Join Date
    Feb 2013
    Location
    Sweden
    Posts
    171
    Quote Originally Posted by john.c View Post
    The OP is actually pretty close, but has gone off the rails at the end.
    He basically just needs a loop controlled by his initial fscanf.
    A loop controlled by my initial fscanf? This one?:

    Code:
        // Get total length of package in bytes
        int totLenPkg; 
        fscanf(file, "%d", &totLenPkg);
        printf("Total length of package: %d", totLenPkg);
    Do you mean that I have to loop like the whole program
    from the initial line of fscanf? Or just a loop somehow
    using fscanf at the end of the program?

    Sorry, but I find this assignment very difficult.

  9. #39
    Lurking whiteflags's Avatar
    Join Date
    Apr 2006
    Location
    United States
    Posts
    9,616
    Well, to be specific, in post #29 I pasted what I think you need to loop. There will be minor changes to the program beyond looping that part; you will need to delete other code that isn't doing something helpful and print out the payload.

    It would probably be good to address some of the warnings in the program too, particularly the ones about void*. malloc()'s return value isn't meant to stay void, you can call it and have it return to a structure pointer assignment.

  10. #40
    Registered User
    Join Date
    Dec 2017
    Posts
    1,068
    Quote Originally Posted by DecoratorFawn82 View Post
    A loop controlled by my initial fscanf?
    Yes. As an example to print out just the text in each packet:
    Code:
    #include <stdio.h>
    #include <stdlib.h>
    #include "framehdr.h"
    
    int main() {
        FILE *f = fopen("TCPdump", "rb");
        if (f == NULL) {
            perror("fopen");
            exit(EXIT_FAILURE);
        }
    
        int len;
        while (fscanf(f, "%d", &len) == 1) {
            fgetc(f); // eat the newline
    
            char *b = malloc(len);
            fread(b, len, 1, f);
            
            int skip = sizeof(struct ethernet_hdr);
    
            int ip_hl = IP_HL((struct ip_hdr*)(b + skip));
            skip += ip_hl;
    
            int th_off = TH_OFF((struct tcp_hdr*)(b + skip));
            skip += th_off;
    
            printf("%s\n", b + skip);
    
            free(b);
        }
    
        fclose(f);
        return 0;
    }
    That's assuming that the structs are "packed" (have no extra padding bytes), which they seem to be. And it's only one way of doing it. The final printf works because the strings always end with a '\0' (and then, interestingly, a '\n').

    Now that I look more closely I see that each packet is separated by an extra newline that is not part of the count. The reason the above code works is that the fscanf skips whitespace before reading the integer, so it automatically skips the extra newline before the number.

    So the structure is:

    text integer
    '\n'
    ethernet_hdr
    ip_hdr
    tcp_hdr
    extra stuff (of size TH_OFF() - sizeof(struct tcp_hdr))
    text message ending with a '\0'
    '\n'

    The fact that the text message ends with '\0''\n' means it is readable by fgets (which stops after reading the newline, but presumably reads the '\0', terminating the string before the newline).

    It's an interesting format, part text part binary.
    Last edited by john.c; 12-16-2017 at 06:32 PM.
    Philosophy is a battle against the bewitchment of our intelligence by means of language. - Wittgenstein

  11. #41
    Registered User
    Join Date
    Feb 2013
    Location
    Sweden
    Posts
    171
    Thanks to all replies, but I actually figured out a way to get each package in the payload
    using another way.

    And it is now printing every sentence of the song

  12. #42
    Registered User
    Join Date
    Feb 2013
    Location
    Sweden
    Posts
    171
    Apparently, it worked in Dev-C++ but not in Visual Studio 2017.
    The program crashes when reading the last package. Due to reading
    past the allocated memory I was told. It was a '\n' character being
    read at the end of the file that shouldn't be read.

    Can someone please help me to get that part down since I've
    figured out pretty much of the rest I guess.

    Code:
    #pragma warning(disable:4996)
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include "framehdr.h"
    
    
    #define SIZE_ETHERNET 14
    #define SIZE_BUFFER 1000
    #define SIZE_SRC_DST 4
    
    
    FILE* readInFile();
    void printPackages(unsigned char* payload, unsigned char* src, unsigned char* dst);
    void getPayloadPackagesContent(FILE *file, char buffer[]);
    
    
    int main() {
        char buffer[SIZE_BUFFER];
    
    
        int pkgCounter = 1;
    
    
        FILE* file = readInFile();
    
    
        fseek(file, 0, SEEK_END);
        int endPos = ftell(file);
        rewind(file);
    
    
        // Using loop to get all payload packages
        int curpos;
        do {
            printf("\n\n");
            printf("--- Pkt %d ---\t", pkgCounter++);
    
    
            getPayloadPackagesContent(file, buffer);
    
    
            curpos = ftell(file);
        } while (endPos != (curpos - 1)); //   fgets(buffer, SIZE_BUFFER, file) != NULL
        //getchar();
    
    
        fclose(file);
    
    
        return 0;
    }
    
    
    FILE* readInFile() {
        char readInFile[SIZE_BUFFER];
    
    
        printf("What file do you want to use? ");
        scanf("%s", readInFile);
        getchar();
    
    
        FILE *file = fopen(readInFile, "rb");
    
    
        if (file == NULL) {
            printf("Error opening file!");
            exit(1);
        }
    
    
        return file;
    }
    
    
    void printPackages(unsigned char* payload, unsigned char* src, unsigned char* dst) {
    
    
        //if (strcmp(payload, "")) {
    
    
            // Here I need to get to the next sentence somehow
            printf("\n");
            printf("Payload: \t%s", payload);
    
    
            // The source adress
            printf("\nsrc: \t\t");
            int i;
            for (i = 0; i < SIZE_SRC_DST; i++) {
                printf("%d.", src[i]);
            }
    
    
            // The destination adress
            printf("\ndst: \t\t");
            int j;
            for (j = 0; j < SIZE_SRC_DST; j++) {
                printf("%d.", dst[j]);
            }
        //}
    }
    
    
    void getPayloadPackagesContent(FILE *file, char buffer[]) {
    
    
        // Get total length of package in bytes
        int totLenPkg;
        fscanf(file, "%d", &totLenPkg);
    
    
        // Read the package only
        fgets(buffer, SIZE_BUFFER, file);
    
    
        char* packet = malloc(totLenPkg);
    
    
        /*printf("\n\n");
        printf("--- Pkt %d ---\t", pkgCounter++);*/
    
    
        // 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);
    
    
        // TCP-package
        struct tcp_hdr* getTCP = (struct tcp_hdr*)(packet + SIZE_ETHERNET + sizeIP);
    
    
        // Size of TCP-package
        int sizeTCP = TH_OFF(getTCP);
    
    
        // Payload-package
        struct tcp_hdr* getPayload = (struct tcp_hdr*)(packet + SIZE_ETHERNET + sizeIP + sizeTCP);
    
    
        unsigned char *str = (unsigned char*)getPayload;
        printPackages(str, srcAdress, dstAdress);
    
    
        free(packet);
    }
    Last edited by DecoratorFawn82; 12-18-2017 at 03:47 AM.

  13. #43
    Registered User
    Join Date
    Feb 2013
    Location
    Sweden
    Posts
    171
    Don't mind previous post. I found a way to solve it

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