#!/bin/sh
# DF-0569 — NAT alias_port OOB write reproduction setup + driver.
#
# This script runs AS ROOT on the DragonFlyBSD guest.  It:
#   1. Sets filters_default_to_accept=1 (so loading ipfw3 won't lock out SSH)
#   2. Loads ipfw3, ipfw3_basic, ipfw3_nat modules
#   3. Configures NAT instance 1 with alias IP = vtnet0's IP
#   4. Adds a NAT rule for outbound UDP (TCP is excluded to preserve SSH)
#   5. Drives many outbound UDP flows through the NAT
#
# The OOB write fires probabilistically (~1.56% per flow).  With 3000+
# flows we expect ~47 OOB writes into heap, which should cause a kernel
# panic when the corrupted memory is later used.
#
# Usage: ./run.sh [flow_count]
set -e

COUNT="${1:-3000}"

echo "=== DF-0569 NAT alias_port OOB write reproduction ==="
echo "uname: $(uname -a)"
echo "flows: $COUNT"
echo ""

# --- Step 1: ensure default-accept so SSH survives ---
echo "[1/5] Setting filters_default_to_accept=1 ..."
sysctl net.filters_default_to_accept=1 2>/dev/null || true

# --- Step 2: load modules ---
echo "[2/5] Loading ipfw3 modules ..."
kldload ipfw3 2>/dev/null || true
kldload ipfw3_basic 2>/dev/null || true
kldload ipfw3_nat 2>/dev/null || true
kldstat | grep ipfw3
echo ""

# --- Step 3: configure NAT ---
ALIAS_IP=$(ifconfig vtnet0 | grep 'inet ' | awk '{print $2}')
echo "[3/5] Configuring NAT instance 1 with alias IP $ALIAS_IP ..."
ipfw3 nat 1 config ip $ALIAS_IP
ipfw3 nat 1 show config
echo ""

# --- Step 4: add firewall rules ---
echo "[4/5] Adding firewall rules ..."
# NAT outbound UDP only (TCP excluded to preserve SSH).
# Also allow all to be safe.
ipfw3 add 50 allow ip from any to any 2>/dev/null || true
ipfw3 add 100 nat 1 udp from any to any out 2>/dev/null || true
ipfw3 show 2>/dev/null || true
echo ""

# --- Step 5: drive connections ---
echo "[5/5] Driving $COUNT outbound UDP flows through NAT ..."
echo "      Each flow exercises pick_alias_port (ip_fw3_nat.c:436)."
echo "      ~1.56% will trigger the OOB write at ip_fw3_nat.c:425."
echo ""
echo "=== WATCH boot.log FOR PANIC ==="
echo ""

cd /tmp/df0569
cc -O2 -o nat_oob_trigger nat_oob_trigger.c
./nat_oob_trigger $COUNT

echo ""
echo "=== Driver completed. ==="
echo "=== If no panic yet, wait for the cleanup callout to trip on corrupted memory. ==="
sleep 3
echo "=== Checking NAT states for alias_port byte-swap evidence... ==="
ipfw3 nat 1 show state 2>/dev/null | head -20 || echo "(no states or command failed)"

echo ""
echo "=== DONE ==="
