Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

DNS + mac os 14.4.1 ready #46

Open
wants to merge 9 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 8 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
# Mac OSX Wi-Fi Location Changer
# Mac OSX Wi-Fi Location & DNS Changer

* Automatically changes the Mac OSX network location when a configured Wi-Fi (SSID) becomes connected
* Automatically changes the Mac OSX network location & custom DNS settings when a configured Wi-Fi (SSID) becomes connected
* Allows having different IP settings depending on the Wi-Fi SSID
* Offers hook to run external script when location changes
* macOS Sonoma 14.4.1 tested

## Configuration
Create a configuration file using the sample:
Expand All @@ -21,9 +22,13 @@ If your SSID is instead a name like Wu Tang LAN, with spaces, then use quotes ar

`home "Wu Tang LAN"`

If no DNS defined, the DNS will be cleared to prevent stucking in the past DNS settings. To define the DNS servers, use quotes around the adress.

`home "Wu Tang LAN" "8.8.8.8"`

**Note:** Ensure you use the exact location names as they appear under "Location" in OSX's System Preferences -> Network, and for SSIDs in your Wi-Fi menu. Capitalization must match! Spaces must match within a quoted name!

Add as many location + SSID lines as you like to the configuration file.
Add as many location + SSID lines + DNS as you like to the configuration file.

### MacOS Notifications
The script triggers a MacOS Notification upon changing location. If you don't want this just delete the lines that start with `osascript`.
Expand Down
107 changes: 77 additions & 30 deletions locationchanger
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,12 @@ sleep 2
SCRIPT_DIR=$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )

# get SSID
SSID=`/System/Library/PrivateFrameworks/Apple80211.framework/Versions/A/Resources/airport -I | awk -F ' SSID: ' '/ SSID:/ {print $2}'`
# SSID=`/System/Library/PrivateFrameworks/Apple80211.framework/Versions/A/Resources/airport -I | awk -F ' SSID: ' '/ SSID:/ {print $2}'`
#SSID=`networksetup -getairportnetwork en0 | awk -F ' SSID: ' '/ SSID:/ {print $2}'`
SSID=`networksetup -getairportnetwork en0 | awk -F ': ' '{print $2}'`
echo `date` "New SSID found: $SSID"


# empty location var
LOCATION=

Expand All @@ -42,6 +45,16 @@ SSID_TelekomPublic=Telekom
SSID_Home=HomeSSID
SSID_Work=WorkSSID

# empty location var (for DNS changer, DNS config needs to be done in the external config file)
DNS=
DNS_Home="8.8.8.8"

# LOCATIONS
# (use to be used Location name here)
# =============================================
Location_Automatic="Automatic"
Location_Home="Home"
Location_Work="Company Intranet"

# SSID -> LOCATION mapping
case $SSID in
Expand All @@ -52,46 +65,79 @@ case $SSID in
esac
REASON="SSID changed to $SSID"

