Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ordering of LI, VN, mode bits #8

Open
mzimmers opened this issue Feb 6, 2019 · 1 comment
Open

ordering of LI, VN, mode bits #8

mzimmers opened this issue Feb 6, 2019 · 1 comment

Comments

@mzimmers
Copy link

mzimmers commented Feb 6, 2019

Hi -

I'm wondering about the order of your bit fields for Leap Indicator, Version Number and Mode. According to multiple sources I've looked at:

LI: bits 0-1
VN: bits 2-4
Mode: bits 5-7

If you wish these values (as indicated in your comment):
LI: 0
VN: 3
Mode: 3

Then the bit pattern should be 011 011 00, or 0110 1100, or 0x6c, not 0x1b as you use.

Not so?

@lettier
Copy link
Owner

lettier commented Feb 9, 2019

Hello @mzimmers,

0x1b is the correct value. Compiling and running the current version with 0x6c as the first byte will hang the client. ⏲️

The bit fields were removed and replaced with a single byte member. The bit fields, for clarity, followed along with the data structure as described in the RFC but were never meant to be interpreted on the client. Interpreting them on the client could result in the wrong interpretation depending on the underlying architecture and the bit field implementation used.

Using 0x1b or 00 011 011...

li = First 2
vn = Next 3
mode = Next 3

As Set
00011011

Server Interpretation - Correct
00   | 011 | 011
li   | vn  | mode
0    | 3   | 3

Possible Client Interpretation - Wrong
000  | 110 | 11
mode | vn  | li
0    | 6   | 3

Using 0x6c or 011 011 00...

li = First 2
vn = Next 3
mode = Next 3

As Set
01101100

Server Interpretation - Wrong
01   | 101 | 100
li   | vn  | mode
1    | 5   | 4

Possible Client Interpretation - Correct
011  | 011 | 00
mode | vn  | li
3    | 3   | 0

In the end, it matters how the server interprets the first byte. For little endianness, you'd want to reorder the bit fields from li, vn, and mode to mode, vn, and li but the data set as the first byte would stay the same. The data stays the same but by reordering the bit fields you alter the interpretation client side.

The order of bits in a byte are not reversed when going from big to little-endian and vice versa.

By removing the bit fields and replacing them with a byte member, along with the provided macros,

  printf("%d\n", LI(packet));
  printf("%d\n", VN(packet));
  printf("%d\n", MODE(packet));

you avoid this ambiguity and can still get the correct values for LI, VN, and Mode if you want but this tutorial didn't require it.

The server's protocol interprets the first byte of bits received as LI, then VN, and then Mode. Thus the packet's first byte is filled out with 0x1b.

*( ( char * ) &packet + 0 ) = 0x1b;
                        ^

That byte is sent first and received first and is correctly interpreted as 0 for LI, 3 for VN, and 3 for Mode since the byte is 27 = 0x1b = 00011011 = 0001 1011 = 00 011 011.

👍

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants