diff --git a/set_dhcp_requested_ip.sh b/set_dhcp_requested_ip.sh new file mode 100644 index 0000000..5eb38a5 --- /dev/null +++ b/set_dhcp_requested_ip.sh @@ -0,0 +1,98 @@ +#!/usr/bin/env bash +# +# Usage: +# 1) Save as: set_dhcp_requested_ip.sh +# 2) Make executable: +# chmod +x set_dhcp_requested_ip.sh +# 3) Run as root, passing the desired IP: +# sudo ./set_dhcp_requested_ip.sh 192.168.1.50 +# +# What it does: +# - detects the primary network interface +# - writes a Netplan config with DHCP enabled +# - adds a systemd-networkd DHCPv4 RequestAddress= override +# - applies the config +# +# Important: +# - the router/DHCP server may ignore the requested IP +# - for guaranteed assignment, make a DHCP reservation on the router too + +set -euo pipefail + +requested_ip="${1:-}" + +if [[ -z "$requested_ip" ]]; then + echo "Error: IP address argument is required." + echo "Example: sudo $0 192.168.1.50" + exit 1 +fi + +if [[ "${EUID}" -ne 0 ]]; then + echo "Run this script as root: sudo $0 $requested_ip" + exit 1 +fi + +if ! [[ "$requested_ip" =~ ^([0-9]{1,3}\.){3}[0-9]{1,3}$ ]]; then + echo "Error: invalid IPv4 format: $requested_ip" + exit 1 +fi + +for octet in ${requested_ip//./ }; do + if (( octet < 0 || octet > 255 )); then + echo "Error: invalid IPv4 octet in $requested_ip" + exit 1 + fi +done + +iface="$(ip route | awk '/^default/ {print $5; exit}')" + +if [[ -z "$iface" ]]; then + echo "Error: could not detect the primary network interface." + exit 1 +fi + +netplan_file="/etc/netplan/99-dhcp-requested-ip.yaml" +networkd_dropin_dir="/etc/systemd/network/10-${iface}.network.d" +networkd_dropin_file="${networkd_dropin_dir}/request-address.conf" + +mkdir -p "$networkd_dropin_dir" + +cat > "$netplan_file" < "$networkd_dropin_file" <