Skip to content

Instantly share code, notes, and snippets.

@donalod
Last active October 18, 2023 20:26
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save donalod/489271adb9e92ae52810355ea04428a4 to your computer and use it in GitHub Desktop.
Save donalod/489271adb9e92ae52810355ea04428a4 to your computer and use it in GitHub Desktop.
apple80211_channel_flags_extract.sh
#!/usr/bin/env bash
# set -e
# set -x
plistbuddy="/usr/libexec/PlistBuddy"
airport_output=$(/System/Library/PrivateFrameworks/Apple80211.framework/Versions/Current/Resources/airport -s -x)
wlan_sp_airport_data_type=$(system_profiler SPAirPortDataType)
scandata=./scandata.plist
# With props to https://newosxbook.com/articles/11208ellpA-II.html for the below (albeit old... header files!)
#
# enum apple80211_channel_flag
# {
# APPLE80211_C_FLAG_NONE = 0x0, // no flags
# APPLE80211_C_FLAG_10MHZ = 0x1, // 10 MHz wide
# APPLE80211_C_FLAG_20MHZ = 0x2, // 20 MHz wide
# APPLE80211_C_FLAG_40MHZ = 0x4, // 40 MHz wide
# APPLE80211_C_FLAG_2GHZ = 0x8, // 2.4 GHz
# APPLE80211_C_FLAG_5GHZ = 0x10, // 5 GHz
# APPLE80211_C_FLAG_IBSS = 0x20, // IBSS supported
# APPLE80211_C_FLAG_HOST_AP = 0x40, // HOST AP mode supported
# APPLE80211_C_FLAG_ACTIVE = 0x80, // active scanning supported
# APPLE80211_C_FLAG_DFS = 0x100, // DFS required
# APPLE80211_C_FLAG_EXT_ABV = 0x200, // If 40 Mhz, extension channel above.
# // If this flag is not set, then the
# // extension channel is below.
# };
printf "%s" "$airport_output" > $scandata &
pid=$!
wait $pid
if [ ! -s $scandata ]; then
echo "Scandata file is empty"
exit 1
fi
#echo $airport_output > tempfile && cp tempfile $scandata # This is a hack to wait for the completion of writing data
# printf "%s" "$airport_output" > "$scandata" &
# pid=$!
# wait $pid
wlan_scan_on="true"
precount=$(
"$plistbuddy" "${scandata}" -c "print ::" | # Extract array items
cat -v | # Convert from binary output to ascii
grep -E "^\s{4}Dict" | # Search for top-level dictionaries
wc -l | # Count top-level dictionaries
xargs # Trim whitespace
)
count=$(expr "${precount}" - 1)
for i in $(seq 0 "${count}")
do
wlan_scan_ssid=$("$plistbuddy" "$scandata" -c "print :$i:SSID_STR")
wlan_scan_bssid=$("${plistbuddy}" "${scandata}" -c "print :$i:BSSID" 2>/dev/null)
#wlan_scan_bssid_tag=$(echo -n "$wlan_scan_bssid") # BSSID should be a clean string as opposed to using SSID as a tag which needs to escape spaces with backslash \
wlan_scan_channel_flags=$("${plistbuddy}" "${scandata}" -c "print :$i:CHANNEL_FLAGS")
wlan_scan_channel_flags_binary=$(echo "obase=2;$wlan_scan_channel_flags" | bc)
wlan_scan_channel_flags_length=${#wlan_scan_channel_flags_binary}
wlan_scan_channel_flags_binary_pad_bits=$(printf "%016.0f" "$wlan_scan_channel_flags_binary")
last_bits=${wlan_scan_channel_flags_binary_pad_bits: -5}
two_ghz_bit=${last_bits:1:1}
five_ghz_bit=${last_bits:0:1}
channel_width_twenty_mhz=${last_bits:3:1}
channel_width_forty_mhz=${last_bits:2:1}
wlan_scan_capabilities=$("${plistbuddy}" "${scandata}" -c "print :$i:CAPABILITIES")i
wlan_scan_channel=$("${plistbuddy}" "${scandata}" -c "print :$i:CHANNEL")i
wlan_scan_cc=$("${plistbuddy}" "${scandata}" -c "print :$i:80211D_IE:IE_KEY_80211D_COUNTRY_CODE" 2>/dev/null)
wlan_scan_channel_width=$("${plistbuddy}" "${scandata}" -c "print :$i:CHANNEL_WIDTH" 2>/dev/null) # Doesn't work on Big Sur but does on Ventura? Go figure.
wlan_scan_ht_secondary_chan_offset=$("${plistbuddy}" "${scandata}" -c "print :$i:HT_IE:HT_SECONDARY_CHAN_OFFSET" 2>/dev/null)i
wlan_scan_rssi=$("${plistbuddy}" "${scandata}" -c "print :$i:RSSI")i
wlan_scan_noise=$("${plistbuddy}" "${scandata}" -c "print :$i:NOISE")i
wlan_scan_vht_op_channel_center_frequency_seg0=$("${plistbuddy}" "${scandata}" -c "print :$i:VHT_OP:CHANNEL_CENTER_FREQUENCY_SEG0" 2>/dev/null)i
wlan_scan_vht_op_channel_center_frequency_seg1=$("${plistbuddy}" "${scandata}" -c "print :$i:VHT_OP:CHANNEL_CENTER_FREQUENCY_SEG1" 2>/dev/null)i
wlan_scan_vht_op_channel_width=$("${plistbuddy}" "${scandata}" -c "print :$i:VHT_OP:CHANNEL_WIDTH" 2>/dev/null)i
wlan_scan_he_any=$("${plistbuddy}" "${scandata}" -c "print :$i:HE_OP_IE:BSS_COLOR" 2>/dev/null)i
wlan_scan_channel_frequency=$(echo "$wlan_sp_airport_data_type" | egrep -i -A2000 "Other Local Wi-Fi Networks" | egrep -i -A2 "$wlan_scan_ssid" | egrep -i "${wlan_scan_channel%?}"| egrep -oi "2ghz|5ghz|6ghz" ) # This doesn't work on non-M2
# Explicit defaults rather than {:=} expansion
# What about to guess the PHY?
if [ "$wlan_scan_ht_secondary_chan_offset" != "i" ]; then
wlan_scan_80211n="true"
else
wlan_scan_80211n="false"
fi
if [ "$wlan_scan_vht_op_channel_center_frequency_seg0" != "i" ]; then
wlan_scan_80211ac="true"
else
wlan_scan_80211ac="false"
fi
if [ "$wlan_scan_he_any" != "i" ]; then
wlan_scan_80211ax="true"
else
wlan_scan_80211ax="false"
fi
if [ $wlan_scan_ht_secondary_chan_offset == "i" ]; then
wlan_scan_ht_secondary_chan_offset="0i"
fi
if [ $wlan_scan_vht_op_channel_center_frequency_seg0 == "i" ]; then
wlan_scan_vht_op_channel_center_frequency_seg0="0i"
fi
if [ $wlan_scan_vht_op_channel_center_frequency_seg1 == "i" ]; then
wlan_scan_vht_op_channel_center_frequency_seg1="0i"
fi
if [ $wlan_scan_vht_op_channel_width == "i" ]; then
wlan_scan_vht_op_channel_width="0i"
fi
fieldset=$( echo -n "wlan_scan_ssid=\"$wlan_scan_ssid\",wlan_scan_bssid=\"$wlan_scan_bssid\",\nwlan_scan_channel_flags=$wlan_scan_channel_flags,\nwlan_scan_channel_flags_binary=$wlan_scan_channel_flags_binary,\nwlan_scan_channel_flags_binary_pad_bits=$wlan_scan_channel_flags_binary_pad_bits,\ntwo_ghz_bit=$two_ghz_bit,\nfive_ghz_bit=$five_ghz_bit,\nchannel_width_twenty_mhz=$channel_width_twenty_mhz,\nchannel_width_forty_mhz=$channel_width_forty_mhz,\nwlan_scan_capabilities=$wlan_scan_capabilities,\nwlan_scan_channel=$wlan_scan_channel,wlan_scan_channel_width=\"${wlan_scan_channel_width:=not_listed}\",wlan_scan_rssi=$wlan_scan_rssi,wlan_scan_noise=$wlan_scan_noise,\nwlan_scan_80211n=$wlan_scan_80211n,\nwlan_scan_80211ac=$wlan_scan_80211ac,\nwlan_scan_80211ax=$wlan_scan_80211ax,\nwlan_scan_frequency=\"${wlan_scan_channel_frequency:=not_listed}\",\nwlan_scan_vht_op_channel_center_frequency_seg0=$wlan_scan_vht_op_channel_center_frequency_seg0,\nwlan_scan_vht_op_channel_center_frequency_seg1=$wlan_scan_vht_op_channel_center_frequency_seg1,\nwlan_scan_vht_op_channel_width=$wlan_scan_vht_op_channel_width,\nwlan_scan_ht_secondary_chan_offset=$wlan_scan_ht_secondary_chan_offset,\nwlan_scan_cc=\"${wlan_scan_cc:=none}\"")
echo -ne "$fieldset\n\n"
done
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment