Claude Code Plugins

Community-maintained marketplace

Feedback
15
0

Create visual and logical maps of network topology. Use this skill when documenting network infrastructure, identifying network segments, or creating diagrams of discovered systems.

Install Skill

1Download skill
2Enable skills in Claude

Open claude.ai/settings/capabilities and find the "Skills" section

3Upload to Claude

Click "Upload skill" and select the downloaded ZIP file

Note: Please verify skill by going through its instructions before using it.

SKILL.md

name network-mapping
description Create visual and logical maps of network topology. Use this skill when documenting network infrastructure, identifying network segments, or creating diagrams of discovered systems.

Network Mapping

Create and visualize network topology maps.

Network Discovery

import ipaddress
from typing import List, Dict
import nmap

def discover_hosts(network: str) -> List[str]:
    """Discover live hosts on network."""
    scanner = nmap.PortScanner()
    scanner.scan(network, arguments='-sn')  # Ping scan

    live_hosts = []
    for host in scanner.all_hosts():
        if scanner[host].state() == 'up':
            live_hosts.append(host)

    return live_hosts

def discover_subnets(targets: List[str]) -> Dict[str, List[str]]:
    """Group hosts by subnet."""
    subnets = {}

    for host in targets:
        try:
            ip = ipaddress.ip_address(host)
            # Assume /24 subnet
            network = ipaddress.ip_network(f"{host}/24", strict=False)
            net_str = str(network)

            if net_str not in subnets:
                subnets[net_str] = []
            subnets[net_str].append(host)
        except ValueError:
            continue

    return subnets

def trace_route(target: str) -> List[Dict]:
    """Trace route to target."""
    scanner = nmap.PortScanner()
    scanner.scan(target, arguments='--traceroute')

    hops = []
    for host in scanner.all_hosts():
        if 'osmatch' in scanner[host]:
            trace = scanner[host].get('trace', {})
            for hop in trace.get('hop', []):
                hops.append({
                    'ttl': hop.get('ttl'),
                    'ip': hop.get('ipaddr'),
                    'host': hop.get('host', ''),
                    'rtt': hop.get('rtt')
                })

    return hops

Build Network Graph

import networkx as nx
import json

def build_network_graph(scan_results: List[Dict]) -> nx.Graph:
    """Build network graph from scan results."""
    G = nx.Graph()

    for host_data in scan_results:
        host = host_data.get('ip') or host_data.get('host')

        # Add host node
        G.add_node(host, **{
            'type': 'host',
            'hostname': host_data.get('hostname', ''),
            'os': host_data.get('os', 'unknown'),
            'ports': [p['port'] for p in host_data.get('ports', [])]
        })

        # Add service nodes
        for port in host_data.get('ports', []):
            if port.get('state') == 'open':
                service_id = f"{host}:{port['port']}"
                G.add_node(service_id, **{
                    'type': 'service',
                    'port': port['port'],
                    'service': port.get('service', 'unknown'),
                    'version': port.get('version', '')
                })
                G.add_edge(host, service_id)

    return G

def add_routing_info(G: nx.Graph, traceroutes: Dict[str, List]) -> nx.Graph:
    """Add routing information to graph."""
    for target, hops in traceroutes.items():
        prev_hop = None
        for hop in hops:
            hop_ip = hop.get('ip')
            if hop_ip:
                if hop_ip not in G:
                    G.add_node(hop_ip, type='router')

                if prev_hop:
                    G.add_edge(prev_hop, hop_ip, type='route')

                prev_hop = hop_ip

        # Connect last hop to target
        if prev_hop and target in G:
            G.add_edge(prev_hop, target, type='route')

    return G

def export_graph(G: nx.Graph, filename: str, format: str = 'json'):
    """Export network graph."""
    if format == 'json':
        data = nx.node_link_data(G)
        with open(filename, 'w') as f:
            json.dump(data, f, indent=2)

    elif format == 'gexf':
        nx.write_gexf(G, filename)

    elif format == 'graphml':
        nx.write_graphml(G, filename)

Visualize Network

import matplotlib.pyplot as plt
import matplotlib.patches as mpatches

def visualize_network(G: nx.Graph, output_file: str = None):
    """Create network visualization."""
    plt.figure(figsize=(16, 12))

    # Node colors by type
    node_colors = []
    for node in G.nodes():
        node_type = G.nodes[node].get('type', 'unknown')
        if node_type == 'host':
            node_colors.append('#2196F3')  # Blue
        elif node_type == 'service':
            node_colors.append('#4CAF50')  # Green
        elif node_type == 'router':
            node_colors.append('#FF9800')  # Orange
        else:
            node_colors.append('#9E9E9E')  # Gray

    # Node sizes
    node_sizes = []
    for node in G.nodes():
        node_type = G.nodes[node].get('type', 'unknown')
        if node_type == 'host':
            node_sizes.append(1000)
        elif node_type == 'service':
            node_sizes.append(300)
        else:
            node_sizes.append(500)

    # Layout
    pos = nx.spring_layout(G, k=2, iterations=50)

    # Draw
    nx.draw_networkx_nodes(G, pos, node_color=node_colors, node_size=node_sizes, alpha=0.8)
    nx.draw_networkx_edges(G, pos, alpha=0.5)

    # Labels for hosts only
    host_labels = {n: n for n in G.nodes() if G.nodes[n].get('type') == 'host'}
    nx.draw_networkx_labels(G, pos, host_labels, font_size=8)

    # Legend
    legend_patches = [
        mpatches.Patch(color='#2196F3', label='Host'),
        mpatches.Patch(color='#4CAF50', label='Service'),
        mpatches.Patch(color='#FF9800', label='Router'),
    ]
    plt.legend(handles=legend_patches, loc='upper left')

    plt.title('Network Topology Map')
    plt.axis('off')

    if output_file:
        plt.savefig(output_file, dpi=300, bbox_inches='tight')
    else:
        plt.show()

    plt.close()

