Saltar a contenido

MTR Cheatsheet

■/div titulada

Sinopsis

MTR (Mi Traceroute) es una poderosa herramienta de diagnóstico de red que combina la funcionalidad de ping y traceroute en una sola utilidad. Envia continuamente paquetes a un destino y muestra estadísticas en tiempo real sobre pérdida de paquetes y latencia para cada hop a lo largo de la ruta. MTR ofrece una visión más completa del rendimiento de la red que las herramientas tradicionales mostrando estadísticas en curso en lugar de instantáneas individuales.

Características clave

  • ** Vigilancia de tiempo real**: Paquete continuo enviado con estadísticas en vivo
  • ** Función combinada**: Ping y traceroute en una herramienta
  • Detección de pérdida de bolsillo: Estadísticas de pérdida de paquetes por página
  • Análisis de latencia: Mín, máx, promedio y métricas de desviación estándar
  • Multiple Output Formats: Texto, CSV, JSON y salida XML
  • IPv4 y IPv6 Soporte: Análisis de red de doble plataforma
  • GUI y CLI Modes: Interfaz terminal y gráfica
  • ** Parámetros personalizables**: Tamaño del paquete, intervalo y opciones de cuenta
  • Visualización del camino de trabajo: Pantalla de topología de ruta clara

Instalación

Linux Systems

# Ubuntu/Debian
sudo apt update
sudo apt install mtr mtr-tiny

# CentOS/RHEL/Fedora
sudo yum install mtr
# or
sudo dnf install mtr

# Arch Linux
sudo pacman -S mtr

# openSUSE
sudo zypper install mtr

# From source
git clone https://github.com/traviscross/mtr.git
cd mtr
./bootstrap.sh
./configure
make
sudo make install

# Verify installation
mtr --version

Sistemas Windows

# WinMTR (Windows GUI version)
# Download from: https://sourceforge.net/projects/winmtr/

# Using Chocolatey
choco install winmtr

# Using Scoop
scoop install winmtr

# Manual installation
# 1. Download WinMTR from SourceForge
# 2. Extract to desired location
# 3. Run WinMTR.exe

# Command line version via WSL
wsl --install
wsl
sudo apt install mtr

macOS Systems

# Using Homebrew
brew install mtr

# Using MacPorts
sudo port install mtr

# From source
git clone https://github.com/traviscross/mtr.git
cd mtr
./bootstrap.sh
./configure
make
sudo make install

# Note: May require additional permissions for raw sockets
sudo mtr google.com

# Verify installation
mtr --version

Docker Instalación

# Pull MTR image
docker pull alpine:latest

# Create custom MTR container
cat > Dockerfile << EOF
FROM alpine:latest
RUN apk add --no-cache mtr
ENTRYPOINT ["mtr"]
EOF

docker build -t mtr-container .

# Run MTR in container
docker run --rm -it mtr-container google.com

# One-liner with Alpine
docker run --rm -it alpine:latest sh -c "apk add --no-cache mtr && mtr google.com"

Uso básico

Interfaz de línea de mando

# Basic MTR to hostname
mtr google.com

# MTR to IP address
mtr 8.8.8.8

# Run for specific number of cycles
mtr -c 10 google.com

# Report mode (non-interactive)
mtr --report google.com

# Report with specific count
mtr --report --report-cycles 20 google.com

# No DNS resolution
mtr -n google.com

# IPv6 mode
mtr -6 google.com

# IPv4 mode (explicit)
mtr -4 google.com

# Specify interface
mtr -I eth0 google.com

Modo interactivo

# Start interactive MTR
mtr google.com

# Interactive mode key bindings:
# q - quit
# r - reset statistics
# d - toggle display mode
# n - toggle DNS resolution
# p - pause/unpause
# space - pause/unpause
# h - help
# ? - help

# Display modes in interactive:
# 0 - default display
# 1 - latency and packet loss
# 2 - packet loss percentage only

Report Generation

# Generate report with 50 cycles
mtr --report --report-cycles 50 google.com

# Wide report format
mtr --report-wide --report-cycles 30 google.com

# CSV output
mtr --csv --report-cycles 20 google.com

# JSON output
mtr --json --report-cycles 15 google.com

# XML output
mtr --xml --report-cycles 25 google.com

# Raw output format
mtr --raw --report-cycles 10 google.com

Configuración avanzada

Opciones de paquete y de tiempo

# Custom packet size
mtr -s 1400 google.com

# Custom interval (seconds between packets)
mtr -i 2 google.com

# Timeout per packet
mtr -t 5 google.com

# Maximum hops
mtr -m 20 google.com

# First hop to start from
mtr -f 3 google.com

# Specify source address
mtr -a 192.168.1.100 google.com

# Set Type of Service (ToS)
mtr -Q 0x10 google.com

