Flannels n sh*t is Making my WiFi Slow

July 24, 2016


I’ve recently been working on renewing the Certified Wireless Network Administrator (CWNA) certification. The CWNA focuses on a deep, technical, and vendor-agnostic understanding of the foundational principles underlying 802.11 WLANs. One day, in between flipping through flash cards, I decided to take a look at the wireless traffic in my own home environment.

I was interested to see quite a few Request to Send/Clear to Send (RTS/CTS) exchanges on the same channel as mine, so I decided to dig a bit deeper to “diagnose” the issue. RTS/CTS is a protection mechanism that is typically enabled in a high throughput 802.11n environment to facilitate coexistence with older 802.11 technologies, namely b/g networks. As we can see above, there are a number of transmissions involving the RTS/CTS exchange prior to any data crossing the airwaves.

Before I start diving deeper into the packet-level diagnostics, let’s get some administrative information out of the way. I don’t really care about showing MAC addresses online, as all of these frames could easily be sniffed over the airwaves by any device running a promiscuous capture in monitor mode. The original packet capture used in this article was obtained using Wireshark and sniffing in monitor mode on a Macbook Pro. Details on my network are also below:

Channel: 1

SSID: Yeezus

BSSID: 14:2d:27:a6:af:fe

First, I wanted to determine the mode that my WLAN was operating in. 802.11n networks can operate in one of four modes. By examining the HT Information Tag within a Beacon frame transmitted by my AP, we can see that my network is operating in mode 01: HT non-member protection mode.

A WLAN in mode 01 consists of only 802.11n HT stations. However, protection mechanisms will be enabled if a non-HT station or access point is overheard on the same channel. This is useful, as it ensures that nearby legacy 802.11b/g networks will not be negatively impacted by the presence of 802.11n networks. Taking a closer look at one of the RTS/CTS frames, we can see that it is transmitted using the 802.11g PHY to ensure that legacy stations are able to hear it.

Great, so I know why I’m seeing protection mechanisms that result in additional MAC overhead and cause slower throughput. However, I’m still not sure who is responsible for running technology from 2003 in my residential neighborhood. Thankfully, I managed to capture 10,000 packets that can be analyzed to glean some insight into the networks used by my neighbors.

Tracking down older WLANs

It actually took me quite awhile, several tries, and a few beers to come up with a good set of criteria for tracking down the problematic WLANs. I finally decided that I would only look for 802.11 frames that met the following:

  • Transmitted at the 802.11b or g PHY
  • Are not RTS or CTS. I’m not interested in frames that are only generated for the sake of the protection mechanisms. I just want to see who is actively using 802.11b or g PHY to transmit data.
  • Are not broadcast or multicast frames. By messing around, I noticed that IPv4 and IPv6 multicast frames were being transmitted at the 802.11g PHY by both my WLAN and other devices. I’m not sure why, and I haven’t been able to find anything that indicates broadcast and multicast frames should also be broadcast at a lower rate, but I was seeing this behavior. At any rate, it’s probably safe to ignore them because there wouldn’t be any transmission on the b or g PHYs if non-member protection mode wasn’t enabled.
  • Are not Null or QoS Null Data Frames. These frames are only used to transmit flag information. They don’t contain any data. Again, it’s probably safe to ignore them because they would otherwise be sent at 802.11n rates if protection mechanisms weren’t in place.

I eventually came up with the Wireshark display filter above that meets my needs. Let’s break it down:

  • wlan.fc.type_subtype != 0x001b – Ignore RTS frames
  • wlan.fc.type_subtype != 0x001c – Ignore CTS frames
  • wlan.fc.type_subtype != 0x002c – Ignore QoS null data frames
  • wlan.fc.type_subtype != 0x0024 – Ignore non-Qos null data frames
  • wlan_radio.phy == 6 – Find only frames transmitted at the 802.11g PHY*
  • wlan.da[0:3] != 01:00:5e – Ignore IPv4 multicast frames
  • wlan.da[0:3] != 33:33:00 – Ignore IPv6 multicast frames
  • wlan.da[0:3] != ff:ff:ff – Ignore broadcast frames

*I did go looking for 802.11b PHY, but didn’t find any frames in my capture. Therefore, for the sake of brevity, I’m leaving off the exclusion from the filter.

Great, so now I have all of the packets that I care about displayed in Wireshark. However, I’d really like to get a sense for who is actively using 802.11g data rates. Ideally, I’d like to narrow down a specific SSID in my area that is still only b/g capable. I wasn’t able to find a way to do this within the Wireshark UI. This is unfortunate, as the UI has a lot of other nice statistics tools. If I was actually a competent software developer, I’d consider contributing this kind of functionality to the project. At any rate, to filter and sort the SSIDs we’ll have to hop over to the command line to parse the packet capture.

First, I saved the displayed packets (only those identified by my filter) to a separate capture file. This is easy. Simply go to File > Export Specified Packets… in Wireshark and choose a different filename.

Next, I had to come up with a way to parse the packet capture and feed it into other *nix tools, such as uniq and sort. After some Googling, I found that this can be accomplished with tshark. Unfortunately, I was running into weird issues where tshark was spewing out some garbage data in its output, which I only discovered after noticing that two seemingly identical lines were completely different in an octal dump. Thankfully, the wonderful community on the Wireshark-users mailing list gave me a hand, and I eventually had the right set of flags to properly use tshark and get the data that I needed. Here’s what I ended up with:

Let’s break this down. First, let’s take a look at the tshark options:

  • -n: disable name resolution
  • -Y wlan.bssid: display filter for the BSSID. Thanks to the Wireshark-users mailing list for this tip
  • -T fields: output field values specified by the -e option
  • -e wlan.bssid: we’re interested in the wlan.bssid field within each frame
  • -r /wlan/packets_to_sort.pcapng: read in from the packet capture that we exported earlier

Next, let’s break down the basic *nix commands that were used to filter and sort the data:

  • sort: sorts the BSSID list output from tshark, which is necessary before piping into uniq
  • uniq -c: remove duplicate entries and add a column with the count of total entries for each value
  • sort -rn: sort in a numerically descending order

The output above shows a few of the BSSIDs displayed. For good measure, I also piped the output into “wc -l” to see a count of the unique BSSIDs, which ended up totaling 198. While this definitely seems like a lot of wireless APs in my area, the count in the output seems to indicate that many of these were one-off frames. I’m more interested in the BSSIDs that appear to be active, namely the top 4.

Let’s take a look at the BSSID seen transmitting the most amount of frames: c0:3f:0e:04:72:5c. It’s fairly easy to track down this BSSID. We’ll just head back to the original packet capture and use the “wlan.bssid == c0:3f:0e:04:72:5c” filter.

Looking at the results of the filter above, we can clearly see data frames being transmitted within this basic service set. We can also see probe responses with the SSID “Flannels n shit” Let’s dig deeper into “Flannels n shit” and see why clients are actively transmitting on the 802.11g PHY. Looking at one of the probe respones will give us more insight into the BSS and client capabilities of the WLAN.

The probe response above indicates that this BSSID supports the 802.11b/g data rates, as seen in the Supported Rates and Extended Supported Rates tagged parameters. However, notice that there is no HT Capabilities or HT Information tagged parameters present. This indicates that the BSSID does not support 802.11n, and is instead limited to the legacy data rates of 802.11b/g.

The “Flannels n shit” WLAN isn’t even capable of using the 802.11n PHY, and is therefore one of the primary reasons for the activation of protection mechanisms within surrounding 802.11n HT WLANs, such as my “Yeezus” network. Flannels provide warm, lumberjack style clothing for the fall months here in Rochester, but they’re slowing down my WLAN and that makes me sad. I really like Flannel. At any rate, it looks like we’ve found the primary cause of the increased medium contention caused by the RTS/CTS and CTS-to-self protection mechanisms.

However, let’s not stop there. There were still 3 other WLANs with a relatively high number of frames transmitted with the 802.11g PHY.

The Remaining Frames

I started taking a look at the next most common BSSIDs: 44:94:fc:07:2b:3c, 8c:09:f4:e6:12:b0, and 14:2d:27:a6:af:fe using the same process as the one above. I quickly found that none of the frames in these BSSIDs were being sent as data frames, so I decided to just lump them all together in one Wireshark display filter.

By filtering for all of these BSSIDs, it immediately becomes apparent that they only frames being sent on these BSSIDs are probe responses. Since probe responses contain capability information, I was able to verify that each of the three SSIDs (University Music, Yeezus, Speak Friend and Enter) were all capable of 802.11n HT data rates. However, they were replying to probe requests sent by clients at 802.11g data rates.

Additionally, I took a look at each probe response. Two of the BSSIDs were in Non-Member Protection mode, and one of the BSSIDs was in greenfield mode. This indicates that none of the other BSSIDs contained any non-802.11n HT capable clients within the BSS.

For the sake of keeping this article brief, and because we already took a frame-level look at the probe response of “Flannels n shit,” I’m going to omit a full discussion of the remaining three WLANs.


This was a fun trek down the rabbit hole of 802.11 fundamentals and Wireshark analysis. From the perspective of improving the speeds within my network, there isn’t much that I can do within the 2.4GHz spectrum. I don’t think my neighbors would be receptive to my recommendation of purchasing an access point that doesn’t only support 13 year old technology. Most likely, I’ll just be shifting my WLAN over to the 5GHz spectrum to avoid the myriad of problems with 2.4GHz, notably the high amount of channel overlap.

In addition to being a fun exercise, this deep dive into 802.11 frames in my environment has some practical benefit for anyone reading this. My personal recommendations include:

  • Using only the 5GHz bands on your AP if the AP and all of your client devices support it. The 5GHz spectrum is far less crowded, and you’ll likely be able to use a channel that only hosts your AP. This avoids unnecessary medium contention caused by co-channel interference.
  • Disable legacy 802.11b/g data rates on your AP, if possible.
  • Only purchase 802.11n capable access points and client adapters. 802.11g was ratified 13 years ago. It’s time to move on. But I’m not going to tell this to my neighbors.

Some of these goals are idealistic. Disabling the 2.4GHz band and b/g data rates on most enterprise (and even SoHo) APs is easy. However, client support for 5GHz and HT WLANs can occasionally be spotty. You’re probably alright in some industries, such as educational institutions where iPads and laptops support standards from the last decade. You’re in worse shape if you work in an industry where incompetent manufacturers of multi-million dollar pieces of equipment decide to cut corners by only integrating 2.4GHz b/g NICs in their products. Did someone say healthcare? Sorry, I thought I heard healthcare.

I hope you’ve enjoyed this wireless witch hunt! For me, it was a really good way to re-familiarize myself with the 802.11 fundamentals that were necessary to re-cert the CWNA, which I thankfully passed about a week ago. I have some more wireless topics in mind for future posts, so stay tuned!