Why put the structures in a structure when assembling a TCP/IP Packet? - Unix

This is a discussion on Why put the structures in a structure when assembling a TCP/IP Packet? - Unix ; Is there anykind of significance to putting a structure inside another stucture when assembling a TCP/IP packet by hand? In the following code snippet, struct iphdr and struct tcphdr are inside another stucture. The only thing I can think of ...

+ Reply to Thread
Results 1 to 8 of 8

Thread: Why put the structures in a structure when assembling a TCP/IP Packet?

  1. Why put the structures in a structure when assembling a TCP/IP Packet?

    Is there anykind of significance to putting a structure inside another
    stucture when assembling a TCP/IP packet by hand? In the following
    code snippet, struct iphdr and struct tcphdr are inside another
    stucture. The only thing I can think of is that it's to ensure some
    kind of memory alignmen

    struct tpack{
    struct iphdr ip;
    struct tcphdr tcp;
    }tpack; /*Why put the structures inside another structure?*/

    struct sockaddr_in sin; /* IP address information */
    /* Setup the sin struct with addressing
    information */
    sin.sin_family=AF_INET; /* Internet address family */
    sin.sin_port=tcphp->dest; /* Source port */
    sin.sin_addr.s_addr=iphp->saddr;/* Dest. address */

    /* Packet assembly begins here */

    /* Fill in all the TCP header
    information */
    tpack.tcp.source=tcphp->dest; /* 16-bit Source port number
    */
    tpack.tcp.dest=tcphp->source; /* 16-bit Destination port */
    tpack.tcp.seq=0; /* 32-bit Sequence Number */
    tpack.tcp.ack_seq=htonl(ntohl(tcphp->seq)+1); /* 32-bit
    Acknowledgement Number */
    tpack.tcp.doff=5; /* Data offset */
    tpack.tcp.res1=0; /* reserved */
    tpack.tcp.res2=0; /* reserved */
    tpack.tcp.urg=0; /* Urgent offset valid flag */
    tpack.tcp.ack=1; /* Acknowledgement field valid
    flag */
    tpack.tcp.psh=0; /* Push flag */
    tpack.tcp.rst=1; /* Reset flag */
    tpack.tcp.syn=0; /* Synchronize sequence
    numbers flag */
    tpack.tcp.fin=0; /* Finish sending flag */
    tpack.tcp.window=0; /* 16-bit Window size */
    tpack.tcp.check=0; /* 16-bit checksum (to be
    filled in below) */
    tpack.tcp.urg_ptr=0; /* 16-bit urgent offset */

    /* Fill in all the IP header
    information */

    tpack.ip.version=4; /* 4-bit Version */
    tpack.ip.ihl=5; /* 4-bit Header Length */
    tpack.ip.tos=0; /* 8-bit Type of service */
    tpack.ip.tot_len=htons(IPHDR+TCPHDR); /* 16-bit Total length */
    tpack.ip.id=0; /* 16-bit ID field */
    tpack.ip.frag_off=0; /* 13-bit Fragment offset */
    tpack.ip.ttl=64; /* 8-bit Time To Live */
    tpack.ip.protocol=IPPROTO_TCP; /* 8-bit Protocol */
    tpack.ip.check=0; /* 16-bit Header checksum
    (filled in below) */
    tpack.ip.saddr=iphp->daddr; /* 32-bit Source Address */
    tpack.ip.daddr=iphp->saddr; /* 32-bit Destination Address
    */


  2. Re: Why put the structures in a structure when assembling a TCP/IP Packet?

    In article <1191893579.696576.127790@k79g2000hse.googlegroups. com>,
    grocery_stocker wrote:

    > Is there anykind of significance to putting a structure inside another
    > stucture when assembling a TCP/IP packet by hand? In the following
    > code snippet, struct iphdr and struct tcphdr are inside another
    > stucture. The only thing I can think of is that it's to ensure some
    > kind of memory alignmen
    >
    > struct tpack{
    > struct iphdr ip;
    > struct tcphdr tcp;
    > }tpack; /*Why put the structures inside another structure?*/


    Because that's how the packet is actually laid out. It also allows
    applications that want to do stuff with the whole header to use a single
    variable rather than two.

    --
    Barry Margolin, barmar@alum.mit.edu
    Arlington, MA
    *** PLEASE post questions in newsgroups, not directly to me ***
    *** PLEASE don't copy me on replies, I'll read them in the group ***

  3. Re: Why put the structures in a structure when assembling a TCP/IP Packet?

    The outer structure functions as a container of a truck.

    Everything needs to be inside the container, and the container gets shipped
    across the net

    Bye,
    Skybuck.



  4. Re: Why put the structures in a structure when assembling a TCP/IP Packet?

    On Oct 8, 7:04 pm, Barry Margolin wrote:
    > In article <1191893579.696576.127...@k79g2000hse.googlegroups. com>,
    >
    > grocery_stocker wrote:
    > > Is there anykind of significance to putting a structure inside another
    > > stucture when assembling a TCP/IP packet by hand? In the following
    > > code snippet, struct iphdr and struct tcphdr are inside another
    > > stucture. The only thing I can think of is that it's to ensure some
    > > kind of memory alignmen

    >
    > > struct tpack{
    > > struct iphdr ip;
    > > struct tcphdr tcp;
    > > }tpack; /*Why put the structures inside another structure?*/

    >
    > Because that's how the packet is actually laid out. It also allows
    > applications that want to do stuff with the whole header to use a single
    > variable rather than two.
    >
    > --


    I would like to take the time to point out that "googling" for
    examples of building TCP/IP packets isn't always a good thing. Half
    the sites I found had something like

    struct tpack{
    struct iphdr ip;
    struct tcphdr tcp;

    }tpack;

    And the other half had something like

    struct iphdr ip;
    struct tcphdr tcp;


    I figured the former, Ie
    struct tpack{
    struct iphdr ip;
    struct tcphdr tcp;

    }tpack;

    was a little bit more politically correct since it was taken from the
    Phrack, while the latter was take someone's personal blog.


  5. Re: Why put the structures in a structure when assembling a TCP/IPPacket?

    grocery_stocker wrote:
    > Is there anykind of significance to putting a structure inside another
    > stucture when assembling a TCP/IP packet by hand? In the following
    > code snippet, struct iphdr and struct tcphdr are inside another
    > stucture. The only thing I can think of is that it's to ensure some
    > kind of memory alignmen
    >
    > struct tpack{
    > struct iphdr ip;
    > struct tcphdr tcp;
    > }tpack; /*Why put the structures inside another structure?*/


    Because UDP packets also begin with (identical) IP headers?

    (As do lots of other protocols that can run on top of IP.)

    - Logan

  6. Re: Why put the structures in a structure when assembling a TCP/IP Packet?

    On Mon, 08 Oct 2007 18:32:59 -0700, grocery_stocker wrote:
    > Is there anykind of significance to putting a structure inside another
    > stucture when assembling a TCP/IP packet by hand? In the following
    > code snippet, struct iphdr and struct tcphdr are inside another
    > stucture. The only thing I can think of is that it's to ensure some
    > kind of memory alignmen
    >
    > struct tpack {
    > struct iphdr ip;
    > struct tcphdr tcp;
    > } tpack; /* Why put the structures inside another structure?*/


    Mostly because it helps when you want to 'reuse' common parts, like the
    definition of struct iphdr.

    It appears to be a trick to help with memory alignment, but if you read
    the C standard carefully, alignment is not guaranteed.

    For more details, see for example the following snippets of the
    standard:

    % ISO/IEC 9899:1999 (E) -- The C Programming Language
    %
    % 6.5.3.4 The sizeof operator
    %
    % 3 When applied to an operand that has type char, unsigned char,
    % or signed char, (or a qualified version thereof) the result is
    % 1. When applied to an operand that has array type, the result
    % is the total number of bytes in the array.84) When applied to
    % an operand that has structure or union type, the result is the
    % total number of bytes in such an object, including internal and
    % trailing padding.
    %
    % 6.7.2.1 Structure and union specifiers
    %
    % 13 Within a structure object, the non-bit-field members and the
    % units in which bit-fields reside have addresses that increase
    % in the order in which they are declared. A pointer to a
    % structure object, suitably converted, points to its initial
    % member (or if that member is a bit-field, then to the unit in
    % which it resides), and vice versa. There may be unnamed
    % padding within a structure object, but not at its beginning.
    %
    % 15 There may be unnamed padding at the end of a structure or union.

    Paragraph 6.7.2.1(13) and 6.7.2.1(15) explicitly allow padding after
    struct object parts, so there is no guarantee that in a struct
    definition like the following the two sub-structures occupy adjacent
    areas in the memory assigned to an object of the super-structure type:

    struct tpack {
    struct iphdr ip;
    struct tcphdr tcp;
    } tpack;

    Having said that, there are usually compiler-specific extensions to
    "pack" structure memmbers, so that no padding bits are used, but then
    you may run into another sort of interesting problem: Unaligned memory
    accesses cause traps on some platforms (most notably on SPARC).

    This means that if you are using a platform where:

    sizeof(int) == 4
    sizeof(long) == 8

    and unaligned memory accesses cause a hardware trap (that is, to read a
    'long' value, the address you are accessing must be a multiple of 8
    bytes), and you happen to be unlucky enough to use a "packed" structure
    like the "struct pack" defined below:

    struct foo {
    int f_int;
    };

    struct bar {
    long b_long;
    };

    struct pack {
    struct foo;
    struct bar;
    } __attribute(__packed); /* compiler extension */

    Then simply _reading_ from the pack.bar.b_long value of a structure may
    cause a hardware trap (which is allowed even to terminate the program
    with some sort of platform-specific error) :-(


  7. Re: Why put the structures in a structure when assembling a TCP/IP Packet?

    Giorgos Keramidas writes:
    > On Mon, 08 Oct 2007 18:32:59 -0700, grocery_stocker wrote:
    >> Is there anykind of significance to putting a structure inside another
    >> stucture when assembling a TCP/IP packet by hand? In the following
    >> code snippet, struct iphdr and struct tcphdr are inside another
    >> stucture. The only thing I can think of is that it's to ensure some
    >> kind of memory alignmen
    >>
    >> struct tpack {
    >> struct iphdr ip;
    >> struct tcphdr tcp;
    >> } tpack; /* Why put the structures inside another structure?*/

    >
    > Mostly because it helps when you want to 'reuse' common parts, like the
    > definition of struct iphdr.
    >
    > It appears to be a trick to help with memory alignment,


    The 'trick to help with alignment' would usually be a union, not a
    struct. The declaration above just declares a composite type whose
    members are composite types themselves.

    > but if you read the C standard carefully, alignment is not
    > guaranteed.


    The usual meaning of 'alignment' would be that the struct members can
    be accessed without causing processor exceptions because they have
    been aligned correctly (ie word-sized objects on word-boundaries),
    padding the structs themselves as necessary.

    [...]

    > % 6.7.2.1 Structure and union specifiers
    > %
    > % 13 Within a structure object, the non-bit-field members and the
    > % units in which bit-fields reside have addresses that increase
    > % in the order in which they are declared. A pointer to a
    > % structure object, suitably converted, points to its initial
    > % member (or if that member is a bit-field, then to the unit in
    > % which it resides), and vice versa. There may be unnamed
    > % padding within a structure object, but not at its beginning.
    > %
    > % 15 There may be unnamed padding at the end of a structure or union.


    [...]

    > Having said that, there are usually compiler-specific extensions to
    > "pack" structure memmbers, so that no padding bits are used, but then
    > you may run into another sort of interesting problem: Unaligned memory
    > accesses cause traps on some platforms (most notably on SPARC).


    At least gcc takes care of accessing potentially misaligned structure
    members such that those accesses don't trap (at the expense of
    performance). And it would greatly surprise me of 'other compilers'
    providing similar facilities would not do likewise -- after all,
    packing structs would be completely useless if it would result in
    unusable data.

  8. Re: Why put the structures in a structure when assembling a TCP/IP Packet?

    ["Followup-To:" header set]

    On Mon, 08 Oct 2007 18:32:59 -0700, grocery_stocker wrote:
    > Is there anykind of significance to putting a structure inside another
    > stucture when assembling a TCP/IP packet by hand? In the following
    > code snippet, struct iphdr and struct tcphdr are inside another
    > stucture. The only thing I can think of is that it's to ensure some
    > kind of memory alignmen


    Also ask yourself if there is a reason to use structs *at all*, and
    take the portability and performance hit from having to tell your
    compiler to disable its normal struct layout. And hoping your CPU
    tolerates reading words from odd addresses.

    Writing or reading an IP header octet-by-octet isn't exactly hard. I
    recently had to debug and fix a bunch of code like this -- it broke in
    interesting ways on 64-bit architectures.

    /Jorgen

    --
    // Jorgen Grahn \X/ snipabacken.dyndns.org> R'lyeh wgah'nagl fhtagn!

+ Reply to Thread