#!/usr/bin/env bash
# Real demos for P147 "Every Networking Term a Beginner Needs in 12 Minutes". Made on the Mac (Docker Desktop).
# A small vet clinic's network and a slice of internet in Docker, all from one stock Ubuntu 24.04 image (lab/Dockerfile),
# on reserved addresses only (RFC 1918 192.168.1.0/24 inside the clinic, RFC 5737 203.0.113.0/24 and 198.51.100.0/24
# "on the internet", .test and .lan names), so nothing here is anyone's real address:
#
#   front-desk (Ana's PC, address by DHCP) ─┐
#   printer 192.168.1.40 (port 9100) ───────┼─ clinic-router 192.168.1.1 | 203.0.113.7  (DHCP + DNS: dnsmasq, NAT)
#                                           │     └─ isp-router 203.0.113.1 | 198.51.100.1  (15 ms of delay each way,
#                                           │           standing in for distance)
#                                           │           ├─ web 198.51.100.80 (the clinic's booking site, ports 80, 8080)
#                                           │           └─ dns 198.51.100.53 (a public DNS server)
# Nothing leaves this machine: the ISP router has no default route.
# Every command shown is typed into a real interactive bash in a pty, one per window (demo_driver.py).
set -euo pipefail
cd "$(dirname "$0")"
P=ce-p147
BOXES="front-desk printer clinic-router isp-router web dns"
cleanup() {
  for b in $BOXES; do docker rm -f $P-$b >/dev/null 2>&1 || true; done
  for n in lan isp dc; do docker network rm $P-$n >/dev/null 2>&1 || true; done
}
cleanup
[ -n "${KEEP:-}" ] || trap cleanup EXIT
docker build -q -t $P lab >/dev/null

# Docker's own gateways at .254, so the routers can own the .1 addresses, as in a real office.
docker network create --subnet 192.168.1.0/24 --gateway 192.168.1.254 $P-lan >/dev/null
docker network create --subnet 203.0.113.0/24 --gateway 203.0.113.254 $P-isp >/dev/null
docker network create --subnet 198.51.100.0/24 --gateway 198.51.100.254 $P-dc >/dev/null
box() {  # box NAME NETWORK IP [docker args]
  local name=$1 net=$2 ip=$3; shift 3
  docker run -d --name $P-$name --hostname $name --cap-add NET_ADMIN --cap-add NET_RAW \
    --sysctl net.ipv6.conf.all.disable_ipv6=1 "$@" --network $P-$net --ip $ip $P sleep infinity >/dev/null
}
box front-desk lan 192.168.1.250           # Docker's address is removed below: the PC asks DHCP for one
box printer lan 192.168.1.40
box clinic-router lan 192.168.1.1 --sysctl net.ipv4.ip_forward=1
docker network connect --ip 203.0.113.7 $P-isp $P-clinic-router
box isp-router isp 203.0.113.1 --sysctl net.ipv4.ip_forward=1
docker network connect --ip 198.51.100.1 $P-dc $P-isp-router
box web dc 198.51.100.80
box dns dc 198.51.100.53
python3 demo_driver.py $P
