summaryrefslogtreecommitdiff
path: root/.config/scripts/network.sh
diff options
context:
space:
mode:
authorsilly <u65487754@gmail.com>2026-04-07 05:20:08 +0000
committerGitHub <noreply@github.com>2026-04-07 05:20:08 +0000
commit1464a8a62bcd0e80fdf0fbfc1751428566abf77c (patch)
tree4ba2d317d09acebc1f2487fe25156d3df3ac07f5 /.config/scripts/network.sh
parent75d3cfbb6be6f1640b3dfb0965ff4b2a9070ec4c (diff)
Create network.sh
Diffstat (limited to '.config/scripts/network.sh')
-rw-r--r--.config/scripts/network.sh227
1 files changed, 227 insertions, 0 deletions
diff --git a/.config/scripts/network.sh b/.config/scripts/network.sh
new file mode 100644
index 0000000..70f01e8
--- /dev/null
+++ b/.config/scripts/network.sh
@@ -0,0 +1,227 @@
+#!/bin/bash
+
+WG_DIR="/etc/wireguard"
+LAST_VPN="$HOME/.cache/last_vpn"
+
+notify() {
+ notify-send -a "network" "$1" "$2" 2>/dev/null || true
+}
+
+wg_active() {
+ wg show interfaces 2>/dev/null | tr ' ' '\n' | grep -v '^$'
+}
+
+wg_configs() {
+ for f in "$WG_DIR"/*.conf; do
+ [[ -f "$f" ]] && basename "$f" .conf
+ done
+}
+
+config_prefix() {
+ echo "$1" | grep -oP '^[a-z]+-[a-z]+'
+}
+
+current_ssid() {
+ nmcli -t -f active,ssid dev wifi 2>/dev/null \
+ | awk -F: '/^yes/{print $2}' | head -1
+}
+
+rofi_pick() {
+ rofi -dmenu -p ">"
+}
+
+wg_down() {
+ local iface="$1"
+ sudo bash -c "
+ wg-quick down '$iface' 2>/dev/null || true
+ ip link delete '$iface' 2>/dev/null || true
+ while ip rule del not fwmark 51820 table 51820 2>/dev/null; do :; done
+ while ip rule del table main suppress_prefixlength 0 2>/dev/null; do :; done
+ ip route flush table 51820 2>/dev/null || true
+ while ip -6 rule del not fwmark 51820 table 51820 2>/dev/null; do :; done
+ while ip -6 rule del table main suppress_prefixlength 0 2>/dev/null; do :; done
+ ip -6 route flush table 51820 2>/dev/null || true
+ nft delete table inet wg-quick-'$iface' 2>/dev/null || true
+ resolvconf -u 2>/dev/null || true
+ "
+ local con
+ con=$(nmcli -t -f name,type con show --active 2>/dev/null \
+ | awk -F: '/wireless/{print $1}' | head -1)
+ [[ -n "$con" ]] && nmcli con up "$con" 2>/dev/null
+}
+
+vpn_connect() {
+ local iface="$1"
+ local return_fn="$2"
+ mapfile -t active < <(wg_active)
+ for a in "${active[@]}"; do
+ wg_down "$a"
+ done
+ sudo resolvconf -u 2>/dev/null
+ if sudo wg-quick up "$iface"; then
+ echo "$iface" > "$LAST_VPN"
+ notify "vpn" "connected: $iface"
+ else
+ notify "vpn" "error: $iface"
+ $return_fn
+ fi
+}
+
+
+vpn_servers() {
+ local location="$1"
+ mapfile -t active < <(wg_active)
+ mapfile -t configs < <(wg_configs)
+
+ local options=""
+ for cfg in "${configs[@]}"; do
+ [[ $(config_prefix "$cfg") != "$location" ]] && continue
+ if printf '%s\n' "${active[@]}" | grep -qx "$cfg"; then
+ options+="$cfg (on)\n"
+ else
+ options+="$cfg\n"
+ fi
+ done
+ options+="back"
+
+ local choice
+ choice=$(echo -e "$options" | rofi_pick)
+ [[ "$choice" == "back" || -z "$choice" ]] && { vpn_locations; return; }
+
+ local iface="${choice/ (on)/}"
+
+ if printf '%s\n' "${active[@]}" | grep -qx "$iface"; then
+ if wg_down "$iface"; then
+ notify "vpn" "disconnected: $iface"
+ else
+ notify "vpn" "error: $iface"
+ fi
+ vpn_servers "$location"
+ else
+ vpn_connect "$iface" "vpn_servers $location"
+ fi
+}
+
+vpn_locations() {
+ mapfile -t configs < <(wg_configs)
+
+ declare -A seen
+ local locations=""
+ for cfg in "${configs[@]}"; do
+ local prefix
+ prefix=$(config_prefix "$cfg")
+ if [[ -n "$prefix" && -z "${seen[$prefix]+x}" ]]; then
+ seen[$prefix]=1
+ locations+="$prefix\n"
+ fi
+ done
+ locations+="back"
+
+ local location
+ location=$(echo -e "$locations" | rofi_pick)
+ [[ "$location" == "back" || -z "$location" ]] && { vpn_menu; return; }
+
+ vpn_servers "$location"
+}
+
+vpn_menu() {
+ local active_vpn
+ active_vpn=$(wg_active | head -1)
+
+ local toggle_label
+ [[ -n "$active_vpn" ]] && toggle_label="on" || toggle_label="off"
+
+ local choice
+ choice=$(printf 'locations\n%s\nback\n' "$toggle_label" | rofi_pick)
+
+ case "$choice" in
+ locations) vpn_locations ;;
+ on|off)
+ if [[ -n "$active_vpn" ]]; then
+ if wg_down "$active_vpn"; then
+ notify "vpn" "disconnected: $active_vpn"
+ else
+ notify "vpn" "error: $active_vpn"
+ vpn_menu
+ fi
+ else
+ local last=""
+ [[ -f "$LAST_VPN" ]] && last=$(cat "$LAST_VPN")
+ if [[ -n "$last" ]]; then
+ vpn_connect "$last" vpn_menu
+ else
+ notify "vpn" "no previous server, pick one from locations"
+ vpn_menu
+ fi
+ fi
+ ;;
+ back) main_menu ;;
+ esac
+}
+
+wifi_menu() {
+ local ssid
+ ssid=$(current_ssid)
+
+ local choice
+ choice=$(printf 'scan\ndisconnect\nback' | rofi_pick)
+
+ case "$choice" in
+ scan)
+ nmcli dev wifi rescan 2>/dev/null
+ local networks
+ networks=$(nmcli -t -f ssid,signal,security dev wifi list 2>/dev/null \
+ | awk -F: 'NF>=1 && $1!="" {printf "%-36s %s %s\n", $1, $2, $3}' \
+ | sort -k2 -rn | head -40)
+
+ local picked
+ picked=$(echo "$networks" | rofi_pick)
+ [[ -z "$picked" ]] && { wifi_menu; return; }
+
+ local target
+ target=$(echo "$picked" | awk '{print $1}')
+
+ if ! nmcli dev wifi connect "$target" 2>/dev/null; then
+ local pass
+ pass=$(rofi -dmenu -password -p "password >" < /dev/null)
+ [[ -z "$pass" ]] && { wifi_menu; return; }
+ nmcli dev wifi connect "$target" password "$pass" \
+ && notify "wifi" "connected: $target" \
+ || notify "wifi" "failed: $target"
+ else
+ notify "wifi" "connected: $target"
+ fi
+ wifi_menu
+ ;;
+ disconnect)
+ local con
+ con=$(nmcli -t -f name,type con show --active \
+ | awk -F: '/wireless/{print $1}' | head -1)
+ [[ -n "$con" ]] \
+ && nmcli con down "$con" && notify "wifi" "disconnected" \
+ || notify "wifi" "nothing to disconnect"
+ wifi_menu
+ ;;
+ back) main_menu ;;
+ esac
+}
+
+main_menu() {
+ local ssid
+ ssid=$(current_ssid)
+ local active_vpn
+ active_vpn=$(wg_active | head -1)
+
+ local choice
+ choice=$(printf 'wifi%s\nvpn%s\n' \
+ "${ssid:+ ($ssid)}" \
+ "${active_vpn:+ ($active_vpn)}" \
+ | rofi_pick)
+
+ case "$choice" in
+ wifi*) wifi_menu ;;
+ vpn*) vpn_menu ;;
+ esac
+}
+
+main_menu