#!/bin/sh
# bty-web PXE activation helper.
#
# Invoked by the ``bty`` service user via the entry in
# ``/etc/sudoers.d/bty-web``. Writes a dnsmasq proxy-DHCP config to
# ``/etc/dnsmasq.d/bty-pxe-active.conf`` and restarts
# ``dnsmasq.service`` so the new config takes effect.
#
# Proxy-DHCP only: bty assumes there is already a DHCP server on
# the segment handing out IPs. dnsmasq just answers PXE-specific
# queries layered on top. We deliberately do NOT support full DHCP
# - "I'm the only DHCP server on this LAN" is the easiest way for
# an operator to accidentally rogue-DHCP a production network and
# wreck other clients' leases. If you genuinely need DHCP-as-a-
# service, run a dedicated DHCP daemon next to bty.
#
# The shipped ``/etc/dnsmasq.d/bty-pxe.conf`` keeps everything
# commented as documentation; this active config goes in a separate
# file so the original stays as the canonical example. Removing
# the active file + ``systemctl restart dnsmasq`` deactivates PXE
# again.
#
# Args:
#   $1  network interface (e.g. ``eth0``, ``ens18``)
#   $2  subnet network address (e.g. ``192.168.1.0``)

set -eu

if [ $# -ne 2 ]; then
    printf 'usage: %s <interface> <subnet>\n' "$0" >&2
    exit 64
fi

IFACE=$1
SUBNET=$2

# Validate inputs (defence in depth - the caller bty-web also
# validates, but this script runs as root).
case "$IFACE" in
    "" | *[!a-zA-Z0-9_-]*) printf 'bad interface name: %s\n' "$IFACE" >&2; exit 64 ;;
esac
case "$SUBNET" in
    "" | *[!0-9.]*) printf 'bad subnet: %s\n' "$SUBNET" >&2; exit 64 ;;
esac

ACTIVE=/etc/dnsmasq.d/bty-pxe-active.conf
TMP=$(mktemp)
trap 'rm -f "$TMP"' EXIT

# ``bind-dynamic`` (instead of bind-interfaces) tolerates the
# interface coming up after dnsmasq starts - relevant when a
# systemd-networkd unit assigns the static IP after dnsmasq.service
# has already started its bind sequence.
cat > "$TMP" <<EOF
# Generated by bty-web-activate-pxe.
# Removing this file and restarting dnsmasq deactivates the chain.

bind-dynamic
interface=$IFACE
dhcp-range=$SUBNET,proxy

dhcp-match=set:bios,option:client-arch,0
dhcp-match=set:efi,option:client-arch,7
dhcp-match=set:efi,option:client-arch,9
dhcp-userclass=set:ipxe,iPXE

dhcp-boot=tag:!ipxe,tag:bios,undionly.kpxe
dhcp-boot=tag:!ipxe,tag:efi,ipxe.efi
dhcp-boot=tag:ipxe,http://\${next-server}:8080/pxe-bootstrap.ipxe
EOF

chown root:root "$TMP"
chmod 0644 "$TMP"
mv "$TMP" "$ACTIVE"
trap - EXIT

systemctl restart dnsmasq.service

printf 'PXE activated on %s (proxy-DHCP on %s)\n' "$IFACE" "$SUBNET"
