detect_router_platform() {
if command -v ndmc >/dev/null 2>&1 || [ -d /opt/etc/ndm ]; then
echo "keenetic"
return
fi
if [ -f /etc/openwrt_release ] || [ -f /etc/openwrt_version ] || \
{ [ -d /etc/config ] && command -v uci >/dev/null 2>&1; }; then
echo "openwrt"
return
fi
case "$(uname -a)" in
*Keenetic*|*Netcraze*|*NDMS*) echo "keenetic"; return ;;
*OpenWrt*|*LEDE*|*ImmortalWrt*) echo "openwrt"; return ;;
esac
if [ -f /etc/debian_version ] || [ -f /etc/os-release ] || \
[ -d /run/systemd/system ] || pidof systemd >/dev/null 2>&1; then
echo "linux"
return
fi
if [ "$(uname -s)" = "Linux" ]; then
echo "linux"
else
echo "unknown"
fi
}
detect_phobos_dir() {
local platform="$1"
if [ "$platform" = "keenetic" ]; then
echo "/opt/etc/Phobos"
elif [ "$platform" = "openwrt" ]; then
echo "/etc/Phobos"
elif [ "$platform" = "linux" ]; then
echo "/opt/Phobos"
else
if [ -d "/opt" ] && [ -d "/opt/etc" ]; then
echo "/opt/etc/Phobos"
else
echo "/etc/Phobos"
fi
fi
}
normalize_arch() {
case "$1" in
x86_64*|x64*|amd64*) echo "x86_64" ;;
aarch64*|arm64*) echo "aarch64" ;;
armv7*|armv6*|armhf*|armel*|arm_*|arm-*|arm) echo "armv7" ;;
mipsel*|mips64el*) echo "mipsel" ;;
mips*) echo "mips" ;;
*) echo "unknown" ;;
esac
}
detect_arch_endianness() {
local base="$1"
local word=$(printf '\1\0' | od -x 2>/dev/null | head -1 | awk '{print $2}')
if [ "$word" = "0001" ]; then
echo "${base}el"
else
echo "$base"
fi
}
detect_arch() {
local raw=""
if [ -r /opt/etc/entware_release ]; then
raw=$(grep '^arch=' /opt/etc/entware_release 2>/dev/null | head -1 | cut -d= -f2)
fi
if [ -z "$raw" ] && [ -r /etc/openwrt_release ]; then
raw=$( . /etc/openwrt_release 2>/dev/null; echo "$DISTRIB_ARCH" )
fi
if [ -z "$raw" ] && command -v opkg >/dev/null 2>&1; then
raw=$(opkg print-architecture 2>/dev/null | grep '^arch ' | grep -v ' all ' | grep -v ' noarch ' | sort -k3 -n | tail -1 | awk '{print $2}')
fi
if [ -z "$raw" ] && command -v apk >/dev/null 2>&1; then
raw=$(apk --print-arch 2>/dev/null)
fi
if [ -z "$raw" ]; then
raw=$(uname -m)
case "$raw" in
mips|mips64) raw=$(detect_arch_endianness "$raw") ;;
esac
fi
normalize_arch "$raw"
}
check_root() {
if [ "$(id -u)" -ne 0 ]; then
echo "Этот скрипт требует root привилегии. Запустите: su -c '$0'"
exit 1
fi
}
log() {
echo "[$(date '+%Y-%m-%d %H:%M:%S')] $*"
}
msg() { printf '%s\n' "$*"; }
print_status() {
local status="$1"
local message="$2"
if [ "${status}" = "OK" ]; then
printf "\\033[0;32m✓\\033[0m %s\n" "${message}"
elif [ "${status}" = "WARN" ]; then
printf "\\033[1;33m⚠\\033[0m %s\n" "${message}"
else
printf "\\033[0;31m✗\\033[0m %s\n" "${message}"
fi
}
PKG_MGR=""
PKG_UPDATE=""
PKG_INSTALL=""
detect_pkg_manager() {
if command -v apk >/dev/null 2>&1; then
PKG_MGR="apk"
PKG_UPDATE="apk update"
PKG_INSTALL="apk add"
elif command -v opkg >/dev/null 2>&1; then
PKG_MGR="opkg"
PKG_UPDATE="opkg update"
PKG_INSTALL="opkg install"
elif command -v apt-get >/dev/null 2>&1; then
PKG_MGR="apt"
PKG_UPDATE="apt-get update"
PKG_INSTALL="apt-get install -y"
else
PKG_MGR=""
fi
}
pkg_update() {
[ -n "$PKG_MGR" ] || return 1
$PKG_UPDATE
}
pkg_install() {
[ -n "$PKG_MGR" ] || return 1
$PKG_INSTALL "$@"
}
compute_slot_names() {
local slot="$1"
local suffix=""
[ "$slot" -gt 0 ] && suffix="$slot"
OBF_BINARY_NAME="wg-obfuscator${suffix}"
OBF_CONF_NAME="wg-obfuscator${suffix}.conf"
OBF_INIT_NAME="S$((49 + slot))wg-obfuscator"
OBF_SERVICE_NAME="phobos-obfuscator${suffix}"
if [ "$ROUTER_PLATFORM" = "openwrt" ]; then
OBF_WG_IFACE="phobos_wg${suffix}"
else
OBF_WG_IFACE="phobos${suffix}"
fi
}
registry_line_for_client() {
[ -f "${PHOBOS_DIR}/registry" ] || return 0
grep "^$1|" "${PHOBOS_DIR}/registry" 2>/dev/null | head -1
}
registry_field() {
echo "$1" | cut -d'|' -f"$2"
}
registry_clients() {
[ -f "${PHOBOS_DIR}/registry" ] || return 0
cut -d'|' -f1 "${PHOBOS_DIR}/registry" 2>/dev/null | grep -v '^$'
}
registry_alloc_slot() {
local max=-1 slot
if [ -f "${PHOBOS_DIR}/registry" ]; then
for slot in $(cut -d'|' -f2 "${PHOBOS_DIR}/registry" 2>/dev/null); do
if [ "$slot" -gt "$max" ] 2>/dev/null; then
max="$slot"
fi
done
fi
echo $((max + 1))
}
registry_alloc_port() {
local base="${1:-13255}"
local used=" "
if [ -f "${PHOBOS_DIR}/registry" ]; then
used=" $(cut -d'|' -f3 "${PHOBOS_DIR}/registry" 2>/dev/null | tr '\n' ' ')"
fi
local port="$base"
while echo "$used" | grep -q " ${port} "; do
port=$((port + 1))
done
echo "$port"
}
registry_add() {
printf '%s\n' "$1" >> "${PHOBOS_DIR}/registry"
}
registry_remove_client() {
local file="${PHOBOS_DIR}/registry"
[ -f "$file" ] || return 0
grep -v "^$1|" "$file" > "${file}.tmp" 2>/dev/null || true
mv "${file}.tmp" "$file"
}