| 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)