wgctl/modules/ip.module.sh
2026-05-06 23:02:12 +00:00

65 lines
1.3 KiB
Bash

#!/usr/bin/env bash
# ============================================
# IP Assignment
# ============================================
function ip::assigned() {
grep -h "^Address" "$(ctx::clients)"/*.conf 2>/dev/null \
| awk '{print $3}' \
| cut -d'/' -f1
}
function ip::is_assigned() {
local candidate="$1"
ip::assigned | grep -q "^${candidate}$"
}
function ip::next_for_type() {
local type="$1"
local subnet
subnet=$(config::subnet_for "$type")
if [[ -z "$subnet" ]]; then
log::error "Unknown device type: ${type}"
return 1
fi
for i in $(seq 1 254); do
local candidate="${subnet}.${i}"
if ! ip::is_assigned "$candidate"; then
echo "$candidate"
return 0
fi
done
log::error "No available IPs in subnet ${subnet}.0/24"
return 1
}
# ============================================
# Validation
# ============================================
function ip::is_valid() {
local ip="$1"
[[ "$ip" =~ ^([0-9]{1,3}\.){3}[0-9]{1,3}(/([0-9]|[1-2][0-9]|3[0-2]))?$ ]]
}
function ip::is_cidr() {
[[ "$1" == *"/"* ]]
}
function ip::validate() {
local ip="$1"
if ! ip::is_valid "$ip"; then
log::error "Invalid IP or CIDR: ${ip}"
return 1
fi
return 0
}
function ip::require_valid() {
local ip="$1"
ip::validate "$ip" || exit 1
}