layered-soul/skills/systematic-debugging/scripts/network-interference-capture.sh
Hermes & Sam 5c5df32101 Populate layered-soul: identity, memories, skills, plan (Hermes & Sam)
- SOUL.md: full agent identity, operating principles, voice
- IDENTITY.md: runtime identity, hosts, boundaries
- USER.md: operator context imported from hermes-soul
- AGENTS.md: actual operating rules, infrastructure, quick reference
- memories/curated/: 5 topics (tailscale, forgejo, agents, projects, vaultwarden)
- skills/: 9 cross-harness skills imported from hermes-soul after review
- docs/PLAN-CONFIGURE-PRIVATE-REPO.md: configuration plan
- Validate: passes clean
2026-06-14 00:21:26 +02:00

86 lines
3.3 KiB
Bash

#!/usr/bin/env bash
# Generic before/after interference test for Wi-Fi/SSH/tmux lag.
# Run once before introducing the suspected interferer, then again after.
# Usage: WIFI_IFACE=wlp1s0 ROUTER_IP=192.168.1.1 REMOTE_IP=1.2.3.4 ./network-interference-capture.sh [duration-seconds] [output-dir]
set -euo pipefail
DURATION="${1:-90}"
STAMP="$(date +%Y%m%d-%H%M%S)"
BASE="${2:-./network-interference-$STAMP}"
IFACE="${WIFI_IFACE:-}"
ROUTER="${ROUTER_IP:-}"
PUBLIC="${PUBLIC_IP:-1.1.1.1}"
REMOTE="${REMOTE_IP:-}"
mkdir -p "$BASE"
if [[ -z "$IFACE" ]]; then
IFACE=$(iw dev 2>/dev/null | awk '/Interface/ {print $2; exit}' || true)
fi
if [[ -z "$ROUTER" ]]; then
ROUTER=$(ip route show default 2>/dev/null | awk '{print $3; exit}' || true)
fi
log(){ printf '\n## %s\n' "$*" | tee -a "$BASE/summary.txt"; }
run(){ printf '\n$ %s\n' "$*" | tee -a "$BASE/summary.txt"; bash -lc "$*" 2>&1 | tee -a "$BASE/summary.txt"; }
log "Network interference test $STAMP duration=${DURATION}s iface=${IFACE:-unknown}"
run "date; uname -a; uptime"
if [[ -n "$IFACE" ]]; then
run "nmcli -f GENERAL,WIFI-PROPERTIES,IP4 device show '$IFACE' 2>/dev/null | sed -n '1,140p' || true"
run "nmcli -f ACTIVE,SSID,BSSID,CHAN,RATE,SIGNAL,BARS,SECURITY dev wifi list --rescan yes 2>/dev/null | sed -n '1,100p' || true"
run "iw dev '$IFACE' link 2>/dev/null || true"
run "ip -s link show '$IFACE'"
fi
run "ss -nti '( sport = :22 or dport = :22 )' || true"
run "tailscale status 2>/dev/null | sed -n '1,100p' || true"
run "tailscale netcheck 2>/dev/null || true"
log "Starting ping streams"
for target in "$ROUTER" "$PUBLIC" "$REMOTE"; do
[[ -n "$target" ]] || continue
safe="${target//[^A-Za-z0-9_.-]/_}"
ping -D -i 0.2 "$target" > "$BASE/ping-$safe.log" 2>&1 &
echo $! >> "$BASE/pids"
done
FILTER_PARTS=()
for target in "$ROUTER" "$PUBLIC" "$REMOTE"; do
[[ -n "$target" ]] && FILTER_PARTS+=("host $target")
done
FILTER="port 22"
if [[ ${#FILTER_PARTS[@]} -gt 0 ]]; then
FILTER="$(IFS=' or '; echo "${FILTER_PARTS[*]}") or port 22"
fi
if [[ -n "$IFACE" ]] && command -v tshark >/dev/null 2>&1; then
log "Starting tshark capture"
sudo tshark -i "$IFACE" -a "duration:$DURATION" -w "$BASE/capture.pcapng" -f "$FILTER" > "$BASE/tshark.log" 2>&1 &
echo $! >> "$BASE/pids"
elif [[ -n "$IFACE" ]] && command -v tcpdump >/dev/null 2>&1; then
log "Starting tcpdump capture"
sudo timeout "$DURATION" tcpdump -i "$IFACE" -s 0 -w "$BASE/capture.pcap" "$FILTER" > "$BASE/tcpdump.log" 2>&1 &
echo $! >> "$BASE/pids"
else
log "No tshark/tcpdump capture available; install one if packet evidence is needed"
fi
sleep "$DURATION"
if [[ -f "$BASE/pids" ]]; then
while read -r pid; do kill "$pid" 2>/dev/null || true; done < "$BASE/pids"
fi
sleep 1
log "Post-test state"
run "date; uptime"
[[ -n "$IFACE" ]] && run "ip -s link show '$IFACE'"
run "ss -nti '( sport = :22 or dport = :22 )' || true"
run "journalctl --since '$(date -d "${DURATION} seconds ago" '+%Y-%m-%d %H:%M:%S')' --no-pager 2>/dev/null | egrep -i 'wlan|wlp|iwlwifi|tailscale|dns|disconnect|deauth|timeout|error|warn|UFW BLOCK' | tail -220 || true"
log "Ping summaries"
for f in "$BASE"/ping-*.log; do
[[ -e "$f" ]] || continue
echo "--- $f" | tee -a "$BASE/summary.txt"
tail -20 "$f" | tee -a "$BASE/summary.txt"
done
printf '\nSaved network interference test directory: %s\nMain summary: %s\n' "$BASE" "$BASE/summary.txt"