# Use TCP instead of ICMP
mtr --tcp google.com

# Specify TCP/UDP port
mtr --port 80 google.com

# UDP mode
mtr --udp google.com

Opciones avanzadas de presentación de informes

# Order output by different fields
mtr --order "Loss%,Avg" --report google.com

# Show IP addresses and hostnames
mtr --show-ips --report google.com

# Display AS numbers
mtr --aslookup --report google.com

# Split output by packet size
mtr --split --report google.com

# Display jitter (standard deviation)
mtr --jitter --report google.com

# Bitpattern for packets
mtr --bitpattern 0xFF --report google.com

# Grace period before starting
mtr --gracetime 5 --report google.com

Personalización de productos

# Custom field selection
mtr --displaymode 0 --report google.com  # Default
mtr --displaymode 1 --report google.com  # Latency focus
mtr --displaymode 2 --report google.com  # Loss focus

# Wide format with all statistics
mtr --report-wide --report-cycles 30 google.com

# Compact format
mtr --curses --report-cycles 20 google.com

# No header in output
mtr --no-dns --report google.com | tail -n +2

Análisis de redes y solución de problemas

Script de análisis de redes

#!/bin/bash
# comprehensive_mtr_analysis.sh

TARGET="$1"
CYCLES="${2:-100}"
OUTPUT_DIR="mtr_analysis_$(date +%Y%m%d_%H%M%S)"

if [ -z "$TARGET" ]; then
    echo "Usage: $0 <target> [cycles]"
    echo "Example: $0 google.com 200"
    exit 1
fi

mkdir -p "$OUTPUT_DIR"

echo "Comprehensive MTR Network Analysis"
echo "=================================="
echo "Target: $TARGET"
echo "Cycles: $CYCLES"
echo "Output Directory: $OUTPUT_DIR"
echo ""

# Function to run MTR test and analyze
run_mtr_analysis() {
    local test_name=$1
    local description=$2
    local mtr_options=$3
    local output_file="$OUTPUT_DIR/${test_name}.txt"
    local analysis_file="$OUTPUT_DIR/${test_name}_analysis.txt"

    echo "Running: $test_name"
    echo "Description: $description"
    echo "Options: $mtr_options"

    # Run MTR test
    eval "mtr $mtr_options --report --report-cycles $CYCLES $TARGET" > "$output_file"

    # Analyze results
    echo "Analysis for: $test_name" > "$analysis_file"
    echo "Description: $description" >> "$analysis_file"
    echo "Timestamp: $(date)" >> "$analysis_file"
    echo "========================================" >> "$analysis_file"

    # Extract key metrics
    if [ -s "$output_file" ]; then
        # Count hops
        hop_count=$(grep -c "^ *[0-9]" "$output_file")
        echo "Total hops: $hop_count" >> "$analysis_file"

        # Find problematic hops
        echo "" >> "$analysis_file"
        echo "Hop Analysis:" >> "$analysis_file"
        echo "-------------" >> "$analysis_file"

        grep "^ *[0-9]" "$output_file" | while read line; do
            hop=$(echo "$line" | awk '{print $1}')
            host=$(echo "$line" | awk '{print $2}')
| loss=$(echo "$line" | awk '{print $3}' | tr -d '%') |
            avg=$(echo "$line" | awk '{print $6}')

            # Check for issues
            issues=""
            if [[ "$loss" =~ ^[0-9]+$ ]] && [ "$loss" -gt 0 ]; then
                issues="$issues PACKET_LOSS(${loss}%)"
            fi

            if [[ "$avg" =~ ^[0-9]+\.?[0-9]*$ ]] && (( $(echo "$avg > 200" | bc -l) )); then
                issues="$issues HIGH_LATENCY(${avg}ms)"
            fi

            if [ -n "$issues" ]; then
                echo "Hop $hop ($host): $issues" >> "$analysis_file"
            fi
        done

        # Overall assessment
        echo "" >> "$analysis_file"
        echo "Overall Assessment:" >> "$analysis_file"
        echo "------------------" >> "$analysis_file"

        # Check final hop performance
        final_line=$(tail -1 "$output_file")
        if echo "$final_line" | grep -q "^ *[0-9]"; then
| final_loss=$(echo "$final_line" | awk '{print $3}' | tr -d '%') |
            final_avg=$(echo "$final_line" | awk '{print $6}')

            if [[ "$final_loss" =~ ^[0-9]+$ ]]; then
                if [ "$final_loss" -eq 0 ]; then
                    echo "✓ No packet loss to destination" >> "$analysis_file"
                elif [ "$final_loss" -lt 5 ]; then
                    echo "⚠ Minor packet loss: ${final_loss}%" >> "$analysis_file"
                else
                    echo "✗ Significant packet loss: ${final_loss}%" >> "$analysis_file"
                fi
            fi

            if [[ "$final_avg" =~ ^[0-9]+\.?[0-9]*$ ]]; then
                if (( $(echo "$final_avg < 50" | bc -l) )); then
                    echo "✓ Good latency: ${final_avg}ms" >> "$analysis_file"
                elif (( $(echo "$final_avg < 150" | bc -l) )); then
                    echo "⚠ Acceptable latency: ${final_avg}ms" >> "$analysis_file"
                else
                    echo "✗ High latency: ${final_avg}ms" >> "$analysis_file"
                fi
            fi
        fi

        echo "  Results saved to: $output_file"
        echo "  Analysis saved to: $analysis_file"
    else
        echo "  Test failed - no results"
        echo "Test failed - no output generated" >> "$analysis_file"
    fi

    echo ""
    sleep 2
}

