Network Monitoring and Configuration Tool
Network Monitoring and Configuration Tool
# ====================
# GLOBAL CONFIGURATION
# ====================
SERVER_PORT = 6499
LOG_PREFIX = "LSE"
NETWORK_SETTINGS = {
'ip': '[Link]',
'mask': '[Link]',
'gateway': '[Link]',
'dns1': '[Link]',
'dns2': '[Link]'
}
# CPU monitoring
cpu_percent = 0
def monitor_cpu():
global cpu_percent
while True:
cpu_percent = psutil.cpu_percent(interval=1)
# Ping monitoring
ping_status = "Disconnected"
ping_time = "0ms"
def monitor_ping():
global ping_status, ping_time
while True:
try:
response_time = [Link]('[Link]', timeout=2)
if response_time is not None:
ping_status = "Connected"
ping_time = f"{int(response_time * 1000)}ms"
else:
ping_status = "Disconnected"
ping_time = "Timeout"
except:
ping_status = "Disconnected"
ping_time = "Error"
[Link](5)
# =================
# LOGGING MECHANISM
# =================
class LogSync:
def __init__(self):
[Link] = []
[Link] = [Link]()
log_sync = LogSync()
# ===================
# SYSTEM INFO HELPERS
# ===================
def get_system_specs():
return {
"hostname": [Link](),
"os": f"{[Link]()} {[Link]()}",
"processor": [Link](),
"ram": f"{round(psutil.virtual_memory().total / (1024**3), 2)} GB",
"architecture": [Link]()[0]
}
def get_performance_data():
global prev_bytes_sent, prev_bytes_recv, prev_time
return {
"cpu": cpu_percent,
"memory": psutil.virtual_memory().percent,
"network": network_usage,
"ping_status": ping_status,
"ping_time": ping_time
}
# =========================
# NETWORK CONFIGURATION
# =========================
def get_ethernet_interfaces():
"""Get Ethernet interfaces using netsh command"""
try:
# Run netsh command to get interfaces
result = subprocess.check_output('netsh interface show interface',
shell=True, text=True)
interfaces = []
lines = [Link]('\n')
return interfaces
except Exception as e:
log_sync.add_log(f"Error getting interfaces: {str(e)}")
return ["Ethernet"] # Default fallback
def set_dhcp_ip(interface):
"""Set DHCP IP using netsh commands"""
try:
# Run commands in background without showing console window
startupinfo = [Link]()
[Link] |= subprocess.STARTF_USESHOWWINDOW
def set_dhcp_dns(interface):
"""Set DHCP DNS using netsh commands"""
try:
# Run commands in background without showing console window
startupinfo = [Link]()
[Link] |= subprocess.STARTF_USESHOWWINDOW
def get_network_info():
"""Get detailed network information using ipconfig"""
net_info = []
try:
# Get ipconfig output
result = subprocess.check_output('ipconfig /all', shell=True, text=True)
current_adapter = ""
adapter_info = {}
current_adapter = [Link](':')[0].strip()
adapter_info = {
'name': current_adapter,
'ipv4': [],
'ipv6': [],
'mac': None,
'dns': [],
'gateway': []
}
return net_info
except Exception as e:
log_sync.add_log(f"Error getting network info: {str(e)}")
return []
# =========================
# FLASK WEB PANEL (Backend)
# =========================
app = Flask(__name__, template_folder='', static_folder='')
@[Link]('/')
def index():
return render_template('[Link]')
@[Link]('/system_info')
def system_info():
return jsonify({
"specs": get_system_specs(),
"performance": get_performance_data()
})
@[Link]('/get_logs')
def get_logs():
return jsonify(logs=log_sync.logs)
@[Link]('/get_interfaces')
def get_interfaces():
return jsonify(interfaces=get_ethernet_interfaces())
@[Link]('/get_network_info')
def get_network_info_route():
return jsonify(network_info=get_network_info())
@[Link]('/update_ip_settings', methods=['POST'])
def update_ip_settings():
data = [Link]
interface = [Link]('interface')
mode = [Link]('mode')
ip = [Link]('ip')
mask = [Link]('mask')
gateway = [Link]('gateway')
if mode == 'static':
success, message = set_static_ip(interface, ip, mask, gateway)
else:
success, message = set_dhcp_ip(interface)
@[Link]('/update_dns_settings', methods=['POST'])
def update_dns_settings():
data = [Link]
interface = [Link]('interface')
mode = [Link]('mode')
dns1 = [Link]('dns1')
dns2 = [Link]('dns2')
if mode == 'static':
success, message = set_static_dns(interface, dns1, dns2)
else:
success, message = set_dhcp_dns(interface)
@[Link]('/update_datetime', methods=['POST'])
def update_datetime():
data = [Link]
date_str = [Link]('date')
time_str = [Link]('time')
try:
# Create datetime object
dt = [Link](f"{date_str} {time_str}", "%Y/%m/%d %H:%M:
%S")
@[Link]('/export_logs')
def export_logs():
log_content = "\n".join(log_sync.logs)
with open("panel_logs.lsremplog", "w") as f:
[Link](log_content)
return send_file("panel_logs.lsremplog", as_attachment=True)
# =====================
# TKINTER CONTROL PANEL
# =====================
class ControlPanel:
def __init__(self, root):
[Link] = root
[Link]("Teknir Control Panel")
[Link]("800x500")
[Link](bg='#2d2d39')
self.create_widgets()
self.server_running = False
self.server_thread = None
self.status_frame = None
def create_widgets(self):
# Header
header = [Link]([Link], bg='#1e1e2d', height=50)
[Link](fill='x')
# Control buttons
btn_frame = [Link](header, bg='#1e1e2d')
btn_frame.pack(side='right', padx=20)
# Log display
log_frame = [Link]([Link], text="Server Logs", font=("System",
10),
fg="white", bg='#2d2d39', bd=1, relief='sunken')
log_frame.pack(fill='both', expand=True, padx=10, pady=10)
def toggle_server(self):
if not self.server_running:
self.start_server()
else:
self.stop_server()
def start_server(self):
def run_flask():
[Link](port=SERVER_PORT, debug=False, use_reloader=False)
def stop_server(self):
self.server_running = False
self.start_btn.config(text="Start Server", bg='#4CAF50')
log_sync.add_log("Web server stopped")
self.update_log_display()
self.show_status("Server stopped", False)
def update_log_display(self):
self.log_area.config(state='normal')
self.log_area.delete(1.0, [Link])
for log in log_sync.logs:
self.log_area.insert([Link], log + '\n')
self.log_area.config(state='disabled')
self.log_area.yview([Link])
[Link](1000, self.update_log_display)
# ===================
# HTML/CSS/JS CONTENT
# ===================
html_content = """
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Teknir Web Panel</title>
<style>
:root {
--bg-primary: #2d2d39;
--bg-secondary: #1e1e2d;
--bg-tertiary: #252533;
--text-primary: #e0e0e0;
--text-secondary: #a0a0b0;
--accent: #4d7cff;
--success: #4CAF50;
--error: #f44336;
--warning: #FF9800;
--sidebar-width: 250px;
--transition-speed: 0.3s;
}
[data-theme="light"] {
--bg-primary: #f5f5f7;
--bg-secondary: #ffffff;
--bg-tertiary: #eaeaea;
--text-primary: #333333;
--text-secondary: #666666;
}
* {
margin: 0;
padding: 0;
box-sizing: border-box;
font-family: 'system-ui', -apple-system, BlinkMacSystemFont,
'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell,
'Open Sans', 'Helvetica Neue', sans-serif;
}
body {
background-color: var(--bg-primary);
color: var(--text-primary);
display: flex;
min-height: 100vh;
overflow: hidden;
transition: background-color var(--transition-speed);
}
.sidebar {
width: var(--sidebar-width);
background: var(--bg-secondary);
height: 100vh;
padding: 20px 0;
transition: width var(--transition-speed);
overflow-y: auto;
box-shadow: 2px 0 10px rgba(0, 0, 0, 0.2);
z-index: 100;
}
.[Link] {
width: 60px;
}
.sidebar-header {
padding: 0 20px 20px;
border-bottom: 1px solid var(--bg-tertiary);
margin-bottom: 20px;
}
.sidebar-header h2 {
font-size: 1.2rem;
white-space: nowrap;
overflow: hidden;
}
.[Link] .sidebar-header h2 {
display: none;
}
.section-title {
padding: 10px 20px;
color: var(--text-secondary);
font-size: 0.8rem;
text-transform: uppercase;
letter-spacing: 1px;
white-space: nowrap;
}
.[Link] .section-title {
display: none;
}
.nav-item {
display: flex;
align-items: center;
padding: 12px 20px;
color: var(--text-primary);
text-decoration: none;
transition: all 0.2s;
white-space: nowrap;
}
.nav-item:hover {
background: var(--bg-tertiary);
}
.[Link] {
background: var(--bg-tertiary);
border-left: 4px solid var(--accent);
}
.nav-icon {
margin-right: 15px;
font-size: 1.2rem;
}
.[Link] .nav-text {
display: none;
}
.main-content {
flex: 1;
display: flex;
flex-direction: column;
overflow-y: auto;
height: 100vh;
transition: margin-left var(--transition-speed);
}
.topbar {
display: flex;
justify-content: space-between;
align-items: center;
padding: 20px;
background: var(--bg-secondary);
box-shadow: 0 2px 5px rgba(0, 0, 0, 0.1);
z-index: 10;
}
.theme-toggle {
background: var(--bg-tertiary);
border: none;
color: var(--text-primary);
padding: 8px 15px;
border-radius: 20px;
cursor: pointer;
display: flex;
align-items: center;
transition: background 0.3s;
}
.sidebar-toggle {
background: none;
border: none;
color: var(--text-primary);
font-size: 1.5rem;
cursor: pointer;
margin-right: 15px;
}
.controls {
display: flex;
align-items: center;
}
.tehran-time {
margin: 0 15px;
font-size: 0.9rem;
font-weight: 500;
}
.ping-status {
margin: 0 15px;
padding: 5px 10px;
border-radius: 20px;
font-size: 0.9rem;
font-weight: 500;
}
.ping-connected {
background: rgba(76, 175, 80, 0.2);
border: 1px solid #4CAF50;
color: #4CAF50;
}
.ping-disconnected {
background: rgba(244, 67, 54, 0.2);
border: 1px solid #f44336;
color: #f44336;
}
.content-area {
padding: 20px;
flex: 1;
overflow-y: auto;
}
/* Hide scrollbars */
.content-area::-webkit-scrollbar,
.sidebar::-webkit-scrollbar,
.log-container::-webkit-scrollbar {
width: 0;
height: 0;
background: transparent;
}
.card {
background: var(--bg-secondary);
border-radius: 10px;
padding: 20px;
margin-bottom: 20px;
box-shadow: 0 3px 10px rgba(0, 0, 0, 0.1);
}
.card-title {
font-size: 1.2rem;
margin-bottom: 20px;
display: flex;
align-items: center;
}
.card-title i {
margin-right: 10px;
}
.metrics {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
gap: 20px;
}
.metric-card {
background: var(--bg-tertiary);
border-radius: 8px;
padding: 15px;
}
.metric-header {
display: flex;
justify-content: space-between;
margin-bottom: 10px;
}
.metric-title {
font-weight: 500;
}
.metric-value {
font-size: 1.8rem;
font-weight: bold;
margin: 10px 0;
}
.progress-bar {
height: 10px;
background: var(--bg-primary);
border-radius: 5px;
overflow: hidden;
}
.progress {
height: 100%;
background: var(--accent);
border-radius: 5px;
transition: width 0.5s;
}
.specs-grid {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(250px, 1fr));
gap: 15px;
}
.spec-item {
background: var(--bg-tertiary);
padding: 15px;
border-radius: 8px;
}
.spec-label {
color: var(--text-secondary);
font-size: 0.9rem;
margin-bottom: 5px;
}
.spec-value {
font-weight: 500;
}
.log-container {
background: var(--bg-tertiary);
border-radius: 8px;
padding: 15px;
height: 400px;
overflow-y: auto;
font-family: monospace;
font-size: 0.9rem;
white-space: pre-wrap;
}
.log-entry {
margin-bottom: 5px;
line-height: 1.4;
}
.form-grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
gap: 20px;
}
.form-group {
margin-bottom: 15px;
}
.form-label {
display: block;
margin-bottom: 5px;
font-weight: 500;
}
.form-input, .form-select {
width: 100%;
padding: 10px;
background: var(--bg-tertiary);
border: 1px solid var(--bg-primary);
border-radius: 5px;
color: var(--text-primary);
}
.btn {
padding: 10px 20px;
background: var(--accent);
color: white;
border: none;
border-radius: 5px;
cursor: pointer;
font-weight: 500;
transition: background 0.3s;
margin-right: 10px;
}
.btn:hover {
background: #3a6bff;
}
.btn-secondary {
background: var(--bg-tertiary);
}
.btn-secondary:hover {
background: #333342;
}
.hidden {
display: none;
}
.mode-toggle {
display: flex;
align-items: center;
margin-bottom: 15px;
}
.mode-option {
margin-right: 15px;
}
.netinfo-grid {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(350px, 1fr));
gap: 20px;
}
.netinfo-card {
background: var(--bg-tertiary);
border-radius: 8px;
padding: 15px;
margin-bottom: 15px;
}
.netinfo-header {
font-weight: bold;
margin-bottom: 10px;
border-bottom: 1px solid var(--bg-primary);
padding-bottom: 5px;
}
.netinfo-item {
margin-bottom: 8px;
}
.netinfo-label {
font-weight: 500;
color: var(--text-secondary);
}
.status-message {
padding: 10px;
margin-bottom: 15px;
border-radius: 5px;
font-weight: 500;
}
.status-success {
background: rgba(76, 175, 80, 0.2);
border: 1px solid #4CAF50;
color: #4CAF50;
}
.status-error {
background: rgba(244, 67, 54, 0.2);
border: 1px solid #f44336;
color: #f44336;
}
</style>
</head>
<body>
<!-- Sidebar -->
<div class="sidebar" id="sidebar">
<div class="sidebar-header">
<h2>Teknir Panel</h2>
</div>
<div class="content-area">
<!-- Dashboard Page -->
<div id="dashboardPage">
<div class="card">
<div class="card-title">📈 Performance Metrics</div>
<div class="metrics">
<div class="metric-card">
<div class="metric-header">
<div class="metric-title">CPU Usage</div>
<div id="cpuValue">0%</div>
</div>
<div class="progress-bar">
<div class="progress" id="cpuProgress"
style="width: 0%"></div>
</div>
</div>
<div class="metric-card">
<div class="metric-header">
<div class="metric-title">Memory Usage</div>
<div id="memValue">0%</div>
</div>
<div class="progress-bar">
<div class="progress" id="memProgress"
style="width: 0%"></div>
</div>
</div>
<div class="metric-card">
<div class="metric-header">
<div class="metric-title">Network Activity</div>
<div id="netValue">0 KB/s</div>
</div>
<div class="progress-bar">
<div class="progress" id="netProgress"
style="width: 0%"></div>
</div>
</div>
</div>
</div>
<div class="card">
<div class="card-title"> System Specifications</div>
<div class="specs-grid" id="specsGrid">
<!-- Dynamically populated -->
</div>
</div>
</div>
<div class="form-group">
<label class="form-label">Interface Name</label>
<select class="form-select" id="ipInterface">
<!-- Populated by JavaScript -->
</select>
</div>
<div class="mode-toggle">
<div class="mode-option">
<input type="radio" id="ipModeStatic" name="ipMode"
value="static" checked>
<label for="ipModeStatic">Static IP</label>
</div>
<div class="mode-option">
<input type="radio" id="ipModeDHCP" name="ipMode"
value="dhcp">
<label for="ipModeDHCP">DHCP (Automatic)</label>
</div>
</div>
<div id="ipStaticSettings">
<div class="form-grid">
<div class="form-group">
<label class="form-label">IP Address</label>
<input type="text" class="form-input"
id="ipAddress" value="[Link]">
</div>
<div class="form-group">
<label class="form-label">Subnet Mask</label>
<input type="text" class="form-input"
id="subnetMask" value="[Link]">
</div>
<div class="form-group">
<label class="form-label">Default Gateway</label>
<input type="text" class="form-input"
id="defaultGateway" value="[Link]">
</div>
</div>
</div>
<div class="form-group">
<button class="btn" id="saveIPv4">Save Settings</button>
<button class="btn btn-secondary" id="resetIPv4">Reset to
Default</button>
</div>
<div class="form-group">
<label class="form-label">Interface Name</label>
<select class="form-select" id="dnsInterface">
<!-- Populated by JavaScript -->
</select>
</div>
<div class="mode-toggle">
<div class="mode-option">
<input type="radio" id="dnsModeStatic" name="dnsMode"
value="static" checked>
<label for="dnsModeStatic">Static DNS</label>
</div>
<div class="mode-option">
<input type="radio" id="dnsModeDHCP" name="dnsMode"
value="dhcp">
<label for="dnsModeDHCP">DHCP (Automatic)</label>
</div>
</div>
<div id="dnsStaticSettings">
<div class="form-grid">
<div class="form-group">
<label class="form-label">Primary DNS</label>
<input type="text" class="form-input" id="dns1"
value="[Link]">
</div>
<div class="form-group">
<label class="form-label">Secondary DNS</label>
<input type="text" class="form-input" id="dns2"
value="[Link]">
</div>
</div>
</div>
<div class="form-group">
<button class="btn" id="saveDNS">Save Settings</button>
<button class="btn btn-secondary" id="resetDNS">Reset to
Default</button>
</div>
<script>
// DOM Elements
const sidebar = [Link]('sidebar');
const sidebarToggle = [Link]('sidebarToggle');
const themeToggle = [Link]('themeToggle');
const themeIcon = [Link]('themeIcon');
const navItems = [Link]('.nav-item');
const pages = {
dashboard: [Link]('dashboardPage'),
logs: [Link]('logsPage'),
ipv4: [Link]('ipv4Page'),
dns: [Link]('dnsPage'),
datetime: [Link]('datetimePage'),
report: [Link]('reportPage'),
netinfo: [Link]('netinfoPage')
};
const pageTitle = [Link]('pageTitle');
const tehranTime = [Link]('tehranTime');
const pingStatus = [Link]('pingStatus');
// Toggle Sidebar
[Link]('click', () => {
[Link]('collapsed');
});
// Theme Toggle
[Link]('click', () => {
const isDark = [Link]('data-theme') !== 'light';
[Link]('data-theme', isDark ? 'light' : '');
[Link] = isDark ? '☀️' : '';
[Link] = `${[Link]} ${isDark ? 'Light' :
'Dark'} Mode`;
});
// Navigation
[Link](item => {
[Link]('click', (e) => {
[Link]();
const page = [Link]('data-page');
if (pages[page]) {
pages[page].[Link]('hidden');
[Link] = [Link]('.nav-
text').textContent;
// Tehran Time
function updateTehranTime() {
const now = new Date();
const tehranTimeStr = [Link]("en-US", {
timeZone: "Asia/Tehran",
hour: '2-digit',
minute: '2-digit',
second: '2-digit',
hour12: false
});
[Link]('tehranTime').textContent = `Tehran $
{tehranTimeStr}`;
}
// Ping Status
function updatePingStatus() {
const pingStatus = [Link]('pingStatus');
if (!pingStatus) return;
// Performance Metrics
async function updatePerformance() {
try {
const response = await fetch('/system_info');
const data = await [Link]();
// CPU
const cpuPercent = [Link] || 0;
[Link]('cpuValue').textContent = `${cpuPercent}%`;
[Link]('cpuProgress').[Link] = `${cpuPercent}
%`;
// Memory
const memPercent = [Link] || 0;
[Link]('memValue').textContent = `${memPercent}%`;
[Link]('memProgress').[Link] = `${memPercent}
%`;
// Network - show KB/s and use dynamic scaling for progress bar
const netKB = [Link]([Link] || 0);
[Link]('netValue').textContent = `${netKB} KB/s`;
// Update specs
const specsGrid = [Link]('specsGrid');
if (specsGrid) {
[Link] = '';
} catch (error) {
[Link]('Failed to fetch system info:', error);
}
}
// Logs Display
async function updateLogs() {
try {
const response = await fetch('/get_logs');
const data = await [Link]();
const logContainer = [Link]('logContainer');
if (logContainer) {
[Link] = [Link](log =>
`<div class="log-entry">${log}</div>`
).join('');
// Auto-scroll to bottom
[Link] = [Link];
}
} catch (error) {
[Link]('Failed to fetch logs:', error);
}
}
} catch (error) {
[Link]('Failed to load interfaces:', error);
}
}
try {
const response = await fetch('/update_ip_settings', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: [Link]({ interface, mode, ip, mask, gateway })
});
try {
const response = await fetch('/update_dns_settings', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: [Link]({ interface, mode, dns1, dns2 })
});
try {
const response = await fetch('/update_datetime', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: [Link]({ date, time })
});
// Export Logs
[Link]('exportLogs').addEventListener('click', () => {
[Link] = '/export_logs';
});
if (!netinfoContent) return;
[Link] = '';
data.network_info.forEach(iface => {
const card = [Link]('div');
[Link] = 'netinfo-card';
if ([Link]) {
content += `<div class="netinfo-item"><span class="netinfo-
label">MAC Address:</span> ${[Link]}</div>`;
}
[Link] = content;
[Link](card);
});
} catch (error) {
[Link] = `<div class="status-message status-
error">Error loading network info: ${[Link]}</div>`;
}
}
[Link]('ipModeStatic').addEventListener('change', ()
=> {
[Link]('ipStaticSettings').[Link] =
'block';
});
}
if ([Link]('dnsModeDHCP')) {
[Link]('dnsModeDHCP').addEventListener('change', () =>
{
[Link]('dnsStaticSettings').[Link] =
'none';
});
[Link]('dnsModeStatic').addEventListener('change', ()
=> {
[Link]('dnsStaticSettings').[Link] =
'block';
});
}
// Initialize
updatePerformance();
updateLogs();
updateTehranTime();
updatePingStatus();
setInterval(updatePerformance, 1000);
setInterval(updateLogs, 3000);
setInterval(updateTehranTime, 1000);
loadInterfaces();
</script>
</body>
</html>
"""
# =====================
# MAIN APPLICATION
# =====================
if __name__ == "__main__":
# Initialize network monitoring
net_io = psutil.net_io_counters()
prev_bytes_sent = net_io.bytes_sent
prev_bytes_recv = net_io.bytes_recv
prev_time = [Link]()