The answer beneath may appear over-complicated, however each single line is essential to totally restore community connectivity. Even then, there are some edge circumstances the place the script would not work and I’ve to reboot my machine. If you understand of a greater resolution, please let me know.
1. Export working community settings
Reboot the machine, hook up with the hotspot, after which persist the right community configuration utilizing the next Python script. You’ll be able to change the WIFI_DEVICE_NAME
to ‘iPhone USB’ to persist (and later restore) USB tethering community settings.
import subprocess
import re
import json
WIFI_DEVICE_NAME = "Wi-Fi"
def get_network_info():
hardware_ports = subprocess.check_output(
["networksetup", "-listallhardwareports"],
textual content=True
)
wifi_match = re.search(
f"{Hardware} Port: {WIFI_DEVICE_NAME}nDevice: (w+)",
hardware_ports
)
if not wifi_match:
elevate Exception("No Wi-Fi interface discovered")
interface = wifi_match.group(1)
ifconfig_output = subprocess.check_output(
f"ifconfig {interface}",
shell=True
).decode().splitlines()
ipv4_address = None
ipv6_addresses = []
for line in ifconfig_output:
if "inet " in line:
ipv4_address = line.break up()[1]
elif "inet6 " in line:
ipv6_addresses.append(line.break up()[1].break up("%")[0])
netstat_output = subprocess.check_output(
f"netstat -nr | grep default | grep {interface}",
shell=True
).decode().splitlines()
ipv4_router = ipv6_router = None
for line in netstat_output:
elements = line.break up()
if len(elements) > 1:
if ":" not in elements[1]:
ipv4_router = elements[1]
else:
ipv6_router = elements[1].break up("%")[0]
config = {
"network_service_name": WIFI_DEVICE_NAME,
"network_interface_id": interface,
"ipv4_address": ipv4_address or "Unknown",
"ipv4_subnet_mask": "255.255.255.0",
"ipv4_router": ipv4_router or "Unknown",
"ipv6_primary_address": ipv6_addresses[0] if ipv6_addresses else "Unknown",
"ipv6_temporary_address": ipv6_addresses[1] if ipv6_addresses[1:] else "Unknown",
"ipv6_clat46_address": ipv6_addresses[2] if ipv6_addresses[2:] else "Unknown",
"ipv6_prefix_length": "64",
"ipv6_router": ipv6_router or "Unknown",
}
config_filename = f"network_settings_{interface}.json"
with open(config_filename, "w") as f:
json.dump(config, f, indent=2)
print(f"Saved config for {WIFI_DEVICE_NAME} ({interface}) to {config_filename}")
if __name__ == "__main__":
get_network_info()
The Python script will generate a JSON file with working IPv4 and IPv6 settings throughout the identical folder.
2. Restore community settings from the config file, then flip auto/DHCP routing again on
Create one other Python script. Observe that working it requires sudo entry, as a result of altering most community settings on Mac can’t be completed with out sudo
privileges.
import subprocess
import json
import time
def run_cmd(cmd, ignore_errors=False):
attempt:
subprocess.run(cmd, verify=True)
print(f"Success: {' '.be a part of(cmd)}")
return True
besides subprocess.CalledProcessError as e:
if not ignore_errors:
print(f"Failed: {' '.be a part of(cmd)}: {e}")
return False
def test_network(config_file):
# Load configuration
with open(config_file) as f:
config = json.load(f)
print("nSetting handbook IP configuration...")
# Configure IPv4 settings
run_cmd([
"sudo", "networksetup", "-setmanual",
config["network_service_name"],
config["ipv4_address"],
config["ipv4_subnet_mask"],
config["ipv4_router"]
])
# Replace IPv4 routing
run_cmd(["sudo", "route", "delete", "default"])
run_cmd(["sudo", "route", "add", "default", config["ipv4_router"]])
# Configure IPv6 settings
run_cmd([
"sudo", "networksetup", "-setv6manual",
config["network_service_name"],
config["ipv6_primary_address"],
config["ipv6_prefix_length"],
config["ipv6_router"]
])
# Add extra IPv6 addresses
run_cmd([
"sudo", "ifconfig", config["network_interface_id"],
"inet6", "add", config["ipv6_temporary_address"],
"prefixlen", config["ipv6_prefix_length"]
])
run_cmd([
"sudo", "ifconfig", config["network_interface_id"],
"inet6", "add", config["ipv6_clat46_address"],
"prefixlen", config["ipv6_prefix_length"]
])
# Replace IPv6 routing
run_cmd(["sudo", "route", "delete", "-inet6", "default"], ignore_errors=True)
run_cmd([
"sudo", "route", "add", "-inet6", "default",
f"{config['ipv6_router']}%{config['network_interface_id']}"
])
print("nWait for 1 second earlier than resetting again to auto/DHCP community configuration...n")
time.sleep(1)
print("Resetting to computerized configuration...")
# Take away all configured IP addresses
output = subprocess.check_output(
f"ifconfig {config['network_interface_id']}",
shell=True
).decode().splitlines()
for line in output:
if "inet " in line:
run_cmd([
"sudo", "ifconfig", config["network_interface_id"],
"inet", line.break up()[1], "take away"
])
elif "inet6 " in line:
run_cmd([
"sudo", "ifconfig", config["network_interface_id"],
"inet6", "del", line.break up()[1]
])
# Reset to computerized configuration
run_cmd(["sudo", "networksetup", "-setdhcp", config["network_service_name"]])
run_cmd(["sudo", "networksetup", "-setv6automatic", config["network_service_name"]])
if __name__ == "__main__":
import sys
test_network(sys.argv[1])
When tethering stops working, execute the script, passing the generated config file identify into it:
python3 load_working_network_settings.py network_settings_en0.json
Voila! Your web entry ought to (hopefully) be restored now.