#!/usr/bin/env bash function net::exists() { local name="${1:?}" local result result=$(json::net_exists "$(ctx::net)" "$name") [[ "$result" == "true" ]] } function net::require_exists() { local name="${1:?}" if ! net::exists "$name"; then log::error "Service not found: ${name}" return 1 fi } function net::resolve() { local name="${1:?}" json::net_resolve "$(ctx::net)" "$name" } function net::reverse_lookup() { local ip="${1:-}" port="${2:-}" proto="${3:-}" [[ -z "$ip" ]] && return 0 json::net_reverse_lookup "$(ctx::net)" "$ip" "$port" "$proto" } function net::annotation() { # Returns " → service:port" or "" — for display use local ip="${1:-}" port="${2:-}" proto="${3:-}" local match match=$(net::reverse_lookup "$ip" "$port" "$proto") [[ -n "$match" ]] && echo " → ${match}" || echo "" } function net::annotate() { # Returns " → service:port-name" or "" for display use local entry="${1:-}" [[ -z "$entry" ]] && return 0 local ann="" if [[ "$entry" == *:*:* ]]; then # ip:port:proto local b_ip b_port b_proto IFS=":" read -r b_ip b_port b_proto <<< "$entry" ann=$(net::reverse_lookup "$b_ip" "$b_port" "$b_proto") else # ip or ip/cidr local ip="${entry%%/*}" ann=$(net::reverse_lookup "$ip") fi [[ -n "$ann" ]] && echo "${ann}" || echo "" } function net::print_entry() { local sign="${1:-}" entry="${2:-}" indent="${3:-6}" local ann ann=$(net::annotate "$entry") local color [[ "$sign" == "+" ]] && color="\033[0;32m" || color="\033[0;31m" local spaces spaces=$(printf '%*s' "$indent" '') printf "%s%b%s\033[0m %-20s\033[0;37m%s\033[0m\n" \ "$spaces" "$color" "$sign" "$entry" \ "${ann:+ → ${ann}}" } function net::print_dns_redirect() { local ip="${1:-}" indent="${2:-6}" label="${3:-DNS}" local spaces spaces=$(printf '%*s' "$indent" '') local ann ann=$(net::annotate "$ip") printf "%s\033[0;36m↺\033[0m %s → %s\033[0;37m%s\033[0m\n" \ "$spaces" "$label" "$ip" "${ann:+ → ${ann}}" } function net::print_dns_redirect_full() { # For rule::show — slightly different prefix local ip="${1:-}" local ann ann=$(net::annotate "$ip") printf " \033[0;36m↺\033[0m Redirect all DNS → %s\033[0;37m%s\033[0m\n" \ "$ip" "${ann:+ → ${ann}}" } function net::resolve_display() { local ip="${1:-}" port="${2:-}" proto="${3:-}" [[ -z "$ip" ]] && return 0 # --raw flag bypass [[ "${_WGCTL_RAW:-false}" == "true" ]] && echo "$ip" && return 0 # 1. hosts.json exact IP match local host_name="" if [[ -f "$(ctx::hosts)" ]]; then host_name=$(hosts::lookup_ip "$ip") fi [[ -n "$host_name" ]] && echo "$host_name" && return 0 # 2. services.json match local svc_name="" svc_name=$(net::reverse_lookup "$ip" "$port" "$proto" 2>/dev/null) || true [[ -n "$svc_name" ]] && echo "$svc_name" && return 0 # 3. Raw IP fallback echo "$ip" }