# process mapping from text file
MAP_FILE=$SCRIPT_DIR/locationchanger.conf
if [ -f "$MAP_FILE" ]; then
# echo "Checking mappings from file \"$MAP_FILE\""
while IFS=' ' read -r loc wifi
do
if [[ "${loc}" == "#"* ]]; then
true # ignore comments
elif [ -z "${loc}" ]; then
true # ignore empty lines
else
wifi=$(echo $wifi | tr -d '"' ) # remove quotes
# echo "location, wifi: \"$loc\", \"$wifi\" "
if [[ "$wifi" == "$SSID" ]]; then
LOCATION="$loc"
REASON="SSID changed to $SSID using mapping file"
break
fi
fi
done < "$MAP_FILE"
echo "Checking mappings from file $MAP_FILE"
while IFS= read -r line || [ -n "$line" ]; do
# Ignore comments and empty lines
if [[ "$line" =~ ^#.* ]] || [ -z "$line" ]; then
continue
fi

# Extract fields using regular expression to handle quoted strings
loc=$(echo "$line" | awk '{print $1}')
wifi=$(echo "$line" | awk -F'"' '{print $2}')
dns=$(echo "$line" | awk -F'"' '{print $4}')

echo "Location: $loc, WiFi: $wifi, DNS: $dns"

if [[ "$wifi" == "$SSID" ]]; then
LOCATION="$loc"
DNS_SETTING="$dns"
REASON="Info : SSID changed to $SSID using mapping file"
break
fi
done < "$MAP_FILE"
fi

# still didn't get a location -> use Location_Automatic
# still didn't get a location -> no match between saved SSID and actual SSID -> use Location_Automatic
if [ -z "$LOCATION" ]; then
LOCATION="$Location_Automatic"
REASON="Automatic Fallback"
REASON=""
sudo networksetup -setdnsservers "Wi-Fi" "Empty" >/dev/null 2>&1
echo "Info: Automatic Fallback (undefined wifi) ==> DNS cleared & Location set to Automatic"
echo "" # add linefeed after output from networksetup
exit 1
fi

# Don't change if we're already there
current_location=$(networksetup -getcurrentlocation)
if [ "$current_location" = "$LOCATION" ]; then
exit
# Check if both the current location and DNS are the same as the desired ones
if [ "$current_location" = "$LOCATION" ] && [ "$current_dns" = "$dns" ]; then
echo "Info: Both location and DNS are already set correctly. No need to change."
exit 1
fi

# change network location: will output "found it!"
if ! networksetup -switchtolocation "$LOCATION"; then
osascript -e "display notification \"Failed to Change Network Location to: $LOCATION\" with title \"Network Update Failure\""
exit 1
if [ "$current_location" != "$LOCATION" ]; then
echo "Info: Updating network location to $LOCATION..."
osascript -e "display notification \"Succeeded to Change Network Location to: $LOCATION\" with title \"Network Update Succes\""
networksetup -switchtolocation "$LOCATION" >/dev/null 2>&1
else
echo "Error: Unable to update network location to $LOCATION..."
osascript -e "display notification \"Failed to Change Network Location to: $LOCATION\" with title \"Network Update Failure\""
fi

# Check if the DNS value is empty
if [ -z "$dns" ] || [ "$dns" == "\"\"" ]; then
echo "Info: DNS from Config empty."
sudo networksetup -setdnsservers "Wi-Fi" "Empty" >/dev/null 2>&1
if [ $? -eq 0 ]; then
echo "Info: DNS variable is empty, DNS servers have been cleared."
osascript -e "display notification \"Successfully cleared DNS\" with title \"DNS Update Success\""
else
echo "Error: Failed to clear DNS."
osascript -e "display notification \"Failed to clear DNS\" with title \"DNS Update Failure\""
fi
else
# If the DNS value is not empty, set the DNS to the specified value
echo "Info: DNS from Config defined."
sudo networksetup -setdnsservers "Wi-Fi" "$dns" >/dev/null 2>&1
if [ $? -eq 0 ]; then
echo "Info: DNS updated to \"$dns\"."
osascript -e "display notification \"Successfully updated DNS to: $dns\" with title \"DNS Update Success\""
else
echo "Error: Failed to update DNS to \"$dns\"."
osascript -e "display notification \"Failed to update DNS to $dns\" with title \"DNS Update Failure\""
fi
fi
echo "" # add linefeed after output from networksetup

# if present, callout to an external script
# use this script's dir and also a file-naming convention to determine if there is an external script to be run
Expand All @@ -106,5 +152,6 @@ fi
osascript -e "display notification \"Network Location Changed to $LOCATION\" with title \"Network Update\""

echo "--> Location Changer: $LOCATION - $REASON"
echo "" # add linefeed after output from networksetup

exit 0
2 changes: 1 addition & 1 deletion locationchanger.conf.sample
Original file line number Diff line number Diff line change
Expand Up @@ -9,5 +9,5 @@
#
# For example:
# Home myHomeWifiSSID
# Work "my Work Wifi"
# Work "my Work Wifi" "8.8.8.8"