In my previous article on MCS and Windows, I laid some groundwork on what MCS is and why itās useful. Check out the first few paragraphs for that background info.
This time, letās turn our attention toward macOS. The best way to dump the Wi-Fi settings in a human-readable format, would be:
sudo /System/Library/PrivateFrameworks/Apple80211.framework/Versions/Current/Resources/airport -I
which yields something like:
agrCtlRSSI: -45
agrExtRSSI: 0
agrCtlNoise: -92
agrExtNoise: 0
state: running
op mode: station
lastTxRate: 1300
maxRate: 217
lastAssocStatus: 0
802.11 auth: open
link auth: wpa3-sae
BSSID: 4c:43:41:4:1c:bc
SSID: Flowers By Irene
MCS: 9
guardInterval: 800
NSS: 3
channel: 149,80
If you run that command without āsudoā, it doesnāt list the BSSID.
You can also run the above program with the -x
flag, which will dump it in XML format, if you prefer that. Honestly, I feel like even though the output above is human-readable, itās also easier to āmachine readā than the XML.
While this gives me more information than Windows does, it doesnāt have a separate uplink vs. downlink indicator. The āmaxRateā is also confusing. Before digging in too much, letās look at another example:
agrCtlRSSI: -33
agrExtRSSI: 0
agrCtlNoise: -88
agrExtNoise: 0
state: running
op mode: station
lastTxRate: 1200
maxRate: 867
lastAssocStatus: 0
802.11 auth: open
link auth: wpa2-psk
BSSID:
SSID: Anudder
MCS: 11
guardInterval: 800
NSS: 2
channel: 52,80
This helps us understand that macOS likes round numbers. Technically, MCS 11 with two spatial streams on 80 MHz OFDMA with a 0.8μs GI is 1201 Mbps.
But we have that mysterious āmaxRateā again. Before rounding to a whole number, 867 is actually 866.7, which is MCS 9 on 2 spatial streams on an 80 MHz channel with a 4μs GI. Perhaps that means it is the uplink rate… that seems conceivable.
From the first example, we have a maxRate of 217, which, before whole-number rounding, is likely 216.7, which is MCS 7 on 3 spatial streams, but on a 20 MHz channel, but we know weāre operating on an 80 MHz channel here.
Python Fun
At any rate (pun intended), parsing the output is pretty easy. Hereās a quick program I wrote to convert macOSās output to a JSON file.
# /System/Library/PrivateFrameworks/Apple80211.framework/Versions/Current/Resources/airport -I
import json
macOS_wifi_dump = """
agrCtlRSSI: -33
agrExtRSSI: 0
agrCtlNoise: -88
agrExtNoise: 0
state: running
op mode: station
lastTxRate: 1200
maxRate: 867
lastAssocStatus: 0
802.11 auth: open
link auth: wpa2-psk
BSSID:
SSID: Anudder
MCS: 11
guardInterval: 800
NSS: 2
channel: 52,80
"""
int_fields = [
'agrCtlRSSI', 'agrExtRSSI', 'agrCtlNoise', 'agrExtNoise',
'lastTxRate', 'maxRate', 'lastAssocStatus', 'MCS',
'guardInterval', 'NSS'
]
airport = {}
for line in macOS_wifi_dump.strip().splitlines():
if ":" in line:
left, right = line.split(":", 1)
key = left.strip()
value = right.strip()
airport[key] = int(value) if key in int_fields else value
airport['channel'], airport['width'] = [int(x) for x in airport['channel'].split(',')]
my_json = json.dumps(airport, indent=4)
print(my_json)
The output would look like this:
{
"agrCtlRSSI": -33,
"agrExtRSSI": 0,
"agrCtlNoise": -88,
"agrExtNoise": 0,
"state": "running",
"op mode": "station",
"lastTxRate": 1200,
"maxRate": 867,
"lastAssocStatus": 0,
"802.11 auth": "open",
"link auth": "wpa2-psk",
"BSSID": "",
"SSID": "Anudder",
"MCS": 11,
"guardInterval": 800,
"NSS": 2,
"channel": 52,
"width": 80
}
My original idea behind MCS fiddling was in order to write a parser that would calculate all the MCS values in order to:
- Output a matrix like the one found on mcsindex.com
- Output a JSON file with the data rate being the key and an array of objects containing each of the possibilities
I may do that at some point in the future. I may also do some Linux āiwā MCS observations. For now, at least, itās good to know what some of the capabilities and restrictions are for reading from macOS.