- ui::_render_endpoint_col: shared endpoint padding primitive
- ui::_build_dest: shared destination display primitive
- ui:⌚:wg_row/fw_row: endpoint annotation (raw_ip → resolved)
- resolve::endpoint_parts: fresh resolution, no stale cache
- resolve::service_name: returns service name or empty (no raw fallback)
- monitor::live: pre-measure w_client from peer names
- watch: fixed w_endpoint=30 for consistent live alignment
- shell: add peer/hosts/identity/subnet/policy/activity to known commands
- shell: updated banner with new commands
- identity/rule help: updated with new features
110 lines
No EOL
3.3 KiB
Bash
110 lines
No EOL
3.3 KiB
Bash
#!/usr/bin/env bash
|
|
# modules/resolve.module.sh — IP/host resolution chain
|
|
# Chains: hosts.json exact match → services.json match → raw IP
|
|
# Depends on: hosts.module.sh, net.module.sh
|
|
|
|
declare -gA _RESOLVE_CACHE=()
|
|
|
|
# resolve::ip <ip> [port] [proto]
|
|
# Resolves an IP to a display name using the full resolution chain.
|
|
# Returns raw IP if no match found.
|
|
# Respects _WGCTL_RAW=true to bypass resolution.
|
|
function resolve::ip() {
|
|
local ip="${1:-}" port="${2:-}" proto="${3:-}"
|
|
[[ -z "$ip" ]] && echo "" && return 0
|
|
[[ "${_WGCTL_RAW:-false}" == "true" ]] && echo "$ip" && return 0
|
|
|
|
local cache_key="${ip}:${port}:${proto}"
|
|
if [[ -z "${_RESOLVE_CACHE[$cache_key]+x}" ]]; then
|
|
local result=""
|
|
|
|
# 1. hosts.json exact IP match
|
|
if [[ -f "$(ctx::hosts)" ]]; then
|
|
result=$(hosts::resolve_ip "$ip")
|
|
fi
|
|
|
|
# 2. services.json match
|
|
if [[ -z "$result" ]]; then
|
|
result=$(net::reverse_lookup "$ip" "$port" "$proto" 2>/dev/null) || result=""
|
|
fi
|
|
|
|
# 3. Raw IP fallback
|
|
[[ -z "$result" ]] && result="$ip"
|
|
|
|
_RESOLVE_CACHE[$cache_key]="$result"
|
|
fi
|
|
|
|
echo "${_RESOLVE_CACHE[$cache_key]}"
|
|
}
|
|
|
|
# resolve::dest <ip> [port] [proto]
|
|
# Like resolve::ip but builds a formatted destination display string.
|
|
# e.g. "pihole:dns-udp" or "vodafone-wan" or "10.0.0.103:853/tcp"
|
|
function resolve::dest() {
|
|
local ip="${1:-}" port="${2:-}" proto="${3:-}"
|
|
[[ -z "$ip" ]] && echo "" && return 0
|
|
|
|
local name
|
|
name=$(resolve::ip "$ip" "$port" "$proto")
|
|
|
|
if [[ "$name" == "$ip" ]]; then
|
|
# No resolution — raw format
|
|
if [[ -n "$port" ]]; then
|
|
echo "${ip}:${port}/${proto}"
|
|
else
|
|
[[ -n "$proto" ]] && echo "${ip} (${proto})" || echo "$ip"
|
|
fi
|
|
else
|
|
# Resolved — just the name, no proto suffix
|
|
echo "$name"
|
|
fi
|
|
}
|
|
|
|
# resolve::service_name <ip> [port] [proto]
|
|
# Returns just the service/host name, empty string if no match (not raw IP).
|
|
# Use when you need to know IF something resolved, not what the raw fallback is.
|
|
function resolve::service_name() {
|
|
local ip="${1:-}" port="${2:-}" proto="${3:-}"
|
|
[[ -z "$ip" ]] && echo "" && return 0
|
|
[[ "${_WGCTL_RAW:-false}" == "true" ]] && echo "" && return 0
|
|
|
|
local result=""
|
|
|
|
# 1. hosts.json exact IP match
|
|
if [[ -f "$(ctx::hosts)" ]]; then
|
|
result=$(hosts::resolve_ip "$ip")
|
|
fi
|
|
|
|
# 2. services.json match
|
|
if [[ -z "$result" ]]; then
|
|
result=$(net::reverse_lookup "$ip" "$port" "$proto" 2>/dev/null) || result=""
|
|
fi
|
|
|
|
# Return empty if no match (caller handles raw fallback)
|
|
[[ "$result" == "$ip" ]] && result=""
|
|
echo "$result"
|
|
}
|
|
|
|
# resolve::endpoint_parts <endpoint_ip>
|
|
# Returns "raw_ip|resolved_name" — empty resolved if no match.
|
|
# Used by watch/logs rows to build "raw_ip → resolved" display.
|
|
function resolve::endpoint_parts() {
|
|
local ip="${1:-}"
|
|
[[ -z "$ip" ]] && echo "|" && return 0
|
|
[[ "${_WGCTL_RAW:-false}" == "true" ]] && echo "${ip}|" && return 0
|
|
|
|
# Don't use cache for endpoint_parts — always resolve fresh
|
|
local resolved=""
|
|
[[ -f "$(ctx::hosts)" ]] && resolved=$(hosts::resolve_ip "$ip" 2>/dev/null || true)
|
|
if [[ -z "$resolved" ]]; then
|
|
resolved=$(net::reverse_lookup "$ip" "" "" 2>/dev/null) || resolved=""
|
|
fi
|
|
[[ "$resolved" == "$ip" ]] && resolved=""
|
|
echo "${ip}|${resolved}"
|
|
}
|
|
|
|
# resolve::clear_cache
|
|
# Clears the resolution cache — call between commands if needed.
|
|
function resolve::clear_cache() {
|
|
_RESOLVE_CACHE=()
|
|
} |