Thread: Read data from a binary file using a pointer

  1. #1
    Registered User
    Join Date
    Feb 2013
    Location
    Sweden
    Posts
    171

    Question Read data from a binary file using a pointer

    I have been asked to read data from a binary file ( TCPdump ) using a pointer. I could read the data using a variable (non-pointer) and the console window did show me some numbers.

    But when I tried doing the same thing with a pointer the program crashed? Is this because I'm not calling malloc() when initializing the pointer? Or is it the syntax when I'm using the pointer that is wrong?

    I uploaded the TCPdump file to this folder (If you need to see it)
    My Files

    The package looks like:

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

    main.c (Laboration3.c)
    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;
    }
    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

  2. #2
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,659
    You need to allocate space.

    Code:
        struct ethernet_hdr* getEthernet;    
        getEthernet = malloc( sizeof(*getEthernet));
        fread(getEthernet, sizeof(struct ethernet_hdr), 1, file);
    Then you need to call free() at some point.

    Don't forget to add all the necessary error checking on malloc / fread.


    PS
    Your pointer casts on the first parameter to fread() serve no purpose at all.
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  3. #3
    Registered User
    Join Date
    Jun 2011
    Posts
    4,513
    Quote Originally Posted by DecoratorFawn82 View Post
    Code:
    if (file == NULL)
        printf("Error");
    If the file fails to open, you print "Error" but still allow the program to proceed and attempt to access that file.

  4. #4
    Registered User
    Join Date
    Feb 2013
    Location
    Sweden
    Posts
    171
    Don't forget to add all the necessary error checking on malloc / fread.

    What is the necessary error handling for malloc and fread?

    Is this what I should do if the program cannot read the file?
    Code:
        
        if (file == NULL) {
            printf("Error");
            exit(1);    
        }

  5. #5
    Registered User
    Join Date
    Jun 2011
    Posts
    4,513
    Quote Originally Posted by DecoratorFawn82 View Post
    What is the necessary error handling for malloc and fread?
    Look up those functions and see what their return values represent.
    This is an important skill you should cultivate.

    Quote Originally Posted by DecoratorFawn82 View Post
    Is this what I should do if the program cannot read the file?
    Code:
        
        if (file == NULL) {
            printf("Error");
            exit(1);    
        }
    Yes, that is one way.

  6. #6
    Banned
    Join Date
    Aug 2017
    Posts
    861
    this works too,
    Code:
    FILE *file;
    
        if ( (file = fopen("TCPdump", "rb") ) == NULL) 
        { 
            printf("Error"); 
            return -1; 
        }

  7. #7
    Registered User
    Join Date
    Dec 2017
    Posts
    1,628
    Better yet:
    Code:
    if (file == NULL) {
        perror("fopen");    // Prints the reason the file didn't open to stderr.
                            // (no such file; permission denied; etc.)
                            // The input string is printed before the error msg.
                            // E.g., fopen: Permission denied.
        exit(EXIT_FAILURE); // EXIT_FAILURE is a portable error return value
                            // (defined in stdlib.h)
    }
    Treat malloc similarly.

  8. #8
    Registered User
    Join Date
    Jun 2011
    Posts
    4,513
    Quote Originally Posted by userxbw View Post
    this works too,
    Code:
    FILE *file;
    
        if ( (file = fopen("TCPdump", "rb") ) == NULL) 
        { 
            printf("Error"); 
            return -1; 
        }
    Be aware that certain environments interpret program return values as unsigned.

  9. #9
    Banned
    Join Date
    Aug 2017
    Posts
    861
    Quote Originally Posted by Matticus View Post
    Be aware that certain environments interpret program return values as unsigned.
    If the open operation is successful, fopen() returns a valid file pointer. The type FILE is defined in stdio.h.
    It is a structure that holds various kinds of information about the file, such as size.The file pointer will be used
    with all other functions that operate on the file and it must never be altered or the object it points to. If fopen() fails
    it returns a NULL pointer so this must always be checked for when opening a file. For example:


    FILE *fp;
    if ((fp = fopen("myfile", "r")) ==NULL){
    printf("Error opening file\n");
    exit(1);
    }

    then someone better up date these people too
    The Stream File
    Last edited by userxbw; 12-13-2017 at 03:06 PM.

  10. #10
    Registered User
    Join Date
    Dec 2017
    Posts
    1,628
    Quote Originally Posted by Matticus View Post
    Be aware that certain environments interpret program return values as unsigned.
    userxbw is totally incompetent and completely incapable of learning.

  11. #11
    Banned
    Join Date
    Aug 2017
    Posts
    861
    Quote Originally Posted by john.c View Post
    userxbw is totally incompetent and completely incapable of learning.
    says the master of insecurity, the playground bully.

  12. #12
    Registered User
    Join Date
    Jun 2011
    Posts
    4,513
    Quote Originally Posted by userxbw View Post
    then someone better up date these people too
    The Stream File
    That link has no relevance to the point at hand.

  13. #13
    Banned
    Join Date
    Aug 2017
    Posts
    861
    Quote Originally Posted by Matticus View Post
    That link has no relevance to the point at hand.
    it is what you referenced. so be more clear. thank you
    Originally Posted by userxbw
    this works too,
    Code:
    Code:
         
    
    ?
    
    1 2 3 4 5 6 7 FILE *file; if ( (file = fopen("TCPdump", "rb") ) == NULL) { printf("Error"); return -1; }

    Be aware that certain environments interpret program return values as unsigned.
    If the open operation is successful, fopen() returns a valid file pointer. The type FILE is defined in stdio.h. It is a structure that holds various kinds of information about the file, such as size.The file pointer will be used with all other functions that operate on the file and it must never be altered or the object it points to. If fopen() fails it returns a NULL pointer so this must always be checked for when opening a file. For example:
    FILE *fp;
    if ((fp = fopen("myfile", "r")) ==NULL){
    printf("Error opening file\n");
    exit(1);
    }
    from that link

    The Stream File

  14. #14
    Registered User
    Join Date
    Jun 2011
    Posts
    4,513
    Quote Originally Posted by userxbw View Post
    it is what you referenced. so be more clear. thank you
    Quote Originally Posted by Matticus View Post
    Be aware that certain environments interpret program return values as unsigned.
    I'm referring to the return value returned to the shell upon program completion.

    What you posted was the return value of a function, used within a program.

  15. #15
    Banned
    Join Date
    Aug 2017
    Posts
    861
    that is what I kind of figured you might be referring to, as that is the only thing I changed, I'll go back to exit (1) or exit (0) and add the header too.
    thanks


    Return negative value in main in C

    C standard leaves most things about the return values of main to be defined by the implementation. Basically returning 0, EXIT_SUCCESS, or EXIT_FAILURE is somehow standard
    and reliable, everything else depends on the platform. In this case it seems like the operating system gives you the value modulo 256 (as an uint8_t).


    In main function return 0 or exit(0) are same but if you write exit(0) in different function then your program will exit from that position returning different values
    return 1or return -1 helps in debugging.

    Basically 0 is returned if the program has executed correctly, 1,2,3...are returned if the program execution doesn't encounter any error but warnings or somewhere logic going wrong and finally -1 is returned if the program counters any error
    Last edited by userxbw; 12-13-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