Last active
November 28, 2025 21:13
-
-
Save gumayunov/2b60bf111e60af9bed6f3d6e00576f2a to your computer and use it in GitHub Desktop.
This file contains hidden or 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
| #!/bin/bash | |
| # Universal macOS Network Cleanup Script | |
| # Fixes most common network issues without reboot | |
| echo "========================================" | |
| echo "macOS Network Cleanup" | |
| echo "========================================" | |
| echo "" | |
| # Safety check | |
| read -p "This will disconnect VPNs temporarily. Continue? (y/n) " -n 1 -r | |
| echo "" | |
| if [[ ! $REPLY =~ ^[Yy]$ ]]; then | |
| echo "Cancelled." | |
| exit 1 | |
| fi | |
| echo "Starting cleanup..." | |
| echo "" | |
| # 1. Disconnect all VPNs | |
| echo "Step 1/7: Disconnecting VPNs..." | |
| scutil --nc list 2>/dev/null | grep "Connected" | while read line; do | |
| NAME=$(echo "$line" | sed 's/.*"\(.*\)".*/\1/') | |
| echo " Stopping: $NAME" | |
| scutil --nc stop "$NAME" 2>/dev/null | |
| done | |
| sleep 3 | |
| # 2. Remove orphaned IPv6 default routes | |
| echo "Step 2/7: Removing orphaned IPv6 routes..." | |
| netstat -rn | grep "^default.*fe80.*utun" | awk '{print $5}' | sort -u | while read iface; do | |
| echo " Removing default via $iface" | |
| sudo route delete -inet6 default -interface $iface 2>/dev/null | |
| sudo route delete -inet6 default -interface $iface 2>/dev/null # duplicates | |
| done | |
| for i in {0..20}; do | |
| sudo route delete -inet6 default -interface utun$i 2>/dev/null | |
| done | |
| # 3. Flush routing table | |
| echo "Step 3/7: Flushing IPv6 routes..." | |
| sudo route -n flush -inet6 2>/dev/null | |
| # 4. Clear pf states | |
| echo "Step 4/7: Clearing packet filter states..." | |
| sudo pfctl -F states 2>/dev/null | |
| # 5. Remove dead utun interfaces | |
| echo "Step 5/7: Removing dead utun interfaces..." | |
| for i in {0..20}; do | |
| # Try destroy first | |
| sudo ifconfig utun$i destroy 2>/dev/null && echo " Destroyed utun$i" | |
| # Then try down | |
| sudo ifconfig utun$i down 2>/dev/null | |
| done | |
| # 6. Restart network daemons | |
| echo "Step 6/7: Restarting network services..." | |
| sudo killall -HUP configd 2>/dev/null | |
| sudo killall -HUP mDNSResponder 2>/dev/null | |
| sudo dscacheutil -flushcache 2>/dev/null | |
| # 7. Cycle WiFi (optional but effective) | |
| echo "Step 7/7: Cycling WiFi interface..." | |
| WIFI_DEVICE=$(networksetup -listallhardwareports | awk '/Wi-Fi/{getline; print $2}') | |
| if [ ! -z "$WIFI_DEVICE" ]; then | |
| echo " Restarting $WIFI_DEVICE..." | |
| sudo ifconfig $WIFI_DEVICE down | |
| sleep 2 | |
| sudo ifconfig $WIFI_DEVICE up | |
| sleep 3 | |
| fi | |
| echo "" | |
| echo "========================================" | |
| echo "Cleanup Complete!" | |
| echo "========================================" | |
| echo "" | |
| echo "Running diagnostic to verify..." | |
| sleep 2 | |
| ~/network_diagnostic.sh | |
| echo "" | |
| echo "👉 You can now reconnect your VPN if needed." | |
| echo "👉 If problems persist, reboot may be necessary." |
This file contains hidden or 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
| #!/bin/bash | |
| # Universal macOS Network Diagnostic Script | |
| # Helps diagnose "Cannot allocate memory" and other network issues | |
| echo "========================================" | |
| echo "macOS Network Diagnostic Report" | |
| echo "Generated: $(date)" | |
| echo "========================================" | |
| echo "" | |
| # 1. Basic network stats | |
| echo "=== BASIC STATISTICS ===" | |
| ACTIVE=$(netstat -an | grep ESTABLISHED | wc -l | tr -d ' ') | |
| TIMEWAIT=$(netstat -an | grep TIME_WAIT | wc -l | tr -d ' ') | |
| ROUTES=$(netstat -rn | wc -l | tr -d ' ') | |
| UTUNS=$(ifconfig | grep "^utun" | wc -l | tr -d ' ') | |
| echo "Active connections: $ACTIVE" | |
| echo "TIME_WAIT sockets: $TIMEWAIT" | |
| echo "Total routes: $ROUTES" | |
| echo "UTun interfaces: $UTUNS" | |
| # Warnings | |
| [ $ACTIVE -gt 1000 ] && echo "⚠️ WARNING: Too many active connections!" | |
| [ $TIMEWAIT -gt 200 ] && echo "⚠️ WARNING: Too many TIME_WAIT sockets!" | |
| [ $ROUTES -gt 500 ] && echo "🔴 CRITICAL: Too many routes! (should be ~150-200)" | |
| [ $UTUNS -gt 15 ] && echo "🔴 CRITICAL: Too many utun interfaces!" | |
| echo "" | |
| # 2. UTun interface details | |
| echo "=== UTUN INTERFACES DETAIL ===" | |
| ACTIVE_UTUNS=0 | |
| DEAD_UTUNS=0 | |
| for i in {0..30}; do | |
| if ifconfig utun$i &>/dev/null 2>&1; then | |
| # Check if UP and has IP | |
| if ifconfig utun$i | grep -q "flags=.*UP"; then | |
| HAS_IP=$(ifconfig utun$i | grep -E "inet |inet6 [^f]" | grep -v "fe80::" | wc -l | tr -d ' ') | |
| if [ $HAS_IP -gt 0 ]; then | |
| IP=$(ifconfig utun$i | grep "inet " | awk '{print $2}' | head -1) | |
| echo " utun$i: ✅ ACTIVE (IP: ${IP:-IPv6 only})" | |
| ACTIVE_UTUNS=$((ACTIVE_UTUNS + 1)) | |
| else | |
| echo " utun$i: ⚠️ UP but no IP (orphaned/dead)" | |
| DEAD_UTUNS=$((DEAD_UTUNS + 1)) | |
| fi | |
| else | |
| echo " utun$i: ❌ DOWN" | |
| DEAD_UTUNS=$((DEAD_UTUNS + 1)) | |
| fi | |
| fi | |
| done | |
| echo "" | |
| echo "Summary: $ACTIVE_UTUNS active, $DEAD_UTUNS dead/orphaned" | |
| if [ $DEAD_UTUNS -gt 5 ]; then | |
| echo "🔴 PROBLEM DETECTED: Too many dead utun interfaces!" | |
| echo " This is likely causing your network issues." | |
| fi | |
| echo "" | |
| # 3. VPN Status | |
| echo "=== VPN CONNECTIONS ===" | |
| scutil --nc list 2>/dev/null | grep -E "Connected|Disconnected" | while read line; do | |
| STATUS=$(echo "$line" | grep -oE "Connected|Disconnected") | |
| NAME=$(echo "$line" | sed 's/.*"\(.*\)".*/\1/') | |
| if [ "$STATUS" = "Connected" ]; then | |
| echo " ✅ $NAME - Connected" | |
| else | |
| echo " ⭕ $NAME - Disconnected" | |
| fi | |
| done | |
| echo "" | |
| # 4. Default routes check | |
| echo "=== DEFAULT ROUTES ===" | |
| DEFAULT_COUNT=$(netstat -rn | grep "^default" | wc -l | tr -d ' ') | |
| echo "Total default routes: $DEFAULT_COUNT" | |
| if [ $DEFAULT_COUNT -gt 3 ]; then | |
| echo "⚠️ WARNING: Too many default routes!" | |
| fi | |
| echo "" | |
| echo "IPv4 defaults:" | |
| netstat -rn | grep "^default" | grep -v "inet6\|fe80" || echo " None" | |
| echo "" | |
| echo "IPv6 defaults:" | |
| netstat -rn | grep "^default" | grep -E "inet6|fe80" || echo " None" | |
| # Check for orphaned IPv6 defaults | |
| ORPHANED_V6=$(netstat -rn | grep "^default.*fe80.*utun" | wc -l | tr -d ' ') | |
| if [ $ORPHANED_V6 -gt 1 ]; then | |
| echo "" | |
| echo "🔴 PROBLEM: $ORPHANED_V6 orphaned IPv6 default routes detected!" | |
| netstat -rn | grep "^default.*fe80.*utun" | head -5 | |
| fi | |
| echo "" | |
| # 5. Routes through dead utun | |
| echo "=== ROUTES THROUGH DEAD UTUN ===" | |
| DEAD_ROUTES=$(netstat -rn | grep -E "utun" | wc -l | tr -d ' ') | |
| echo "Total routes through utun interfaces: $DEAD_ROUTES" | |
| if [ $DEAD_ROUTES -gt 50 ]; then | |
| echo "⚠️ This might be excessive. Showing sample:" | |
| netstat -rn | grep -E "utun[0-9]" | head -10 | |
| fi | |
| echo "" | |
| # 6. Network Extension processes | |
| echo "=== NETWORK EXTENSION PROCESSES ===" | |
| ps aux | grep -iE "vpn|network.*extension|packet.*tunnel|wireguard|openvpn|outline|tailscale" | grep -v grep | awk '{print $11}' | sort -u || echo " None found" | |
| echo "" | |
| # 7. Socket/descriptor limits | |
| echo "=== SYSTEM LIMITS ===" | |
| echo "Max files (soft/hard): $(launchctl limit maxfiles 2>/dev/null || echo 'N/A')" | |
| OPEN_FILES=$(lsof -n | wc -l | tr -d ' ') | |
| echo "Currently open files: $OPEN_FILES" | |
| echo "" | |
| # 8. Summary and recommendations | |
| echo "========================================" | |
| echo "SUMMARY & RECOMMENDATIONS" | |
| echo "========================================" | |
| ISSUES=0 | |
| if [ $ROUTES -gt 500 ]; then | |
| echo "❌ ISSUE #$((++ISSUES)): Too many routes ($ROUTES)" | |
| echo " → Run cleanup script to flush orphaned routes" | |
| fi | |
| if [ $DEAD_UTUNS -gt 5 ]; then | |
| echo "❌ ISSUE #$((++ISSUES)): Too many dead utun interfaces ($DEAD_UTUNS)" | |
| echo " → VPN clients not cleaning up properly" | |
| fi | |
| if [ $ORPHANED_V6 -gt 1 ]; then | |
| echo "❌ ISSUE #$((++ISSUES)): Orphaned IPv6 default routes ($ORPHANED_V6)" | |
| echo " → This commonly causes 'Cannot allocate memory' errors" | |
| fi | |
| if [ $TIMEWAIT -gt 200 ]; then | |
| echo "⚠️ ISSUE #$((++ISSUES)): Many TIME_WAIT sockets ($TIMEWAIT)" | |
| echo " → May indicate connection leaks" | |
| fi | |
| if [ $ISSUES -eq 0 ]; then | |
| echo "✅ No obvious network issues detected!" | |
| echo " If you still have problems, check application-specific logs." | |
| else | |
| echo "" | |
| echo "👉 To fix detected issues, run the cleanup script." | |
| fi | |
| echo "" | |
| echo "========================================" | |
| echo "Report saved to: /tmp/network_diagnostic_$(date +%Y%m%d_%H%M%S).txt" | |
| echo "========================================" |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment