V8055 commited on
Commit
33bcc2b
·
verified ·
1 Parent(s): 87908ef

Update app.py

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