Deciphering 802.11

I'm reading the excellent 802.11 Wireless Networks: The Definitive Guide, 2nd Ed by Matthew Gast. Matthew knows 802.11, period. I can't wait to review this book. I wish I had read it sooner.

I've been analyzing network traffic in Wireshark while devouring the book. I read that figures like 3-10 (reproduced below -- please consider this free publicity, O'Reilly!) show the least significant bit (LSb) first -- at least within a defined field.

Also, although the diagrams are LSb first, the text uses values that are most siginifcant bit (MSb) first. For example, the subtype for a RTS frame is depicted as 1101 in a diagram but 1011 in the text and Table 3-1.

This is where I became confused when closely inspecting Wireshark output.

The top of the figure shows a generic 802.11 MAC frame. The bottom of the figure expands upon the Frame Control field. With the FC field, notice the bits are numbered 0 to 15, with 0 at the far left and 15 at the far right of the diagram.

So what does this look like on the wire? Here is Tshark's rendition of the important parts.

orr:/home/richard$ tshark -n -V -x -r sample_wireless.lpc
Frame 1 (97 bytes on wire, 97 bytes captured)
Arrival Time: Apr 5, 2006 20:27:06.651549000
Time delta from previous packet: 0.000000000 seconds
Time since reference or first frame: 0.000000000 seconds
Frame Number: 1
Packet Length: 97 bytes
Capture Length: 97 bytes
Frame is marked: False
Protocols in frame: wlan
IEEE 802.11
Type/Subtype: Probe Response (5)
Frame Control: 0x0850 (Normal)
Version: 0
Type: Management frame (0)
Subtype: 5
Flags: 0x8
DS status: Not leaving DS or network is operating in AD-HOC mode
(To DS: 0 From DS: 0) (0x00)
.... .0.. = More Fragments: This is the last fragment
.... 1... = Retry: Frame is being retransmitted
...0 .... = PWR MGT: STA will stay up
..0. .... = More Data: No data buffered
.0.. .... = Protected flag: Data is not protected
0... .... = Order flag: Not strictly ordered
Duration: 314
Destination address: 00:20:a6:4c:3b:87 (00:20:a6:4c:3b:87)
Source address: 00:0f:f8:58:40:cb (00:0f:f8:58:40:cb)
BSS Id: 00:0f:f8:58:40:cb (00:0f:f8:58:40:cb)
Fragment number: 0
Sequence number: 367

0000 50 08 3a 01 00 20 a6 4c 3b 87 00 0f f8 58 40 cb P.:.. .L;....X@.
0010 00 0f f8 58 40 cb f0 16 0d ab 9f 1e 2e 00 00 00 ...X@...........
0020 64 00 01 00 00 0b 00 00 00 00 00 00 00 00 00 00 d...............
0030 00 01 04 82 84 8b 96 03 01 0b dd 06 00 40 96 01 .............@..
0040 01 00 dd 05 00 40 96 03 02 dd 16 00 40 96 04 00 .....@......@...
0050 03 06 a5 00 00 22 a5 00 00 41 54 00 00 61 43 00 ....."...AT..aC.
0060 00 .

If you don't like reading text, here is a jpg or the packet itself.

In any case, you'll see this represents the Frame Control field.

Frame Control: 0x0850 (Normal)

If you look at the hex output above, however you see this:

0000 50 08 3a 01 00 20 a6 4c 3b 87 00 0f f8 58 40 cb P.:.. .L;....X@.

The 0x5008 is represented as 0x0850 by Tshark/Wireshark/whatever. Why not 0x5008? Is it because Frame Control is 16 bits?

At this point it would be nice for someone to respond and say "That's because..." I'm guessing that although traffic is sent in network byte order, the positioning of those bytes may be interpreted differently when two bytes are needed to represent an entire field. (Frame Control is 16 bits or 2 bytes.)

Thus far the only relevant line I've read is on p. 78:

The most significant bits in the 802.11 specification come at the end of fields.

Can anyone comment? Sorry if this is a dumb question -- I've been working with this chapter for a few hours, and even Matthew warns people not to read it unless they really need to understand 802.11 internals.

By the way, the following filter has been helpful to ignore Probe Requests, Probe Responses, and Beacons while inspecting wireless traffic.

!(wlan.fc.type == 0 and wlan.fc.subtype == 4) and !(wlan.fc.type == 0 and wlan.fc.subtype == 5) and !(wlan.fc.type == 0 and wlan.fc.subtype == 8)

I'm also using the following dumb for loop to look for traces with specific type and subtypes set, so I can see real traffic.

$ for i in `ls *.dump`; do echo $i && tshark -n -r $i -R "wlan.fc.type == 1 and wlan.fc.subtype == 10"; done

The -R feature lets you pass a Wireshark display filter as if it were a capture filter or BPF.


Anonymous said…
Careful not to get confused between most significant bit first and most significant byte first. Big- vs. little-endian is generally referring to byte order, rather than bit order. e.g. if you have the integer 16909060 (1 * 2^24 + 2 * 2^16 + 3 * 2^8 + 4), big-endian MSb (SPARC) would be 0x01020304, little-endian MSb (Intel) would be 0x04030201. In both cases, the bit order within the byte is the same. However, in big-endian LSb it would be 0x8040c020.

In the case of what you're looking at, I'd guess tshark was running on an Intel box and just read the value as a short int and printed it (as 0x0850) before parsing it. When it parsed it, it handled the octets in the correct order - the 0x08 was parsed as the high (flags) octet. In MSb, it is 00001000, and the flags in the text dump shows reset (fourth from the left in LSb, fourth from the right in MSb) as set. Interestingly, the subtype shows a value of 5 - which is the MSb value of the subtype (the four high-order bits in the low-order octet). So if I've understood correctly, tshark is correctly pulling out the correct four bits for the subtype, but not reversing them before printing... which is definately confusing. I'd also question whether it's properly mapping the subtype; if probe response is actually int 5, then this wouldn't be a probe response, it's int 10. However, if probe response is 'bits 4 and 6 according to the diagram being set', then it is a probe response, and tshark should probably print out the value as 10. Well, most importantly, it should show what the standard specifies, so if the standard says 'a probe response is 1010', it should print 1010; if the standard says 'a probe response is 0xa', it should print 0xa.

Thanks Richard, now my head hurts. ;-)
Anonymous said…
It is not a mistake.

That is because, 802.11 is little-endian , while general networking - TCP/IP-802.3 etc., are all big-endian

Popular posts from this blog

Zeek in Action Videos

MITRE ATT&CK Tactics Are Not Tactics

New Book! The Best of TaoSecurity Blog, Volume 4