views:

1168

answers:

5

See the definition of TCP header in /netinet/tcp.h:

struct tcphdr
  {
    u_int16_t th_sport;         /* source port */
    u_int16_t th_dport;         /* destination port */
    tcp_seq th_seq;             /* sequence number */
    tcp_seq th_ack;             /* acknowledgement number */
#  if __BYTE_ORDER == __LITTLE_ENDIAN
    u_int8_t th_x2:4;           /* (unused) */
    u_int8_t th_off:4;          /* data offset */
#  endif
#  if __BYTE_ORDER == __BIG_ENDIAN
    u_int8_t th_off:4;          /* data offset */
    u_int8_t th_x2:4;           /* (unused) */
#  endif
    u_int8_t th_flags;
#  define TH_FIN        0x01
#  define TH_SYN        0x02
#  define TH_RST        0x04
#  define TH_PUSH       0x08
#  define TH_ACK        0x10
#  define TH_URG        0x20
    u_int16_t th_win;           /* window */
    u_int16_t th_sum;           /* checksum */
    u_int16_t th_urp;           /* urgent pointer */
};

Why does the 8-bit field have a different order in endianness? I thought only 16-bit and 32-bit fields mattered with byte order, and you could convert between endians with ntohs and ntohl, respectively. What would the function be for handling 8-bit things? If there is none, it seems that a TCP using this header on a little endian machine would not work with a TCP on a big endian machine.

A: 

My reading of the comment is that the two one-byte fields together are construed as a two-byte value (or were -- seems like one byte is unused anyway). Rather than declare one two-byte value, they declare two one-byte values but reverse the order of declaration depending on endian-ness.

Sean Owen
No, it is clearly intending to define two 4-bit fields. See e.g. http://www.freesoft.org/CIE/Course/Section4/8.htm for TCP header layout.
Lance Richardson
+10  A: 

There are two kind of order. One is byte order, one is bitfield order. There is no standard order about the bitfield order in C language. It depends on the compiler. Typically, the order of bitfields are reversed between big and little endian.

kcwu
this seems like the correct answer, and I have a vague recollection of hearing it before, but I can't in good conscience upvote without a citation... can you provide one?
rmeador
this is the only answer that makes sense to me
Claudiu
+2  A: 

Its possible that in this machine the endianess also refers to the bit order as well as the byte order. This wikipedia article mentions that this is sometimes the case.

shoosh
In this question, it has no relation to bit order.
kcwu
+7  A: 

This is compiler-dependent and non-portable. How bit fields are ordered is implementation dependent, it would be far better here to use an 8-bit field and shift/mask to obtain the subfields.

Lance Richardson
Sounds like a better plan to me.
Dave Cluderay
+1  A: 

My understanding is that bit ordering and endianness are generally two different things. Structures with bit-fields are generally not portable across compilers/architectures. Sometimes ifdefs can be used to support different bit orderings. In this case the endianness is really irrelevant and it should be an ifdef about the bit ordering. The assumption that some endianesses have a certain bit-order may be true in some cases.