Spaces:
Runtime error
Runtime error
File size: 9,071 Bytes
33bcc2b d8e0173 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 |
import gradio as gr
import time
import json
from typing import Dict, List, Optional, Tuple
import networkx as nx
import matplotlib.pyplot as plt
import matplotlib.patches as patches
from io import BytesIO
import base64
class RouteEntry:
def __init__(self, next_hop_ip: str = "", hop_count: int = float('inf')):
self.next_hop_ip = next_hop_ip
self.hop_count = hop_count
def __repr__(self):
return f"RouteEntry(next_hop={self.next_hop_ip}, hops={self.hop_count})"
class Device:
def __init__(self, name: str, ip_address: str, mac_address: str):
self.name = name
self.ip_address = ip_address
self.mac_address = mac_address
self.gateway = ""
self.connected_router = None
def connect_router(self, router, gateway_ip: str):
self.connected_router = router
self.gateway = gateway_ip
class Router:
def __init__(self, name: str, ip_address: str):
self.name = name
self.ip_address = ip_address
self.routing_table: Dict[str, RouteEntry] = {}
self.neighbors: List['Router'] = []
self.connected_devices: List[Device] = []
def connect_neighbor(self, neighbor: 'Router'):
if neighbor not in self.neighbors:
self.neighbors.append(neighbor)
def connect_device(self, device: Device):
self.connected_devices.append(device)
device.connect_router(self, self.ip_address)
# Add route to directly connected network
network = self.get_network(device.ip_address)
self.routing_table[network] = RouteEntry(device.ip_address, 1)
def exchange_routes(self) -> List[str]:
updates = []
for neighbor in self.neighbors:
for dest_net, entry in self.routing_table.items():
new_hops = entry.hop_count + 1
if new_hops > 15: # RIP hop limit
continue
if (dest_net not in neighbor.routing_table or
new_hops < neighbor.routing_table[dest_net].hop_count):
neighbor.routing_table[dest_net] = RouteEntry(self.ip_address, new_hops)
update_msg = f"{neighbor.name} learned route to {dest_net} via {self.ip_address} (hops: {new_hops})"
updates.append(update_msg)
return updates
def get_routing_table(self) -> Dict[str, Dict[str, any]]:
table = {}
for dest, entry in self.routing_table.items():
table[dest] = {
"next_hop": entry.next_hop_ip,
"hop_count": entry.hop_count if entry.hop_count != float('inf') else "∞"
}
return table
def get_next_hop(self, dest_ip: str) -> str:
dest_net = self.get_network(dest_ip)
if dest_net in self.routing_table:
return self.routing_table[dest_net].next_hop_ip
return "unreachable"
@staticmethod
def get_network(ip: str) -> str:
parts = ip.split('.')
return f"{parts[0]}.{parts[1]}.{parts[2]}.0"
class NetworkSimulator:
def __init__(self):
self.routers: List[Router] = []
self.devices: List[Device] = []
self.simulation_log: List[str] = []
self.setup_default_topology()
def setup_default_topology(self):
# Create routers
router1 = Router("Router1", "192.168.1.1")
router2 = Router("Router2", "192.168.2.1")
router3 = Router("Router3", "192.168.3.1")
# Connect routers
router1.connect_neighbor(router2)
router2.connect_neighbor(router1)
router2.connect_neighbor(router3)
router3.connect_neighbor(router2)
# Create devices
dev1 = Device("PC1", "192.168.1.2", "00:1A:2B:3C:4D:01")
dev2 = Device("PC2", "192.168.2.2", "00:1A:2B:3C:4D:02")
dev3 = Device("PC3", "192.168.3.2", "00:1A:2B:3C:4D:03")
# Connect devices to routers
router1.connect_device(dev1)
router2.connect_device(dev2)
router3.connect_device(dev3)
self.routers = [router1, router2, router3]
self.devices = [dev1, dev2, dev3]
self.simulation_log = ["Network topology initialized"]
def run_rip_simulation(self, rounds: int = 3) -> Tuple[str, Dict]:
log = []
log.append("=== Starting RIP Simulation ===\n")
for round_num in range(1, rounds + 1):
log.append(f"--- RIP Round {round_num} ---")
round_updates = []
for router in self.routers:
updates = router.exchange_routes()
round_updates.extend(updates)
if round_updates:
log.extend(round_updates)
else:
log.append("No new route updates")
log.append("")
# Generate routing tables
routing_tables = {}
for router in self.routers:
routing_tables[router.name] = router.get_routing_table()
log.append("=== Final Routing Tables ===")
for router_name, table in routing_tables.items():
log.append(f"\n{router_name} Routing Table:")
for dest, info in table.items():
log.append(f" {dest} → Next Hop: {info['next_hop']}, Hops: {info['hop_count']}")
return "\n".join(log), routing_tables
def simulate_data_transfer(self, src_device_name: str, dst_device_name: str) -> str:
src_device = next((d for d in self.devices if d.name == src_device_name), None)
dst_device = next((d for d in self.devices if d.name == dst_device_name), None)
if not src_device or not dst_device:
return "Error: Device not found"
log = []
log.append(f"\n=== Data Transfer: {src_device.name} → {dst_device.name} ===")
log.append(f"Source: {src_device.ip_address}")
log.append(f"Destination: {dst_device.ip_address}")
next_hop = src_device.connected_router.get_next_hop(dst_device.ip_address)
if next_hop == "unreachable":
log.append("❌ Destination unreachable")
else:
log.append(f"✅ Next hop: {next_hop}")
log.append(f"✅ Data successfully routed to {dst_device.name}")
return "\n".join(log)
def create_network_diagram(self) -> str:
# Create network graph
G = nx.Graph()
pos = {}
# Add routers
for i, router in enumerate(self.routers):
G.add_node(router.name, type='router')
pos[router.name] = (i * 3, 1) # Position routers horizontally
# Add devices
for i, device in enumerate(self.devices):
G.add_node(device.name, type='device')
pos[device.name] = (i * 3, 0) # Position devices below routers
# Add edges between routers
for router in self.routers:
for neighbor in router.neighbors:
G.add_edge(router.name, neighbor.name)
# Add edges between devices and routers
for device in self.devices:
if device.connected_router:
G.add_edge(device.name, device.connected_router.name)
# Create matplotlib figure
plt.figure(figsize=(12, 8))
# Draw nodes
router_nodes = [n for n, d in G.nodes(data=True) if d['type'] == 'router']
device_nodes = [n for n, d in G.nodes(data=True) if d['type'] == 'device']
nx.draw_networkx_nodes(G, pos, nodelist=router_nodes,
node_color='lightblue', node_size=1500,
node_shape='s', label='Routers')
nx.draw_networkx_nodes(G, pos, nodelist=device_nodes,
node_color='lightgreen', node_size=1000,
node_shape='o', label='Devices')
# Draw edges
nx.draw_networkx_edges(G, pos, alpha=0.6, width=2)
# Draw labels
nx.draw_networkx_labels(G, pos, font_size=10, font_weight='bold')
# Add IP addresses as labels
ip_labels = {}
for router in self.routers:
ip_labels[router.name] = router.ip_address
for device in self.devices:
ip_labels[device.name] = device.ip_address
label_pos = {k: (v[0], v[1] - 0.2) for k, v in pos.items()}
nx.draw_networkx_labels(G, label_pos, ip_labels, font_size=8, font_color='red')
plt.title("Network Topology", size=16, weight='bold')
plt.legend()
plt.axis('off')
plt.tight_layout()
# Convert to base64 string
buffer = BytesIO()
plt.savefig(buffer, format='png', dpi=150, bbox_inches='tight')
buffer.seek(0)
image_base64 = base64.b64encode(buffer.getvalue()).decode()
plt.close()
|