TCP header and endianess - TCP-IP

This is a discussion on TCP header and endianess - TCP-IP ; While looking at the Linux tcp.h header file, I see the following: struct tcphdr { u_int16_t source; u_int16_t dest; u_int32_t seq; u_int32_t ack_seq; # if __BYTE_ORDER == __LITTLE_ENDIAN u_int16_t res1:4; u_int16_t doff:4; u_int16_t fin:1; u_int16_t syn:1; u_int16_t rst:1; u_int16_t psh:1; ...

+ Reply to Thread
Results 1 to 6 of 6

Thread: TCP header and endianess

  1. TCP header and endianess


    While looking at the Linux tcp.h header file, I see the following:


    struct tcphdr
    {
    u_int16_t source;
    u_int16_t dest;
    u_int32_t seq;
    u_int32_t ack_seq;
    # if __BYTE_ORDER == __LITTLE_ENDIAN
    u_int16_t res1:4;
    u_int16_t doff:4;
    u_int16_t fin:1;
    u_int16_t syn:1;
    u_int16_t rst:1;
    u_int16_t psh:1;
    u_int16_t ack:1;
    u_int16_t urg:1;
    u_int16_t res2:2;
    # elif __BYTE_ORDER == __BIG_ENDIAN
    u_int16_t doff:4;
    u_int16_t res1:4;
    u_int16_t res2:2;
    u_int16_t urg:1;
    u_int16_t ack:1;
    u_int16_t psh:1;
    u_int16_t rst:1;
    u_int16_t syn:1;
    u_int16_t fin:1;

    u_int16_t window;
    u_int16_t check;
    u_int16_t urg_ptr;
    };


    I am a bit confused about the bit-ordering. I thought big-endianess and
    little-endianess apply only to "bytes" within either a 16 bit integer (hence
    ntohs and htons) or 32-bit integers (hence nthol and htonl). So why are
    they re-ordering the "bits" within a byte? i.e. why are the flag bits in
    reverse order for little-endianess?






  2. Re: TCP header and endianess

    On May 3, 11:26*pm, "barcaroller" wrote:
    > While looking at the Linux tcp.h header file, I see the following:
    >
    > struct tcphdr
    > {
    > * * u_int16_t source;
    > * * u_int16_t dest;
    > * * u_int32_t seq;
    > * * u_int32_t ack_seq;
    > # *if __BYTE_ORDER == __LITTLE_ENDIAN
    > * * u_int16_t res1:4;
    > * * u_int16_t doff:4;
    > * * u_int16_t fin:1;
    > * * u_int16_t syn:1;
    > * * u_int16_t rst:1;
    > * * u_int16_t psh:1;
    > * * u_int16_t ack:1;
    > * * u_int16_t urg:1;
    > * * u_int16_t res2:2;
    > # *elif __BYTE_ORDER == __BIG_ENDIAN
    > * * u_int16_t doff:4;
    > * * u_int16_t res1:4;
    > * * u_int16_t res2:2;
    > * * u_int16_t urg:1;
    > * * u_int16_t ack:1;
    > * * u_int16_t psh:1;
    > * * u_int16_t rst:1;
    > * * u_int16_t syn:1;
    > * * u_int16_t fin:1;
    >
    > * * u_int16_t window;
    > * * u_int16_t check;
    > * * u_int16_t urg_ptr;
    >
    > };
    >
    > I am a bit confused about the bit-ordering. *I thought big-endianess and
    > little-endianess apply only to "bytes" within either a 16 bit integer (hence
    > ntohs and htons) or 32-bit integers (hence nthol and htonl). *So why are
    > they re-ordering the "bits" within a byte? i.e. why are the flag bits in
    > reverse order for little-endianess?


    This is because the bits defined in structure are endianess relative.
    The C programming language points this when introduce bits in struct.
    You can check it.

    Regards,
    Matthew

  3. Re: TCP header and endianess

    In article
    ,
    Matthew Xu wrote:

    > On May 3, 11:26*pm, "barcaroller" wrote:
    > > While looking at the Linux tcp.h header file, I see the following:
    > >
    > > struct tcphdr
    > > {
    > > * * u_int16_t source;
    > > * * u_int16_t dest;
    > > * * u_int32_t seq;
    > > * * u_int32_t ack_seq;
    > > # *if __BYTE_ORDER == __LITTLE_ENDIAN
    > > * * u_int16_t res1:4;
    > > * * u_int16_t doff:4;
    > > * * u_int16_t fin:1;
    > > * * u_int16_t syn:1;
    > > * * u_int16_t rst:1;
    > > * * u_int16_t psh:1;
    > > * * u_int16_t ack:1;
    > > * * u_int16_t urg:1;
    > > * * u_int16_t res2:2;
    > > # *elif __BYTE_ORDER == __BIG_ENDIAN
    > > * * u_int16_t doff:4;
    > > * * u_int16_t res1:4;
    > > * * u_int16_t res2:2;
    > > * * u_int16_t urg:1;
    > > * * u_int16_t ack:1;
    > > * * u_int16_t psh:1;
    > > * * u_int16_t rst:1;
    > > * * u_int16_t syn:1;
    > > * * u_int16_t fin:1;
    > >
    > > * * u_int16_t window;
    > > * * u_int16_t check;
    > > * * u_int16_t urg_ptr;
    > >
    > > };
    > >
    > > I am a bit confused about the bit-ordering. *I thought big-endianess and
    > > little-endianess apply only to "bytes" within either a 16 bit integer (hence
    > > ntohs and htons) or 32-bit integers (hence nthol and htonl). *So why are
    > > they re-ordering the "bits" within a byte? i.e. why are the flag bits in
    > > reverse order for little-endianess?

    >
    > This is because the bits defined in structure are endianess relative.
    > The C programming language points this when introduce bits in struct.
    > You can check it.


    Actually, I think the order of bit fields is left
    implementation-dependent by the C language. It just so happens that
    most implementations lay them out consistently with the endianness.

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

  4. Re: TCP header and endianess

    On May 4, 3:39*pm, Barry Margolin wrote:

    > > > I am a bit confused about the bit-ordering. *I thought big-endianessand
    > > > little-endianess apply only to "bytes" within either a 16 bit integer (hence
    > > > ntohs and htons) or 32-bit integers (hence nthol and htonl). *So whyare
    > > > they re-ordering the "bits" within a byte? i.e. why are the flag bits in
    > > > reverse order for little-endianess?


    > Actually, I think the order of bit fields is left
    > implementation-dependent by the C language. *It just so happens that
    > most implementations lay them out consistently with the endianness.


    That's annoying. Since the most common setup these days is IP over
    Ethernet, meaning big endian byte order and little endian bit order in
    each byte, switching simultaneously both the bit and the byte order is
    a perfect formula for creating confusion.

    Good to know, though. Chalk it up to "tricks of the trade."

    Bert

  5. Re: TCP header and endianess

    In article
    ,
    Albert Manfredi wrote:

    > On May 4, 3:39*pm, Barry Margolin wrote:
    >
    > > > > I am a bit confused about the bit-ordering. *I thought big-endianess
    > > > > and
    > > > > little-endianess apply only to "bytes" within either a 16 bit integer
    > > > > (hence
    > > > > ntohs and htons) or 32-bit integers (hence nthol and htonl). *So why
    > > > > are
    > > > > they re-ordering the "bits" within a byte? i.e. why are the flag bits
    > > > > in
    > > > > reverse order for little-endianess?

    >
    > > Actually, I think the order of bit fields is left
    > > implementation-dependent by the C language. *It just so happens that
    > > most implementations lay them out consistently with the endianness.

    >
    > That's annoying. Since the most common setup these days is IP over
    > Ethernet, meaning big endian byte order and little endian bit order in
    > each byte, switching simultaneously both the bit and the byte order is
    > a perfect formula for creating confusion.


    Yeah. The C designers didn't really intend bit fields to be used for
    external data.

    The way to write bit-twiddling code portably is to use shifting and
    masking, rather than bit fields.

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

  6. Re: TCP header and endianess

    On Sun, 04 May 2008 20:29:04 -0400, Barry Margolin wrote:
    > In article
    > ,
    > Albert Manfredi wrote:
    >
    >> On May 4, 3:39*pm, Barry Margolin wrote:
    >>
    >> > > > I am a bit confused about the bit-ordering. *I thought big-endianess
    >> > > > and
    >> > > > little-endianess apply only to "bytes" within either a 16 bit integer
    >> > > > (hence
    >> > > > ntohs and htons) or 32-bit integers (hence nthol and htonl). *So why
    >> > > > are
    >> > > > they re-ordering the "bits" within a byte? i.e. why are the flag bits
    >> > > > in
    >> > > > reverse order for little-endianess?

    >>
    >> > Actually, I think the order of bit fields is left
    >> > implementation-dependent by the C language. *It just so happens that
    >> > most implementations lay them out consistently with the endianness.

    >>
    >> That's annoying. Since the most common setup these days is IP over
    >> Ethernet, meaning big endian byte order and little endian bit order in
    >> each byte, switching simultaneously both the bit and the byte order is
    >> a perfect formula for creating confusion.

    >
    > Yeah. The C designers didn't really intend bit fields to be used for
    > external data.
    >
    > The way to write bit-twiddling code portably is to use shifting and
    > masking, rather than bit fields.


    Yes. And in my experience, you typically do not gain a lot of
    readability by mapping onto structs and bitfields. When I have
    rewritten code to use a few well-chosen encoding/decoding functions
    instead of structs and bit fields, it has become *more* readable.

    Also, for the struct tcphdr in the original example, note that if you
    cast some char * or void * buffer to a struct tcphdr *, you better
    make sure it is word-aligned. Otherwise, depending on your CPU
    architecture, you may get a bus error, or suffer drastic performance
    reduction.

    /Jorgen

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

+ Reply to Thread