Last active
October 18, 2023 20:26
-
-
Save donalod/489271adb9e92ae52810355ea04428a4 to your computer and use it in GitHub Desktop.
apple80211_channel_flags_extract.sh
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/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