Path: utzoo!utgpu!news-server.csri.toronto.edu!bonnie.concordia.ca!uunet!stanford.edu!agate!ucbvax!alias.com!mark From: mark@alias.com (Mark Andrews) Newsgroups: comp.protocols.tcp-ip Subject: Re: Byte and bit order within packet headers Message-ID: <9104261535.AA28580@alias.alias.com> Date: 26 Apr 91 15:35:24 GMT Sender: daemon@ucbvax.BERKELEY.EDU Organization: The Internet Lines: 91 From NIC.DDN.MIL!tcp-ip-RELAY@utcsri Fri Apr 26 03:20:29 1991 Date: 26 Apr 91 05:15:36 GMT From: usc!rpi!news-server.csri.toronto.edu!utgpu!watserv1!sunee!erick@apple.com (Erick Engelke) Organization: University of Waterloo Subject: Re: Byte and bit order within packet headers References: <9104241753.AA21589@dino.alias.com> Sender: tcp-ip-relay@nic.ddn.mil To: tcp-ip@nic.ddn.mil Erick Engelke (usc!rpi!news-server.csri.toronto.edu!utgpu!watserv1!sunee!erick@apple.com) responds to my question: >In article <9104241753.AA21589@dino.alias.com> mandrews@alias.com (Mark Andrews) writes: >> >>I have a question concerning concering the byte and bit order of fields >>within packet headers. Many of the RFCS (including RFC1060) state rules >>about the byte (octet) order: >> > >Much confusion stems from the fact that Intel processors store >bits in the following order > > +--+--+--+--+--+--+--+---+---+--+--+--+--+--+--+---+ > |07 06 05 04 03 02 01 00 | 15 14 13 12 11 10 09 08 | > +--+--+--+--+--+--+--+---+---+--+--+--+--+--+--+---+ > | first stored byte | second stored byte | etc. > >whereas network order is > > +--+--+--+--+--+--+--+---+---+--+--+--+--+--+--+---+ > |15 14 13 12 11 10 09 08 | 07 06 05 04 03 02 01 00 | > +--+--+--+--+--+--+--+---+---+--+--+--+--+--+--+---+ > >so the bits and nybbles are already in network order, you simply need to >organize quantities larger than a byte, namely 16 and 32 bit values. > >The intel code should have > unsigned ip_h : 4; > unsigned ip_v : 4; > >I hope this clears it up a bit. > >Erick Fine, this a good example. In my specific example, I was looking how BSD code interprets the version number and header length of an IP packet header: struct ip { #if BYTE_ORDER == LITTLE_ENDIAN u_char ip_hl:4, /* header length */ ip_v:4; /* version */ #endif #if BYTE_ORDER == BIG_ENDIAN u_char ip_v:4, /* version */ ip_hl:4; /* header length */ #endif Unfortunately, the bit order is machine and compiler dependent. On little endian machines, the bit fields are assigned least significant bit first (right to left), resulting in: MSB LSB +--+--+--+--+--+--+--+--+ | ip_v | ip_hl | +--+--+--+--+--+--+--+--+ 07 06 05 04 03 02 01 00 On big endian machines, the bit fields are also assigned least significant bit first, but this time the bit fields are assigned left to right: LSB MSB +--+--+--+--+--+--+--+--+ | ip_v | ip_hl | +--+--+--+--+--+--+--+--+ 00 01 02 03 04 05 06 07 In which order are the bits transmitted such that the integrity of the data is not compromised, independent of the endian order. For example, if a big endian machine is talking to a little endian machine, in what order are the bits transmitted so that the ip_v and ip_hl fields from the big endian machine are interpreted properly on the little endian machine. In the case of the ip_v field, bits 0-3 of the big endian byte must be transmitted to bits 4-7 of the little endian byte! Thanks for any information, Mark