# 1. Standard ICMP test
echo "1. Standard Tests"
echo "================="
run_mtr_analysis "icmp_standard" \
    "Standard ICMP test" \
    ""

run_mtr_analysis "icmp_no_dns" \
    "ICMP test without DNS resolution" \
    "-n"

# 2. Protocol variations
echo "2. Protocol Tests"
echo "================="
run_mtr_analysis "tcp_test" \
    "TCP test (port 80)" \
    "--tcp --port 80"

run_mtr_analysis "udp_test" \
    "UDP test" \
    "--udp"

# 3. Packet size tests
echo "3. Packet Size Tests"
echo "==================="
for size in 64 512 1400; do
    run_mtr_analysis "packet_size_${size}" \
        "Test with ${size} byte packets" \
        "-s $size"
done

# 4. IPv6 test (if supported)
echo "4. IPv6 Test"
echo "============"
if ping6 -c 1 "$TARGET" >/dev/null 2>&1; then
    run_mtr_analysis "ipv6_test" \
        "IPv6 connectivity test" \
        "-6"
else
    echo "IPv6 not supported or target not reachable via IPv6"
fi

# 5. Generate comprehensive report
echo "5. Generating Comprehensive Report"
echo "=================================="

REPORT_FILE="$OUTPUT_DIR/comprehensive_report.html"

