How to use ttl in scripts, CI/CD pipelines, and integrate with other tools.
TTL provides several output formats for scripting:
# JSON output (full session data)
ttl 1.1.1.1 -c 10 --json
# CSV output (hop statistics)
ttl 1.1.1.1 -c 10 --csv
# Text report (human-readable summary)
ttl 1.1.1.1 -c 10 --report
# Disable TUI for headless environments
ttl 1.1.1.1 -c 10 --no-tuiTest connectivity to critical endpoints as part of your deployment:
name: Network Connectivity Check
on:
push:
branches: [main]
jobs:
connectivity:
runs-on: ubuntu-latest
steps:
- name: Install ttl
run: cargo install ttl
- name: Set capabilities
run: sudo setcap cap_net_raw+ep ~/.cargo/bin/ttl
- name: Check API endpoint reachability
run: |
ttl api.example.com -c 20 --json > trace.json
# Fail if destination not reached
if ! jq -e '.hops[] | select(.is_destination == true)' trace.json > /dev/null; then
echo "ERROR: Could not reach destination"
exit 1
fi
# Warn on high packet loss
MAX_LOSS=$(jq '[.hops[].loss_percent] | max' trace.json)
if (( $(echo "$MAX_LOSS > 10" | bc -l) )); then
echo "WARNING: High packet loss detected: ${MAX_LOSS}%"
finetwork-check:
stage: test
image: rust:latest
before_script:
- cargo install ttl
- setcap cap_net_raw+ep /usr/local/cargo/bin/ttl
script:
- ttl $TARGET_HOST -c 10 --json > network-trace.json
artifacts:
paths:
- network-trace.json
when: alwaysTTL requires NET_RAW capability to send ICMP packets:
# Run ttl in Docker
docker run --rm --cap-add=NET_RAW -it rust:latest bash -c "
cargo install ttl &&
ttl 1.1.1.1 -c 5 --report
"Or in a Dockerfile:
FROM rust:latest
RUN cargo install ttl
# Container needs --cap-add=NET_RAW at runtime
ENTRYPOINT ["ttl"]docker build -t ttl .
docker run --rm --cap-add=NET_RAW ttl 1.1.1.1 -c 5 --reportTTL's JSON output contains detailed hop information:
# Get all hop IPs
ttl 1.1.1.1 -c 10 --json | jq -r '.hops[].responders[].ip'
# Get hops with packet loss > 5%
ttl 1.1.1.1 -c 10 --json | jq '.hops[] | select(.loss_percent > 5)'
# Extract ASN information
ttl 1.1.1.1 -c 10 --json | jq -r '.hops[].responders[].asn.name // "unknown"'
# Get average RTT per hop
ttl 1.1.1.1 -c 10 --json | jq '.hops[] | {ttl: .ttl, avg_ms: .avg_ms}'
# Check for NAT detection
ttl 1.1.1.1 -c 10 --flows 4 --json | jq '.hops[] | select(.nat_detected == true)'
# Find IX points in path
ttl cloudflare.com -c 10 --json | jq '.hops[].responders[].ix | select(. != null)'#!/bin/bash
# check-connectivity.sh - Alert on network issues
TARGET="$1"
THRESHOLD_LOSS=10
THRESHOLD_RTT=100
result=$(ttl "$TARGET" -c 20 --json 2>/dev/null)
# Check if destination was reached
if ! echo "$result" | jq -e '.complete' > /dev/null; then
echo "CRITICAL: Cannot reach $TARGET"
exit 2
fi
# Check packet loss
max_loss=$(echo "$result" | jq '[.hops[].loss_percent] | max')
if (( $(echo "$max_loss > $THRESHOLD_LOSS" | bc -l) )); then
echo "WARNING: High packet loss to $TARGET: ${max_loss}%"
exit 1
fi
# Check latency
max_rtt=$(echo "$result" | jq '[.hops[].avg_ms // 0] | max')
if (( $(echo "$max_rtt > $THRESHOLD_RTT" | bc -l) )); then
echo "WARNING: High latency to $TARGET: ${max_rtt}ms"
exit 1
fi
echo "OK: $TARGET reachable, loss=${max_loss}%, rtt=${max_rtt}ms"
exit 0#!/bin/bash
# compare-paths.sh - Compare network paths
targets=("8.8.8.8" "1.1.1.1" "9.9.9.9")
for target in "${targets[@]}"; do
echo "=== $target ==="
ttl "$target" -c 10 --json | jq -r '
.hops[] |
"\(.ttl)\t\(.responders[0].ip // "*")\t\(.responders[0].asn.name // "-")\t\(.avg_ms // "-")ms"
' | column -t
echo
done#!/bin/bash
# find-mtu.sh - Find path MTU to target
TARGET="$1"
echo "Discovering MTU to $TARGET..."
result=$(ttl "$TARGET" --pmtud -c 30 --json 2>/dev/null)
mtu=$(echo "$result" | jq -r '.pmtud.discovered_mtu // "unknown"')
echo "Path MTU: $mtu bytes"
if [[ "$mtu" != "unknown" && "$mtu" -lt 1500 ]]; then
echo "WARNING: MTU is below standard Ethernet MTU (1500)"
echo "Consider adjusting MTU settings for this path"
fittl target.com -c 10 --json | logger -t ttl-traceecho "$(date -Iseconds) $(ttl target.com -c 10 --json)" >> /var/log/ttl-traces.jsonlttl target.com -c 10 --json | curl -X POST "localhost:9200/ttl-traces/_doc" \
-H "Content-Type: application/json" \
-d @-Save and replay sessions for historical analysis or sharing:
# Save a trace session
ttl 1.1.1.1 -c 100 --json > trace-$(date +%Y%m%d-%H%M%S).json
# Replay in TUI (final state)
ttl --replay trace-20240115-143022.json
# Animated replay (shows probe-by-probe discovery at 10x speed)
ttl --replay trace.json --animate
# Real-time animated replay
ttl --replay trace.json --animate --speed 1.0
# Replay and export as CSV
ttl --replay trace.json --csv > trace.csvDuring animated replay, use p/Space to pause, Left/Right to seek ±0.5s, [/] to seek ±5s, +/- to adjust speed, and Home/End to jump to start/end. A progress bar shows position, speed, and event count. Press ? for the full keybinding list.
| Code | Meaning |
|---|---|
| 0 | Success |
| 1 | Error (network, permissions, etc.) |
| 2 | Invalid arguments |
Use in scripts:
if ttl target.com -c 5 --no-tui > /dev/null 2>&1; then
echo "Target reachable"
else
echo "Target unreachable or error"
fi- Always use
-c Nto limit probe count - otherwise ttl runs indefinitely - Use
--jsonfor machine-readable output - Use
--no-tuiin headless environments to avoid terminal issues - Set capabilities once with
setcapto avoid needing sudo in scripts - Handle timeouts - some targets may not respond to ICMP, try
-p udpor-p tcp