Size of my Struct? PLZ PLZ reply

Discussion in 'C Programming' started by brian, Nov 23, 2004.

  1. brian

    brian Guest

    ANaiveProgrammer wrote:

    > Last but not the least , i need to send the ethernet_frame struct over
    > a socket , is the following a legitimate way to do that
    > write(sockfd,(char *)&ef,10);//'ef' is the instance of ethernet_frame
    > struct
    > Please tell me how to send a struct over the socket, is above way
    > correct OR there is another around?
    > Any help, at earliest, would highly be appreciated. I know its a
    > lenghty post and may take a bit of your time. However, i will be
    > highly compelled for this esteemed favour.
    > Cheers
    > Waqas


    This has already been done in libnet. I would suggest checking out
    the source code for that library.

    Also, there is more than one type of ethernet header you can send.
    Check out the RFCs. You might also want to read TCP Illustrated
    vol I.

    Finally, write() is a unix system call, which is out of scope for
    this newsgroup even though K&R mention it in their book. And you
    want to test the buffering to make sure everything you want to send
    actually got sent. Don't forget to use good error coding.

    comp.unix.programmer might be able to help you out more.

    Brian

    ps And the size of structs is covered in the FAQ.
     
    brian, Nov 23, 2004
    #1
    1. Advertising

  2. Hi all

    I have made the following two structs and size is not according to
    what is supposed to be, so please ponder over following and identify
    if im wrong...
    please also mention what would be the size of "ethernet_frame" struct
    and why ?

    typedef struct {
    //This struct defines Arp--Request.
    uint8_t haddr_type
    uint8_t proto_type[4];
    uint8_t hard_len;
    uint8_t proto_len
    uint16_t operation;
    uint8_t sender_hard[6];
    uint8_t sender_proto[4];
    uint8_t target_ip[4];

    }arp_request;

    typedef struct{
    //Ethernet Frame
    uint8_t destip[4];
    uint8_t sourceip[4];
    uint8_t frametype[3];
    arp_request *req;
    } ethernet_frame;

    int main(){
    arp_request request;
    ethernet_frame ef;

    printf("Size of ARP---%d\n",sizeof(request));
    printf("Size of Ethernet---%d\n",sizeof(ef));
    }
    --------

    im compiling this code under Red Hat linux(PSyche)...
    My second question is that how will i initialize a uint8_t array, for
    example

    As i have defined a uint8_t frametype[3]in ethernet_frame struct...i
    have defined this unsigned integer array in another function as
    follows

    uint8_t frame[3]={0x8,0x0,0x6};
    for( k=0; k<3;k++)
    ef->frametype[k] = frame[k];
    //where 'ef' is a pointer to ethernet_frame struct
    Well im very much sure that there would be some better way around than
    above in terms of code optimization. please answer this question as
    well???

    Last but not the least , i need to send the ethernet_frame struct over
    a socket , is the following a legitimate way to do that
    write(sockfd,(char *)&ef,10);//'ef' is the instance of ethernet_frame
    struct
    Please tell me how to send a struct over the socket, is above way
    correct OR there is another around?
    Any help, at earliest, would highly be appreciated. I know its a
    lenghty post and may take a bit of your time. However, i will be
    highly compelled for this esteemed favour.
    Cheers
    Waqas
     
    ANaiveProgrammer, Nov 23, 2004
    #2
    1. Advertising

  3. brian

    Eric Sosman Guest

    ANaiveProgrammer wrote:
    > Hi all
    >
    > I have made the following two structs and size is not according to
    > what is supposed to be, so please ponder over following and identify
    > if im wrong...


    This is Question 2.13 in the comp.lang.c Frequently
    Asked Questions (FAQ) list

    http://www.eskimo.com/~scs/C-faq/top.html

    > please also mention what would be the size of "ethernet_frame" struct
    > and why ?


    The correct answer is `sizeof(ethernet_frame)' and the
    "why" is "because."

    --
     
    Eric Sosman, Nov 23, 2004
    #3
  4. brian

    -berlin.de Guest

    ANaiveProgrammer <> wrote:
    > I have made the following two structs and size is not according to
    > what is supposed to be, so please ponder over following and identify
    > if im wrong...
    > please also mention what would be the size of "ethernet_frame" struct
    > and why ?


    > typedef struct {
    > //This struct defines Arp--Request.
    > uint8_t haddr_type
    > uint8_t proto_type[4];
    > uint8_t hard_len;
    > uint8_t proto_len
    > uint16_t operation;
    > uint8_t sender_hard[6];
    > uint8_t sender_proto[4];
    > uint8_t target_ip[4];
    >
    > }arp_request;


    > typedef struct{
    > //Ethernet Frame
    > uint8_t destip[4];
    > uint8_t sourceip[4];
    > uint8_t frametype[3];
    > arp_request *req;
    > } ethernet_frame;


    > int main(){
    > arp_request request;
    > ethernet_frame ef;


    > printf("Size of ARP---%d\n",sizeof(request));
    > printf("Size of Ethernet---%d\n",sizeof(ef));
    > }
    > --------


    > im compiling this code under Red Hat linux(PSyche)...


    The size of both structures is determined by the compiler and may
    depend on the hardware the program is compiled for. The compiler
    is allowed to insert as many padding bytes into the structure as
    it deems necessary, see the C-FAQ, section 2.12/13. For that
    reason it is _not_ a good idea to try to assemble binary data
    in a certain format by using structures. You have to use a "flat"
    memory region and populate it by copying the elements into that
    region using memcpy(). Only if you don't mind making your program
    dependend on the compiler you use then you can use some compiler-
    specific extensions to make sure the compiler does not insert
    padding bytes (but even in that case you may still have to popu-
    late the elements of the structure using memcpy() since on many
    machines you may get a bus error when trying to access the
    structure elements because the hardware allows only accesses to
    e.g. even addresses).

    > My second question is that how will i initialize a uint8_t array, for
    > example


    > As i have defined a uint8_t frametype[3]in ethernet_frame struct...i
    > have defined this unsigned integer array in another function as
    > follows


    > uint8_t frame[3]={0x8,0x0,0x6};
    > for( k=0; k<3;k++)
    > ef->frametype[k] = frame[k];
    > //where 'ef' is a pointer to ethernet_frame struct
    > Well im very much sure that there would be some better way around than
    > above in terms of code optimization. please answer this question as
    > well???


    Well, you can use memcpy() (or memmove() in case the data you want to
    copy could overlap). If that is faster in your case can only be deter-
    mined experimentally. The C language does not make any promises about
    the execution speed of a program.

    > Last but not the least , i need to send the ethernet_frame struct over
    > a socket , is the following a legitimate way to do that
    > write(sockfd,(char *)&ef,10);//'ef' is the instance of ethernet_frame
    > struct
    > Please tell me how to send a struct over the socket, is above way
    > correct OR there is another around?


    Well, now you rather left the field of what's topical in this group.
    The C language has no built-in support for network operations and
    also the write() function is not a standard C function but system
    dependend. Since you seem to be using Linux the newsgroups
    comp.os.linux.development.apps or comp.unix.programmer would seem
    to be good places to ask instead.

    But typically sending structures in binary form is a bad idea since
    the machines on both ends may have quite different ideas about the
    lay-out of the structure (e.g. because different amounts of padding
    bytes are used) and since the way numbers are represented may differ
    a lot between machines with different architectures (look up e.g. the
    difference between "big-endian" and "little-endian" machines). It
    will probably work when both machines have the same architecture
    and the programs on both ends have been compiled with the same
    compiler (using the same version of that specific compiler and the
    same compiler flags), but otherwise it can fail miserably. It's
    the same problem as with writing structures into a file in binary
    format and then trying to read them back on a different machine.
    One solution would be to convert the data into some common repre-
    sentation (e.g. ASCII), send them over to the other side in that
    form and then assemble them back into a structure on the other
    machine.
    Regards, Jens
    --
    \ Jens Thoms Toerring ___ -berlin.de
    \__________________________ http://www.toerring.de
     
    -berlin.de, Nov 23, 2004
    #4
  5. brian

    dandelion Guest

    "brian" <> wrote in message
    news:86Vod.84801$SW3.16551@fed1read01...
    > ANaiveProgrammer wrote:


    <snip>

    > Also, there is more than one type of ethernet header you can send.
    > Check out the RFCs.


    <*cough*>
    The IETF does not concern itself with ethernet-packet definitions. You want
    IEEE 802.3.
    <*cough*>

    See http://standards.ieee.org/getieee802/portfolio.html
     
    dandelion, Nov 24, 2004
    #5
  6. >I have made the following two structs and size is not according to
    >what is supposed to be,


    If you think the size of a particular struct is supposed to be some
    particular integer, regardless of implementation, STOP THINKING
    THAT. The size of a particular struct is obtained by using the
    sizeof operator. The implementation is always allowed to add padding
    to the end of or in the middle of the struct.


    Why would something likely to be transmitted over a network
    (your ethernet_frame struct) contain a *POINTER*?

    <snip>

    >Last but not the least , i need to send the ethernet_frame struct over
    >a socket , is the following a legitimate way to do that
    >write(sockfd,(char *)&ef,10);//'ef' is the instance of ethernet_frame
    >struct


    The size of ef is sizeof(ef), not 10 or any other explicit integer.
    The layout of structures varies from implementation to implementation,
    so there is no guarantee that the sending and receiving machine
    agree on the size, byte order, alignment, padding, etc. of a raw
    binary structure.

    Gordon L. Burditt
     
    Gordon Burditt, Nov 24, 2004
    #6
  7. Many thanks for your reply...
    >
    > The size of ef is sizeof(ef), not 10 or any other explicit integer.
    > The layout of structures varies from implementation to implementation,
    > so there is no guarantee that the sending and receiving machine
    > agree on the size, byte order, alignment, padding, etc. of a raw
    > binary structure.


    So bottom line is , my structurs will work?????????am i right.....


    what is padding in structures, why do compilers do that ? i mean im
    stupmed about this....wht is the advantange of using Byte padding in
    structures....
    cheers
     
    ANaiveProgrammer, Nov 24, 2004
    #7
  8. brian

    -berlin.de Guest

    ANaiveProgrammer <> wrote:
    > Many thanks for your reply...
    >>
    >> The size of ef is sizeof(ef), not 10 or any other explicit integer.
    >> The layout of structures varies from implementation to implementation,
    >> so there is no guarantee that the sending and receiving machine
    >> agree on the size, byte order, alignment, padding, etc. of a raw
    >> binary structure.


    > So bottom line is , my structurs will work?????????am i right.....


    Where did you got that from Gordons reply (and, please, keep proper
    attributions)?

    > what is padding in structures, why do compilers do that ? i mean im
    > stupmed about this....wht is the advantange of using Byte padding in
    > structures....


    The advantage of padding bytes is that the compiler can produce
    code that won't crash with bus errors on some machines. There are
    quite a number of machines where accessing e.g. odd addresses is
    not allowed. So, when you have e.g. a structure like

    struct crash_me {
    int a;
    char b;
    int c;
    } x;

    and sizeof(int) is at an even and sizeof(char) an odd number, then,
    without an additional padding byte, 'c' would be at an odd address
    (the compiler makes sure that the structure does not start at an
    odd address in such cases). And the result would be that for

    x.c = 3;

    the computer would have to write a value to an int that is at an odd
    address and that would kill the program. In order to avoid that the
    compiler automatically inserts at least one "padding byte" between
    the members 'b' and 'c' of the structure, so that accessing the member
    'c' won't lead to the program getting aborted.

    You are also for example not allowed to do things like

    int a;

    *( ( char * ) a + 1 ) = 1;

    because that could result in an "unaligned" access, i.e., in the example
    from above, in an access to an odd address.

    That's probably the main reason for padding bytes. But even on machines
    where accesses to odd addresses are allowed it's often a lot slower
    than accessing even addresses (e.g. i386 CPUs).

    Regards, Jens
    --
    \ Jens Thoms Toerring ___ -berlin.de
    \__________________________ http://www.toerring.de
     
    -berlin.de, Nov 25, 2004
    #8
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. javagirl86
    Replies:
    0
    Views:
    390
    javagirl86
    May 24, 2007
  2. ZOD
    Replies:
    2
    Views:
    339
    Blinky the Shark
    Aug 7, 2007
  3. ram

    Reply plz..........

    ram, Jan 19, 2008, in forum: Java
    Replies:
    2
    Views:
    369
    Markus Tazl
    Jan 20, 2008
  4. davidj411
    Replies:
    1
    Views:
    1,058
    Mike Driscoll
    May 27, 2008
  5. Replies:
    2
    Views:
    567
Loading...

Share This Page