cat > "$REPORT_FILE" << EOF
<!DOCTYPE html>
<html>
<head>
    <title>MTR Network Analysis Report</title>
    <style>
        body { font-family: Arial, sans-serif; margin: 20px; }
        table { border-collapse: collapse; width: 100%; margin: 20px 0; }
        th, td { border: 1px solid #ddd; padding: 12px; text-align: left; }
        th { background-color: #f2f2f2; }
        .summary { background-color: #e7f3ff; padding: 15px; border-radius: 5px; margin: 20px 0; }
        .good { background-color: #d4edda; }
        .warning { background-color: #fff3cd; }
        .alert { background-color: #f8d7da; }
        .test-section { margin: 30px 0; }
        pre { background-color: #f8f9fa; padding: 15px; border-radius: 5px; overflow-x: auto; }
    </style>
</head>
<body>
    <h1>MTR Network Analysis Report</h1>
    <div class="summary">
        <h3>Test Summary</h3>
        <p><strong>Target:</strong> $TARGET</p>
        <p><strong>Cycles per test:</strong> $CYCLES</p>
        <p><strong>Generated:</strong> $(date)</p>
        <p><strong>Test Directory:</strong> $OUTPUT_DIR</p>
    </div>
EOF

# Process each test result
for result_file in "$OUTPUT_DIR"/*.txt; do
    if [[ "$result_file" != *"_analysis.txt" ]] && [ -f "$result_file" ]; then
        test_name=$(basename "$result_file" .txt)
        analysis_file="$OUTPUT_DIR/${test_name}_analysis.txt"

        echo "    <div class=\"test-section\">" >> "$REPORT_FILE"
        echo "        <h2>$test_name</h2>" >> "$REPORT_FILE"

        if [ -f "$analysis_file" ]; then
| description=$(grep "Description:" "$analysis_file" | cut -d: -f2- | sed 's/^ *//') |
            echo "        <p><strong>Description:</strong> $description</p>" >> "$REPORT_FILE"

            # Add analysis summary
            if grep -q "Overall Assessment:" "$analysis_file"; then
                echo "        <h3>Analysis Summary</h3>" >> "$REPORT_FILE"
                echo "        <ul>" >> "$REPORT_FILE"

| sed -n '/Overall Assessment:/,/^$/p' "$analysis_file" | tail -n +3 | while read line; do |
                    if [ -n "$line" ]; then
                        echo "            <li>$line</li>" >> "$REPORT_FILE"
                    fi
                done

                echo "        </ul>" >> "$REPORT_FILE"
            fi
        fi

        # Add raw results
        echo "        <h3>Raw Results</h3>" >> "$REPORT_FILE"
        echo "        <pre>" >> "$REPORT_FILE"
        cat "$result_file" >> "$REPORT_FILE"
        echo "        </pre>" >> "$REPORT_FILE"
        echo "    </div>" >> "$REPORT_FILE"
    fi
done

cat >> "$REPORT_FILE" << EOF

    <div class="summary">
        <h3>Recommendations</h3>
        <ul>
            <li>Review hop-by-hop analysis for bottlenecks</li>
            <li>Compare different protocol results</li>
            <li>Monitor packet loss patterns over time</li>
            <li>Consider packet size impact on performance</li>
            <li>Use results for capacity planning and SLA monitoring</li>
        </ul>
    </div>
</body>
</html>
EOF

echo "Comprehensive analysis completed!"
echo "Results directory: $OUTPUT_DIR"
echo "HTML report: $REPORT_FILE"
echo ""

# Display summary
echo "Test Summary:"
echo "============="
for analysis_file in "$OUTPUT_DIR"/*_analysis.txt; do
    if [ -f "$analysis_file" ]; then
        test_name=$(basename "$analysis_file" _analysis.txt)
        echo -n "$test_name: "

        if grep -q "✓.*No packet loss" "$analysis_file"; then
            echo "Good (No packet loss)"
        elif grep -q "⚠.*packet loss" "$analysis_file"; then
            loss=$(grep "⚠.*packet loss" "$analysis_file" | grep -o "[0-9]*%")
            echo "Warning (Packet loss: $loss)"
        elif grep -q "✗.*packet loss" "$analysis_file"; then
            loss=$(grep "✗.*packet loss" "$analysis_file" | grep -o "[0-9]*%")
            echo "Alert (High packet loss: $loss)"
        else
            echo "Completed"
        fi
    fi
done

Monitoreo de redes en tiempo real

#!/bin/bash
# realtime_mtr_monitor.sh

TARGET="$1"
DURATION="${2:-3600}"  # Default 1 hour
LOG_INTERVAL="${3:-300}"  # Log every 5 minutes

if [ -z "$TARGET" ]; then
    echo "Usage: $0 <target> [duration_seconds] [log_interval_seconds]"
    echo "Example: $0 google.com 7200 180"
    exit 1
fi

MONITOR_DIR="mtr_monitor_$(date +%Y%m%d_%H%M%S)"
mkdir -p "$MONITOR_DIR"

LOG_FILE="$MONITOR_DIR/monitor.log"
CSV_FILE="$MONITOR_DIR/monitor.csv"
ALERT_FILE="$MONITOR_DIR/alerts.log"

# CSV header
echo "timestamp,avg_loss,avg_latency,max_latency,hop_count,worst_hop,worst_hop_loss" > "$CSV_FILE"

echo "Starting MTR real-time monitoring..."
echo "Target: $TARGET"
echo "Duration: $DURATION seconds"
echo "Log interval: $LOG_INTERVAL seconds"
echo "Monitor directory: $MONITOR_DIR"
echo ""

# Alert thresholds
LOSS_THRESHOLD=5      # 5% packet loss
LATENCY_THRESHOLD=200 # 200ms latency

END_TIME=$(($(date +%s) + DURATION))
CYCLE_COUNT=0

# Function to analyze MTR output
analyze_mtr_output() {
    local mtr_output="$1"
    local timestamp="$2"

    # Extract metrics
    local total_loss=0
    local total_latency=0
    local max_latency=0
    local hop_count=0
    local worst_hop=""
    local worst_hop_loss=0

    while read line; do
        if echo "$line" | grep -q "^ *[0-9]"; then
            hop_count=$((hop_count + 1))

            hop=$(echo "$line" | awk '{print $1}')
            host=$(echo "$line" | awk '{print $2}')
| loss=$(echo "$line" | awk '{print $3}' | tr -d '%') |
            avg=$(echo "$line" | awk '{print $6}')

            # Accumulate statistics
            if [[ "$loss" =~ ^[0-9]+$ ]]; then
                total_loss=$((total_loss + loss))

                if [ "$loss" -gt "$worst_hop_loss" ]; then
                    worst_hop_loss=$loss
                    worst_hop="$hop ($host)"
                fi
            fi

            if [[ "$avg" =~ ^[0-9]+\.?[0-9]*$ ]]; then
                total_latency=$(echo "$total_latency + $avg" | bc)

                if (( $(echo "$avg > $max_latency" | bc -l) )); then
                    max_latency=$avg
                fi
            fi
        fi
    done <<< "$mtr_output"

    # Calculate averages
    local avg_loss=0
    local avg_latency=0

    if [ "$hop_count" -gt 0 ]; then
        avg_loss=$(echo "scale=2; $total_loss / $hop_count" | bc)
        avg_latency=$(echo "scale=2; $total_latency / $hop_count" | bc)
    fi

    # Log to CSV
    echo "$timestamp,$avg_loss,$avg_latency,$max_latency,$hop_count,$worst_hop,$worst_hop_loss" >> "$CSV_FILE"

    # Check for alerts
    local alerts=""

    if (( $(echo "$avg_loss > $LOSS_THRESHOLD" | bc -l) )); then
        alerts="$alerts HIGH_PACKET_LOSS(${avg_loss}%)"
    fi

    if (( $(echo "$avg_latency > $LATENCY_THRESHOLD" | bc -l) )); then
        alerts="$alerts HIGH_LATENCY(${avg_latency}ms)"
    fi

    if [ -n "$alerts" ]; then
        echo "[$timestamp] ALERT: $alerts" | tee -a "$ALERT_FILE"
        echo "  Worst hop: $worst_hop (${worst_hop_loss}% loss)" | tee -a "$ALERT_FILE"
    fi

    # Display current status
    echo "[$timestamp] Avg Loss: ${avg_loss}%, Avg Latency: ${avg_latency}ms, Max: ${max_latency}ms, Hops: $hop_count"

    if [ "$worst_hop_loss" -gt 0 ]; then
        echo "  Worst hop: $worst_hop (${worst_hop_loss}% loss)"
    fi
}

# Main monitoring loop
while [ $(date +%s) -lt $END_TIME ]; do
    CYCLE_COUNT=$((CYCLE_COUNT + 1))
    TIMESTAMP=$(date '+%Y-%m-%d %H:%M:%S')

    echo "Cycle $CYCLE_COUNT - $TIMESTAMP" | tee -a "$LOG_FILE"

    # Run MTR test
    MTR_OUTPUT=$(mtr --report --report-cycles 20 -n "$TARGET" 2>/dev/null)

    if [ $? -eq 0 ] && [ -n "$MTR_OUTPUT" ]; then
        # Save full output
        echo "=== Cycle $CYCLE_COUNT - $TIMESTAMP ===" >> "$MONITOR_DIR/full_output.log"
        echo "$MTR_OUTPUT" >> "$MONITOR_DIR/full_output.log"
        echo "" >> "$MONITOR_DIR/full_output.log"

        # Analyze output
        analyze_mtr_output "$MTR_OUTPUT" "$TIMESTAMP"
    else
        echo "  ERROR: MTR test failed" | tee -a "$LOG_FILE"
        echo "$TIMESTAMP,0,0,0,0,ERROR,0" >> "$CSV_FILE"
    fi

    echo "" | tee -a "$LOG_FILE"

    # Wait for next cycle
    sleep $LOG_INTERVAL
done

echo "Monitoring completed!"
echo "Results saved in: $MONITOR_DIR"

# Generate summary statistics
if command -v python3 >/dev/null 2>&1; then
    python3 << EOF
import csv
import statistics

# Read monitoring data
data = []
with open('$CSV_FILE', 'r') as f:
    reader = csv.DictReader(f)
    for row in reader:
        if row['avg_loss'] != '0' or row['avg_latency'] != '0':
            try:
                data.append({
                    'loss': float(row['avg_loss']),
                    'latency': float(row['avg_latency']),
                    'max_latency': float(row['max_latency']),
                    'hop_count': int(row['hop_count'])
                })
            except ValueError:
                continue

if data:
    losses = [d['loss'] for d in data]
    latencies = [d['latency'] for d in data]
    max_latencies = [d['max_latency'] for d in data]

    print("Monitoring Summary Statistics:")
    print("==============================")
    print(f"Total monitoring cycles: {len(data)}")
    print(f"Average packet loss: {statistics.mean(losses):.2f}%")
    print(f"Maximum packet loss: {max(losses):.2f}%")
    print(f"Average latency: {statistics.mean(latencies):.2f}ms")
    print(f"Maximum latency: {max(max_latencies):.2f}ms")
    print(f"Latency std deviation: {statistics.stdev(latencies):.2f}ms")

    # Count alerts
    high_loss_count = sum(1 for loss in losses if loss > $LOSS_THRESHOLD)
    high_latency_count = sum(1 for lat in latencies if lat > $LATENCY_THRESHOLD)

    print(f"High packet loss alerts: {high_loss_count}")
    print(f"High latency alerts: {high_latency_count}")
else:
    print("No valid monitoring data collected")
EOF
fi

# Check if alerts were generated
if [ -f "$ALERT_FILE" ]; then
    echo ""
    echo "ALERTS GENERATED:"
    echo "=================="
    cat "$ALERT_FILE"
fi

Herramienta de comparación de rendimiento

#!/usr/bin/env python3
# mtr_performance_comparison.py

import subprocess
import json
import time
import datetime
import argparse
import statistics
from pathlib import Path
import matplotlib.pyplot as plt
import pandas as pd

class MTRComparison:
    def __init__(self, targets, cycles=50):
        self.targets = targets
        self.cycles = cycles
        self.results = {}

    def run_mtr_test(self, target):
        """Run MTR test and parse results"""
        try:
            # Run MTR with report mode
            cmd = ['mtr', '--report', '--report-cycles', str(self.cycles), '-n', target]
            result = subprocess.run(cmd, capture_output=True, text=True, timeout=300)

            if result.returncode == 0:
                return self.parse_mtr_output(result.stdout, target)
            else:
                print(f"MTR failed for {target}: {result.stderr}")
                return None

        except subprocess.TimeoutExpired:
            print(f"MTR timed out for {target}")
            return None
        except Exception as e:
            print(f"Error running MTR for {target}: {e}")
            return None

    def parse_mtr_output(self, output, target):
        """Parse MTR output into structured data"""
        lines = output.strip().split('\n')
        hops = []

        for line in lines:
            # Skip header and empty lines
            if not line.strip() or 'HOST:' in line or 'Start:' in line:
                continue

            # Parse hop lines
            parts = line.split()
            if len(parts) >= 7 and parts[0].isdigit():
                try:
                    hop_data = {
                        'hop': int(parts[0]),
                        'host': parts[1],
                        'loss_percent': float(parts[2].rstrip('%')),
                        'sent': int(parts[3]),
                        'last': float(parts[4]),
                        'avg': float(parts[5]),
                        'best': float(parts[6]),
                        'worst': float(parts[7]),
                        'stdev': float(parts[8]) if len(parts) > 8 else 0.0
                    }
                    hops.append(hop_data)
                except (ValueError, IndexError):
                    continue

        return {
            'target': target,
            'timestamp': datetime.datetime.now().isoformat(),
            'cycles': self.cycles,
            'hops': hops,
            'total_hops': len(hops)
        }

    def run_comparison(self):
        """Run MTR tests for all targets"""
        print(f"Running MTR comparison for {len(self.targets)} targets")
        print(f"Cycles per target: {self.cycles}")
        print("=" * 50)

        for i, target in enumerate(self.targets, 1):
            print(f"Testing {i}/{len(self.targets)}: {target}")

            result = self.run_mtr_test(target)
            if result:
                self.results[target] = result

                # Display summary
                if result['hops']:
                    final_hop = result['hops'][-1]
                    print(f"  Hops: {result['total_hops']}")
                    print(f"  Final hop loss: {final_hop['loss_percent']:.1f}%")
                    print(f"  Final hop avg latency: {final_hop['avg']:.1f}ms")
                else:
                    print("  No hop data available")
            else:
                print("  Test failed")

            print()

            # Small delay between tests
            if i < len(self.targets):
                time.sleep(2)

        return self.results

    def generate_comparison_report(self, output_dir="mtr_comparison"):
        """Generate comprehensive comparison report"""
        if not self.results:
            print("No results to compare")
            return

        output_path = Path(output_dir)
        output_path.mkdir(exist_ok=True)

        timestamp = datetime.datetime.now().strftime("%Y%m%d_%H%M%S")

        # Generate summary statistics
        summary_data = []
        for target, result in self.results.items():
            if result['hops']:
                final_hop = result['hops'][-1]
                summary_data.append({
                    'target': target,
                    'hops': result['total_hops'],
                    'final_loss': final_hop['loss_percent'],
                    'final_avg_latency': final_hop['avg'],
                    'final_best_latency': final_hop['best'],
                    'final_worst_latency': final_hop['worst'],
                    'final_stdev': final_hop['stdev']
                })

        # Save to CSV
        if summary_data:
            df = pd.DataFrame(summary_data)
            csv_file = output_path / f"mtr_comparison_{timestamp}.csv"
            df.to_csv(csv_file, index=False)
            print(f"Summary CSV saved: {csv_file}")

        # Generate visualizations
        self.create_visualizations(output_path, timestamp)

        # Generate HTML report
        html_file = output_path / f"mtr_comparison_{timestamp}.html"
        self.generate_html_report(html_file, summary_data)

        # Save raw JSON data
        json_file = output_path / f"mtr_raw_data_{timestamp}.json"
        with open(json_file, 'w') as f:
            json.dump(self.results, f, indent=2)

        print(f"Comparison report generated:")
        print(f"  HTML: {html_file}")
        print(f"  JSON: {json_file}")

        return str(html_file)

    def create_visualizations(self, output_path, timestamp):
        """Create comparison visualizations"""
        if not self.results:
            return

        # Prepare data for plotting
        targets = []
        avg_latencies = []
        loss_percentages = []
        hop_counts = []

        for target, result in self.results.items():
            if result['hops']:
                final_hop = result['hops'][-1]
                targets.append(target)
                avg_latencies.append(final_hop['avg'])
                loss_percentages.append(final_hop['loss_percent'])
                hop_counts.append(result['total_hops'])

        if not targets:
            return

        # Create subplots
        fig, ((ax1, ax2), (ax3, ax4)) = plt.subplots(2, 2, figsize=(15, 12))
        fig.suptitle('MTR Network Performance Comparison', fontsize=16)

        # 1. Average Latency Comparison
        ax1.bar(range(len(targets)), avg_latencies, color='skyblue')
        ax1.set_title('Average Latency Comparison')
        ax1.set_ylabel('Latency (ms)')
        ax1.set_xticks(range(len(targets)))
        ax1.set_xticklabels(targets, rotation=45, ha='right')

        # Add value labels on bars
        for i, v in enumerate(avg_latencies):
            ax1.text(i, v + max(avg_latencies) * 0.01, f'{v:.1f}ms', 
                    ha='center', va='bottom')

        # 2. Packet Loss Comparison
        colors = ['green' if loss == 0 else 'orange' if loss < 5 else 'red' 
                 for loss in loss_percentages]
        ax2.bar(range(len(targets)), loss_percentages, color=colors)
        ax2.set_title('Packet Loss Comparison')
        ax2.set_ylabel('Packet Loss (%)')
        ax2.set_xticks(range(len(targets)))
        ax2.set_xticklabels(targets, rotation=45, ha='right')

        # Add value labels
        for i, v in enumerate(loss_percentages):
            ax2.text(i, v + max(loss_percentages + [1]) * 0.01, f'{v:.1f}%', 
                    ha='center', va='bottom')

        # 3. Hop Count Comparison
        ax3.bar(range(len(targets)), hop_counts, color='lightcoral')
        ax3.set_title('Network Hop Count Comparison')
        ax3.set_ylabel('Number of Hops')
        ax3.set_xticks(range(len(targets)))
        ax3.set_xticklabels(targets, rotation=45, ha='right')

        # Add value labels
        for i, v in enumerate(hop_counts):
            ax3.text(i, v + max(hop_counts) * 0.01, str(v), 
                    ha='center', va='bottom')

        # 4. Latency vs Loss Scatter Plot
        ax4.scatter(avg_latencies, loss_percentages, s=100, alpha=0.7)
        ax4.set_title('Latency vs Packet Loss')
        ax4.set_xlabel('Average Latency (ms)')
        ax4.set_ylabel('Packet Loss (%)')

        # Add target labels to scatter points
        for i, target in enumerate(targets):
            ax4.annotate(target, (avg_latencies[i], loss_percentages[i]),
                        xytext=(5, 5), textcoords='offset points', fontsize=8)

        plt.tight_layout()

        # Save plot
        plot_file = output_path / f"mtr_comparison_plots_{timestamp}.png"
        plt.savefig(plot_file, dpi=300, bbox_inches='tight')
        plt.close()

        print(f"Visualization saved: {plot_file}")

    def generate_html_report(self, output_file, summary_data):
        """Generate HTML comparison report"""
        html_content = f"""
<!DOCTYPE html>
<html>
<head>
    <title>MTR Network Performance Comparison Report</title>
    <style>
        body {{ font-family: Arial, sans-serif; margin: 20px; }}
        table {{ border-collapse: collapse; width: 100%; margin: 20px 0; }}
        th, td {{ border: 1px solid #ddd; padding: 12px; text-align: left; }}
        th {{ background-color: #f2f2f2; font-weight: bold; }}
        .summary {{ background-color: #e7f3ff; padding: 15px; border-radius: 5px; margin: 20px 0; }}
        .good {{ background-color: #d4edda; }}
        .warning {{ background-color: #fff3cd; }}
        .alert {{ background-color: #f8d7da; }}
        .metric {{ display: inline-block; margin: 10px 20px; }}
        .best {{ font-weight: bold; color: #28a745; }}
        .worst {{ font-weight: bold; color: #dc3545; }}
    </style>
</head>
<body>
    <h1>MTR Network Performance Comparison Report</h1>
    <div class="summary">
        <h3>Test Summary</h3>
        <p><strong>Targets Tested:</strong> {len(self.targets)}</p>
        <p><strong>Cycles per Target:</strong> {self.cycles}</p>
        <p><strong>Generated:</strong> {datetime.datetime.now()}</p>
    </div>
"""

        if summary_data:
            # Find best and worst performers
            best_latency = min(summary_data, key=lambda x: x['final_avg_latency'])
            worst_latency = max(summary_data, key=lambda x: x['final_avg_latency'])
            best_loss = min(summary_data, key=lambda x: x['final_loss'])
            worst_loss = max(summary_data, key=lambda x: x['final_loss'])

            html_content += f"""
    <div class="summary">
        <h3>Performance Highlights</h3>
        <div class="metric"><strong>Best Latency:</strong> <span class="best">{best_latency['target']} ({best_latency['final_avg_latency']:.1f}ms)</span></div>
        <div class="metric"><strong>Worst Latency:</strong> <span class="worst">{worst_latency['target']} ({worst_latency['final_avg_latency']:.1f}ms)</span></div>
        <div class="metric"><strong>Best Loss:</strong> <span class="best">{best_loss['target']} ({best_loss['final_loss']:.1f}%)</span></div>
        <div class="metric"><strong>Worst Loss:</strong> <span class="worst">{worst_loss['target']} ({worst_loss['final_loss']:.1f}%)</span></div>
    </div>
"""

            # Comparison table
            html_content += """
    <h2>Detailed Comparison</h2>
    <table>
        <tr>
            <th>Target</th>
            <th>Hops</th>
            <th>Packet Loss (%)</th>
            <th>Avg Latency (ms)</th>
            <th>Best Latency (ms)</th>
            <th>Worst Latency (ms)</th>
            <th>Std Dev (ms)</th>
            <th>Performance Rating</th>
        </tr>
"""

            for data in summary_data:
                # Determine performance rating
                if data['final_loss'] == 0 and data['final_avg_latency'] < 50:
                    rating = "Excellent"
                    row_class = "good"
                elif data['final_loss'] < 1 and data['final_avg_latency'] < 100:
                    rating = "Good"
                    row_class = "good"
                elif data['final_loss'] < 5 and data['final_avg_latency'] < 200:
                    rating = "Acceptable"
                    row_class = "warning"
                else:
                    rating = "Poor"
                    row_class = "alert"

                html_content += f"""
        <tr class="{row_class}">
            <td>{data['target']}</td>
            <td>{data['hops']}</td>
            <td>{data['final_loss']:.1f}</td>
            <td>{data['final_avg_latency']:.1f}</td>
            <td>{data['final_best_latency']:.1f}</td>
            <td>{data['final_worst_latency']:.1f}</td>
            <td>{data['final_stdev']:.1f}</td>
            <td>{rating}</td>
        </tr>
"""

            html_content += "</table>"

        # Detailed results for each target
        html_content += "<h2>Detailed Hop Analysis</h2>"

        for target, result in self.results.items():
            html_content += f"""
    <h3>{target}</h3>
    <table>
        <tr>
            <th>Hop</th>
            <th>Host</th>
            <th>Loss (%)</th>
            <th>Packets Sent</th>
            <th>Last (ms)</th>
            <th>Avg (ms)</th>
            <th>Best (ms)</th>
            <th>Worst (ms)</th>
            <th>StdDev (ms)</th>
        </tr>
"""

            for hop in result['hops']:
                # Determine row class based on performance
                if hop['loss_percent'] == 0 and hop['avg'] < 100:
                    row_class = "good"
                elif hop['loss_percent'] < 5 and hop['avg'] < 200:
                    row_class = "warning"
                else:
                    row_class = "alert"

                html_content += f"""
        <tr class="{row_class}">
            <td>{hop['hop']}</td>
            <td>{hop['host']}</td>
            <td>{hop['loss_percent']:.1f}</td>
            <td>{hop['sent']}</td>
            <td>{hop['last']:.1f}</td>
            <td>{hop['avg']:.1f}</td>
            <td>{hop['best']:.1f}</td>
            <td>{hop['worst']:.1f}</td>
            <td>{hop['stdev']:.1f}</td>
        </tr>
"""

            html_content += "</table>"

        html_content += """
</body>
</html>
"""

        with open(output_file, 'w') as f:
            f.write(html_content)

def main():
    parser = argparse.ArgumentParser(description='MTR Performance Comparison Tool')
    parser.add_argument('targets', nargs='+', help='Target hostnames or IPs to compare')
    parser.add_argument('--cycles', type=int, default=50, help='Number of cycles per test (default: 50)')
    parser.add_argument('--output-dir', default='mtr_comparison', help='Output directory for results')

    args = parser.parse_args()

    # Create comparison instance
    comparison = MTRComparison(args.targets, args.cycles)

    # Run comparison
    results = comparison.run_comparison()

    # Generate report
    if results:
        report_file = comparison.generate_comparison_report(args.output_dir)
        print(f"\nOpen the HTML report: {report_file}")
    else:
        print("No successful tests to compare")

if __name__ == "__main__":
    main()

Esta amplia hoja de trampa MTR proporciona todo lo necesario para el diagnóstico profesional de red, monitoreo en tiempo real y análisis comparativo de red, desde el rastreo básico de rutas hasta escenarios avanzados de automatización y visualización.