#!/bin/zsh DNS_SERVER="45.8.173.221" printf "应用桥:1 设置热点 DNS;2 恢复原设置\n" read -r choice /usr/bin/sudo /usr/bin/python3 - "$choice" "$DNS_SERVER" <<'APPLICATION_BRIDGE_PY' """Standalone macOS Internet Sharing DHCP DNS helper, embedded in a download.""" import copy import ipaddress import json import os from pathlib import Path import plistlib import pwd import re import subprocess import sys import tempfile def main(): if os.geteuid()!=0:raise ValueError('需要管理员权限修改热点 DHCP 配置') uid=int(os.environ.get('SUDO_UID','0')) account=pwd.getpwuid(uid) folder=Path(account.pw_dir)/'Library/Application Support/ApplicationBridge' folder.mkdir(parents=True,exist_ok=True,mode=0o700) os.chown(folder,uid,account.pw_gid) record=folder/'hotspot-dns.json' config_file=Path('/etc/bootpd.plist') config=plistlib.loads(config_file.read_bytes()) action=sys.argv[1] if action=='1': if record.exists():raise ValueError('已有未恢复设置,请先选择 2 恢复;未覆盖恢复记录') resolver=str(ipaddress.IPv4Address(sys.argv[2])) if not ipaddress.ip_address(resolver).is_global: raise ValueError('此工具需要实际公网 DNS 地址;本机开发预览地址不能用于车机热点') matches=[x for x in config.get('Subnets',[]) if x.get('_creator')=='com.apple.NetworkSharing' and x.get('interface') in config.get('dhcp_enabled',[])] if len(matches)!=1:raise ValueError('请先开启唯一的 Wi-Fi 互联网共享热点') subnet=matches[0] state={'interface':subnet['interface'],'network':subnet['net_address'], 'present':'dhcp_domain_name_server' in subnet, 'original':copy.deepcopy(subnet.get('dhcp_domain_name_server')),'resolver':resolver} with record.open('x') as f: os.fchmod(f.fileno(),0o600);os.fchown(f.fileno(),uid,account.pw_gid) json.dump(state,f) subnet['dhcp_domain_name_server']=[resolver] elif action=='2': if not record.exists():print('没有待恢复的热点 DNS 设置');return state=json.loads(record.read_text()) if not re.fullmatch(r'bridge[0-9]+',state['interface']):raise ValueError('恢复记录接口无效') ipaddress.IPv4Address(state['network']);ipaddress.IPv4Address(state['resolver']) for value in state.get('original') or []:ipaddress.ip_address(value) matches=[x for x in config.get('Subnets',[]) if x.get('_creator')=='com.apple.NetworkSharing' and x.get('interface')==state['interface'] and x.get('net_address')==state['network']] if len(matches)!=1:raise ValueError('共享子网已变化,未覆盖当前配置') subnet=matches[0] if subnet.get('dhcp_domain_name_server') not in ([state['resolver']],state['original']): raise ValueError('DNS 已被其他操作改动,未覆盖当前设置') if state['present']:subnet['dhcp_domain_name_server']=state['original'] else:subnet.pop('dhcp_domain_name_server',None) else:raise ValueError('请选择 1 或 2') info=config_file.stat();fd,name=tempfile.mkstemp(prefix='.appbridge-',dir=str(config_file.parent)) try: with os.fdopen(fd,'wb') as f: os.fchmod(f.fileno(),info.st_mode&0o777);os.fchown(f.fileno(),info.st_uid,info.st_gid) plistlib.dump(config,f);f.flush();os.fsync(f.fileno()) os.replace(name,config_file) finally: if os.path.exists(name):os.unlink(name) running=subprocess.run(['/bin/launchctl','print','system/com.apple.bootpd'],capture_output=True,text=True) if running.returncode==0 and 'state = running' in running.stdout: subprocess.run(['/bin/launchctl','kill','SIGHUP','system/com.apple.bootpd'],check=True,capture_output=True) if action=='2':record.unlink() print('热点 DHCP DNS 已更新;Mac 自身上联 DNS 保持原样。请让车机重新连接热点。') if __name__=='__main__': try:main() except Exception as error: print('操作未完成:'+str(error),file=sys.stderr) sys.exit(1) APPLICATION_BRIDGE_PY printf "\n请让车机断开重连热点。按回车关闭。" read -r