Skip to content

Instantly share code, notes, and snippets.

@gumayunov
Last active November 28, 2025 21:13
Show Gist options
  • Select an option

  • Save gumayunov/2b60bf111e60af9bed6f3d6e00576f2a to your computer and use it in GitHub Desktop.

Select an option

Save gumayunov/2b60bf111e60af9bed6f3d6e00576f2a to your computer and use it in GitHub Desktop.
#!/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."
#!/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