Skip to content

Channel Hopping

Why channel hopping?

The 802.11 standard defines a large number of frequencies (or channels) on which a WiFi network can operate. This is beneficial for avoiding contention and bandwidth issues. However, it also implies that your wireless adapter must be tuned to a single channel at a time, thus incapable of capturing all wireless traffic simultaneously. Under normal operations, your operating system will handle this automatically.

Since the goal is not to monitor just one but potentially all WiFi channels, you'd either require a multitude of adapters—with each one dedicated to a different channel—or you'd need to rapidly cycle over multiple channels on a single adapter. Nzyme supports configuration for multiple channels per WiFi adapter.

For instance, if you configure nzyme to monitor channels 1 through 6 on one adapter and channels 7 through 11 on a second adapter, it will first tune the first adapter to channel 1, then shift to channel 2, then to channel 3, and so forth. While this approach may cause us to miss some wireless frames on channels we're currently not tuned to, it prevents us from completely missing out on data from any particular channel.

What channels do my WiFi adapters support?

You can use the --generate-channels flag of nzyme-tap to automatically generate a configuration for all supported channels of your connected WiFi adapters and print it to STDOUT. It is important to note that you will likely see duplicated channels if you have multiple adapters. You have to manually pick and choose channels as described below. A channel can only be assigned to a single adapter or the tap will refuse to start.

Alternatively, you can use the iw program to list all channels supported by a WiFi adapter. It should be pre-installed on all modern Linux distributions.

First, list all wireless adapters:

$ iw dev

...

phy#2
    Interface wlx9cefd5f8985d
        ifindex 7
        wdev 0x200000001
        addr 9c:ef:d5:f8:98:5d
        type managed
        txpower 3.00 dBm
        multicast TXQ:
            qsz-byt qsz-pkt flows   drops   marks   overlmt hashcol 
            0   0   0   0   0   0   0   0       0
phy#1
    Interface wlx9cefd5f890de
        ifindex 5
        wdev 0x100000001
        addr 9c:ef:d5:f8:90:de
        type managed
        txpower 3.00 dBm
        multicast TXQ:
            qsz-byt qsz-pkt flows   drops   marks   overlmt hashcol 
            0   0   0   0   0   0   0   0       0
phy#0
    Unnamed/non-netdev interface
        wdev 0x2
        addr 00:93:37:8d:f7:7b
        type P2P-device
        txpower 0.00 dBm
    Interface wlo1
        ifindex 4
        wdev 0x1
        addr 00:93:37:8d:f7:7a
        type managed
        txpower 0.00 dBm
        multicast TXQ:
            qsz-byt qsz-pkt flows   drops   marks   overlmt hashcol 
            0   0   0   0   0   0   0   0       0

Copy the physical identifier (for example, phy#1) of the device you are interested in and use it with the iw phy command:

$ iw phy phy1 channels

...

Band 1:
    * 2412 MHz [1] 
      Maximum TX power: 20.0 dBm
      Channel widths: 20MHz HT40+
    * 2417 MHz [2] 
      Maximum TX power: 20.0 dBm
      Channel widths: 20MHz HT40+
    * 2422 MHz [3] 
      Maximum TX power: 20.0 dBm
      Channel widths: 20MHz HT40+
    * 2427 MHz [4] 
      Maximum TX power: 20.0 dBm
      Channel widths: 20MHz HT40+
    * 2432 MHz [5] 
      Maximum TX power: 20.0 dBm
      Channel widths: 20MHz HT40- HT40+
    * 2437 MHz [6] 
      Maximum TX power: 20.0 dBm
      Channel widths: 20MHz HT40- HT40+
    * 2442 MHz [7] 
      Maximum TX power: 20.0 dBm
      Channel widths: 20MHz HT40- HT40+
    * 2447 MHz [8] 
      Maximum TX power: 20.0 dBm
      Channel widths: 20MHz HT40- HT40+
    * 2452 MHz [9] 
      Maximum TX power: 20.0 dBm
      Channel widths: 20MHz HT40- HT40+
    * 2457 MHz [10] 
      Maximum TX power: 20.0 dBm
      Channel widths: 20MHz HT40-
    * 2462 MHz [11] 
      Maximum TX power: 20.0 dBm
      Channel widths: 20MHz HT40-
    * 2467 MHz [12] 
      Maximum TX power: 20.0 dBm
      No IR
      Channel widths: 20MHz HT40-
    * 2472 MHz [13] 
      Maximum TX power: 20.0 dBm
      No IR
      Channel widths: 20MHz HT40-
    * 2484 MHz [14] 
      Maximum TX power: 20.0 dBm
      No IR
      Channel widths: 20MHz
Band 2:
    * 5180 MHz [36] 
      Maximum TX power: 20.0 dBm
      Channel widths: 20MHz HT40+ VHT80
    * 5200 MHz [40] 
      Maximum TX power: 20.0 dBm
      No IR
      Channel widths: 20MHz HT40- HT40+ VHT80
    * 5220 MHz [44] 
      Maximum TX power: 20.0 dBm
      Channel widths: 20MHz HT40- HT40+ VHT80
    * 5240 MHz [48] 
      Maximum TX power: 20.0 dBm
      Channel widths: 20MHz HT40- HT40+ VHT80
    * 5260 MHz [52] 

...

In this example, you see that for the first band, the first supported frequency is 2412 MHz / channel 1: 2412 MHz [1].

You can now add supported channels to your nzyme-tap.conf file.

Configuring the Tap Channels

An example configuration of a nzyme tap listening on 2.4 GHz, 5 GHz and 6 GHz channels could look like this:

[wifi_interfaces.wlx00c0ca000000]
active = true
channel_width_hopping_mode = "full"
channels_2g = [1, 6, 11]
channels_5g = [100, 102, 104, 106, 108, 110, 112, 136, 138, 140, 149, 151, 153, 155, 157, 159, 161, 165]
channels_6g = []

[wifi_interfaces.wlx00c0ca000001]
active = true
channel_width_hopping_mode = "full"
channels_2g = [2, 3, 4, 5, 7, 8, 9, 10, 12, 13]
channels_5g = [36, 40, 44, 48, 52, 56, 60, 64, 173]
channels_6g = [5, 9, 13, 17, 21, 25, 29, 109, 113, 153, 157, 161, 165, 169, 173, 177, 181, 185, 189, 229, 233]

Info

The 802.11 WiFi standard started to assign overlapping channel numbers. This is why you see that, for example, channel 5 is configured for the 2.4 GHz (2432 MHz / 802.11b/g/n) band as well as the the 6 GHz band (5975 MHz / WiFi 6E / 802.11ax).

What channels should I choose?

The selection of channels largely depends on your specific use-case, wireless environment, and objectives. Generally, the goal is to cover as much of the WiFi spectrum as possible. It's advisable to set up at least one adapter to cover all 2.4 GHz channels and another to cover all 5GHz channels, providing comprehensive visibility of the entire WiFi environment.

If you're equipped with multiple adapters, it might be beneficial to prioritize busier channels. For instance, if you have two adapters dedicated to the 2.4 GHz band, it's advisable to configure one to cycle through the frequently busy channels 1, 6, and 11, while the other covers all remaining channels. This approach ensures more time is spent monitoring the typically busier channels, resulting in more data capture.

Alternatively, a single adapter can be set to cycle through all the channels it supports. While this is a feasible approach, keep in mind that it will spend less time on each channel, potentially missing more data.

Channel Width Hopping Mode

WiFi standards support different channel widths, including 20 Mhz, 40 Mhz, 80 Mhz, 160 MHz and 320 Mhz. It is common for WiFi networks to operate on multiple channel widths to optimize throughput.

Nzyme can automatically cycle through all supported channel widths of a WiFi channel supported by your WiFi adapters. This way, all WiFi clients can be observed, no matter what channel width they operate on, assuming your WiFi adapter supports such a channel width. The downside of this approach is that nzyme will miss more traffic on other channels while it is cycling through potentially unoccupied channel widths. It will simply spend less time capturing traffic per channel.

By default, nzyme will cycle through all channel widths it can use. However, you can control this behavior by configuring the channel_width_hopping_mode configuration variable of each configured WiFi adapter of a tap. It can be set to either full or limited:

[wifi_interfaces.wlx00c0ca000000]
channel_width_hopping_mode = "full"
...

[wifi_interfaces.wlx00c0ca000001]
channel_width_hopping_mode = "limited"
...

When set to limited, nzyme will only use the 20 MHz channel width. Virtually all access points will be using 20 Mhz channels to advertise their existence using beacon or probe response frames. This way, you will miss a significant part of client traffic, but capture more other relevant traffic on the 20 Mhz channel width of each frequency.

The default setting is full. Do not change this setting if you are unsure about what it does.

Disabling Channel Hopping

You can disable channel hopping for a WiFi adapter by adding the disable_hopper configuration option and setting it to true. This can be useful in the rare case of another process controlling the channel selection.

[wifi_interfaces.wlx00c0ca000000]
active = true
disable_hopper = true
( ... other adapter configuration ... )