def visualize_by_subnet(G: nx.Graph, output_file: str = None):
    """Create subnet-based visualization."""
    from matplotlib.patches import FancyBboxPatch

    plt.figure(figsize=(20, 14))

    # Group nodes by subnet
    subnets = {}
    for node in G.nodes():
        if G.nodes[node].get('type') == 'host':
            try:
                ip = ipaddress.ip_address(node)
                subnet = str(ipaddress.ip_network(f"{node}/24", strict=False))
                if subnet not in subnets:
                    subnets[subnet] = []
                subnets[subnet].append(node)
            except:
                pass

    # Create positions with subnet clustering
    pos = {}
    subnet_y = 0
    for subnet, hosts in subnets.items():
        for i, host in enumerate(hosts):
            pos[host] = (i * 2, subnet_y)

            # Position services near their host
            for neighbor in G.neighbors(host):
                if G.nodes[neighbor].get('type') == 'service':
                    pos[neighbor] = (i * 2 + 0.3, subnet_y - 0.5)

        subnet_y += 3

    # Draw with subnet boxes
    ax = plt.gca()
    subnet_y = 0
    colors = plt.cm.Set3(range(len(subnets)))
    for idx, (subnet, hosts) in enumerate(subnets.items()):
        width = len(hosts) * 2 + 1
        rect = FancyBboxPatch(
            (-0.5, subnet_y - 1),
            width, 2,
            boxstyle="round,pad=0.1",
            facecolor=colors[idx],
            alpha=0.3,
            edgecolor='black'
        )
        ax.add_patch(rect)
        plt.text(-0.3, subnet_y + 0.8, subnet, fontsize=10, fontweight='bold')
        subnet_y += 3

    # Draw nodes
    for node in G.nodes():
        if node in pos:
            node_type = G.nodes[node].get('type', 'unknown')
            if node_type == 'host':
                plt.plot(*pos[node], 'o', markersize=15, color='#2196F3')
                plt.text(pos[node][0], pos[node][1] + 0.2, node, fontsize=8, ha='center')
            elif node_type == 'service':
                port = G.nodes[node].get('port', '')
                plt.plot(*pos[node], 's', markersize=8, color='#4CAF50')
                plt.text(pos[node][0], pos[node][1] - 0.2, str(port), fontsize=6, ha='center')

    # Draw edges
    for u, v in G.edges():
        if u in pos and v in pos:
            plt.plot([pos[u][0], pos[v][0]], [pos[u][1], pos[v][1]], 'k-', alpha=0.3)

    plt.title('Network Map by Subnet')
    plt.axis('off')

    if output_file:
        plt.savefig(output_file, dpi=300, bbox_inches='tight')
    else:
        plt.show()

    plt.close()

Generate Reports

def generate_topology_report(G: nx.Graph) -> str:
    """Generate text-based topology report."""
    report = []

    report.append("=" * 60)
    report.append("NETWORK TOPOLOGY REPORT")
    report.append("=" * 60)

    # Summary
    hosts = [n for n in G.nodes() if G.nodes[n].get('type') == 'host']
    services = [n for n in G.nodes() if G.nodes[n].get('type') == 'service']
    routers = [n for n in G.nodes() if G.nodes[n].get('type') == 'router']

    report.append(f"\nTotal Hosts: {len(hosts)}")
    report.append(f"Total Services: {len(services)}")
    report.append(f"Routers/Gateways: {len(routers)}")

    # Host details
    report.append("\n" + "-" * 60)
    report.append("HOST DETAILS")
    report.append("-" * 60)

    for host in hosts:
        report.append(f"\n{host}")
        hostname = G.nodes[host].get('hostname', '')
        if hostname:
            report.append(f"  Hostname: {hostname}")

        os_info = G.nodes[host].get('os', '')
        if os_info:
            report.append(f"  OS: {os_info}")

        # List services
        host_services = [n for n in G.neighbors(host) if G.nodes[n].get('type') == 'service']
        if host_services:
            report.append("  Open Ports:")
            for svc in sorted(host_services, key=lambda x: G.nodes[x].get('port', 0)):
                port = G.nodes[svc].get('port')
                service_name = G.nodes[svc].get('service', 'unknown')
                version = G.nodes[svc].get('version', '')
                report.append(f"    - {port}: {service_name} {version}".strip())

    # Network paths (if routing info available)
    if routers:
        report.append("\n" + "-" * 60)
        report.append("NETWORK PATH")
        report.append("-" * 60)
        for router in routers:
            report.append(f"  Router: {router}")

    return '\n'.join(report)

def export_to_html(G: nx.Graph, output_file: str):
    """Export network map to interactive HTML."""
    from pyvis.network import Network

    net = Network(height='800px', width='100%', bgcolor='#ffffff')

    # Add nodes
    for node in G.nodes():
        node_type = G.nodes[node].get('type', 'unknown')
        if node_type == 'host':
            net.add_node(node, label=node, color='#2196F3', size=25)
        elif node_type == 'service':
            port = G.nodes[node].get('port', '')
            service = G.nodes[node].get('service', '')
            net.add_node(node, label=f"{service}:{port}", color='#4CAF50', size=15)
        elif node_type == 'router':
            net.add_node(node, label=node, color='#FF9800', size=20)

    # Add edges
    for u, v in G.edges():
        net.add_edge(u, v)

    net.save_graph(output_file)