l / index.html
jojithefoji's picture
add more features - Initial Deployment
c74c327 verified
Raw
History Blame Contribute Delete
42.7 kB
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Network Packet Analyzer</title>
<script src="https://cdn.tailwindcss.com"></script>
<script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">
<style>
/* Hacker Theme */
.hacker-theme {
background-color: #000 !important;
color: #0f0 !important;
background-image:
linear-gradient(rgba(0, 255, 0, 0.05) 1px, transparent 1px),
linear-gradient(90deg, rgba(0, 255, 0, 0.05) 1px, transparent 1px);
background-size: 20px 20px;
text-shadow: 0 0 5px #0f0;
}
.hacker-theme .bg-white {
background-color: #000 !important;
color: #0f0 !important;
border: 1px solid #0a5c0a !important;
box-shadow: 0 0 10px #0f0;
}
.hacker-theme .text-gray-800,
.hacker-theme .text-gray-700,
.hacker-theme .text-gray-600,
.hacker-theme .text-gray-500 {
color: #0f0 !important;
text-shadow: 0 0 3px #0f0;
}
.hacker-theme .bg-indigo-100 {
background-color: #0a2e0a !important;
box-shadow: 0 0 5px #0f0;
}
.hacker-theme .text-indigo-600 {
color: #0f0 !important;
}
.hacker-theme .bg-indigo-600 {
background-color: #0a5c0a !important;
box-shadow: 0 0 10px #0f0;
}
.hacker-theme .hover\:bg-indigo-700:hover {
background-color: #0a7e0a !important;
box-shadow: 0 0 15px #0f0;
}
.hacker-theme .font-mono {
font-family: 'Courier New', monospace !important;
}
.hacker-theme .packet-row:hover {
background-color: #0a2e0a !important;
box-shadow: 0 0 5px #0f0 inset;
}
.hacker-theme ::-webkit-scrollbar-thumb {
background: #0a5c0a !important;
box-shadow: 0 0 5px #0f0;
}
.hacker-theme ::-webkit-scrollbar-thumb:hover {
background: #0a7e0a !important;
box-shadow: 0 0 8px #0f0;
}
.hacker-theme .file-upload {
border: 2px dashed #0a5c0a !important;
}
.hacker-theme .file-upload:hover {
border-color: #0f0 !important;
box-shadow: 0 0 10px #0f0;
}
.hacker-theme .file-upload.dragover {
background-color: #0a2e0a !important;
border-color: #0f0 !important;
}
.hacker-theme .protocol-tag {
box-shadow: 0 0 5px #0f0;
border: 1px solid #0a5c0a !important;
}
.hacker-theme #packet-search {
background-color: #000 !important;
border: 1px solid #0a5c0a !important;
color: #0f0 !important;
}
.file-upload {
border: 2px dashed #cbd5e0;
transition: all 0.3s ease;
}
.file-upload:hover {
border-color: #4f46e5;
}
.file-upload.dragover {
background-color: #f0f9ff;
border-color: #4f46e5;
}
.protocol-tag {
display: inline-flex;
align-items: center;
padding: 0.25rem 0.5rem;
border-radius: 9999px;
font-size: 0.75rem;
font-weight: 500;
}
.packet-details {
max-height: 300px;
overflow-y: auto;
}
.packet-row:hover {
background-color: #f8fafc;
}
/* Custom scrollbar */
::-webkit-scrollbar {
width: 8px;
}
::-webkit-scrollbar-track {
background: #f1f1f1;
}
::-webkit-scrollbar-thumb {
background: #c7d2fe;
border-radius: 4px;
}
::-webkit-scrollbar-thumb:hover {
background: #a5b4fc;
}
</style>
</head>
<body class="bg-gray-50 min-h-screen">
<div class="container mx-auto px-4 py-8">
<!-- Header -->
<header class="mb-8">
<div class="flex items-center justify-between">
<div>
<h1 class="text-3xl font-bold text-indigo-800">Network Packet Analyzer</h1>
<p class="text-gray-600">Analyze PCAP, CSV, and text files containing network packet captures</p>
</div>
<div class="flex items-center space-x-4">
<button id="theme-toggle" class="p-2 rounded-full bg-indigo-100 text-indigo-600 hover:bg-indigo-200 transition" title="Toggle Theme">
<i class="fas fa-moon"></i>
</button>
<button id="help-btn" class="p-2 rounded-full bg-indigo-100 text-indigo-600 hover:bg-indigo-200 transition">
<i class="fas fa-question-circle"></i>
</button>
<button id="settings-btn" class="p-2 rounded-full bg-indigo-100 text-indigo-600 hover:bg-indigo-200 transition">
<i class="fas fa-cog"></i>
</button>
</div>
</div>
</header>
<!-- Main Content -->
<div class="grid grid-cols-1 lg:grid-cols-3 gap-6">
<!-- File Upload Section -->
<div class="lg:col-span-1 bg-white rounded-xl shadow-md p-6">
<h2 class="text-xl font-semibold text-gray-800 mb-4">Upload Capture File</h2>
<div id="file-upload" class="file-upload rounded-lg p-8 text-center cursor-pointer mb-4">
<div class="flex flex-col items-center justify-center space-y-2">
<i class="fas fa-cloud-upload-alt text-4xl text-indigo-500"></i>
<p class="text-gray-600">Drag & drop your file here</p>
<p class="text-sm text-gray-500">or</p>
<button id="browse-btn" class="px-4 py-2 bg-indigo-600 text-white rounded-md hover:bg-indigo-700 transition">
Browse Files
</button>
</div>
<input type="file" id="file-input" class="hidden" accept=".pcap,.csv,.txt">
</div>
<div class="mt-4">
<h3 class="font-medium text-gray-700 mb-2">Supported Formats</h3>
<div class="flex flex-wrap gap-2">
<span class="protocol-tag bg-blue-100 text-blue-800">
<i class="fas fa-file-alt mr-1"></i> PCAP
</span>
<span class="protocol-tag bg-green-100 text-green-800">
<i class="fas fa-file-csv mr-1"></i> CSV
</span>
<span class="protocol-tag bg-purple-100 text-purple-800">
<i class="fas fa-file-alt mr-1"></i> TXT
</span>
</div>
</div>
<div class="mt-6">
<h3 class="font-medium text-gray-700 mb-2">Analysis Options</h3>
<div class="space-y-2">
<label class="flex items-center space-x-2">
<input type="checkbox" id="deep-analysis" class="rounded text-indigo-600">
<span>Deep Packet Inspection</span>
</label>
<label class="flex items-center space-x-2">
<input type="checkbox" id="geo-lookup" class="rounded text-indigo-600" checked>
<span>Geo IP Lookup</span>
</label>
<label class="flex items-center space-x-2">
<input type="checkbox" id="threat-detection" class="rounded text-indigo-600" checked>
<span>Threat Detection</span>
</label>
</div>
</div>
<button id="analyze-btn" class="w-full mt-6 py-2 bg-indigo-600 text-white rounded-md hover:bg-indigo-700 transition flex items-center justify-center space-x-2 disabled:opacity-50" disabled>
<i class="fas fa-search"></i>
<span>Analyze</span>
</button>
</div>
<!-- Analysis Results -->
<div class="lg:col-span-2 space-y-6">
<!-- Summary Cards -->
<div class="grid grid-cols-1 md:grid-cols-3 gap-4">
<div class="bg-white rounded-xl shadow-md p-4">
<div class="flex items-center justify-between">
<div>
<p class="text-sm text-gray-500">Total Packets</p>
<h3 id="total-packets" class="text-2xl font-bold text-gray-800">0</h3>
</div>
<div class="p-3 rounded-full bg-indigo-100 text-indigo-600">
<i class="fas fa-network-wired"></i>
</div>
</div>
</div>
<div class="bg-white rounded-xl shadow-md p-4">
<div class="flex items-center justify-between">
<div>
<p class="text-sm text-gray-500">Protocols</p>
<h3 id="protocol-count" class="text-2xl font-bold text-gray-800">0</h3>
</div>
<div class="p-3 rounded-full bg-green-100 text-green-600">
<i class="fas fa-project-diagram"></i>
</div>
</div>
</div>
<div class="bg-white rounded-xl shadow-md p-4">
<div class="flex items-center justify-between">
<div>
<p class="text-sm text-gray-500">Threats</p>
<h3 id="threat-count" class="text-2xl font-bold text-gray-800">0</h3>
</div>
<div class="p-3 rounded-full bg-red-100 text-red-600">
<i class="fas fa-shield-alt"></i>
</div>
</div>
</div>
</div>
<!-- Protocol Distribution Chart -->
<div class="bg-white rounded-xl shadow-md p-6">
<div class="flex items-center justify-between mb-4">
<h2 class="text-xl font-semibold text-gray-800">Protocol Distribution</h2>
<div class="flex space-x-2">
<button id="chart-toggle" class="px-3 py-1 text-sm bg-gray-100 rounded-md hover:bg-gray-200 transition">
<i class="fas fa-chart-pie mr-1"></i> Pie
</button>
</div>
</div>
<div class="h-64">
<canvas id="protocol-chart"></canvas>
</div>
</div>
<!-- Packet List -->
<div class="bg-white rounded-xl shadow-md p-6">
<div class="flex items-center justify-between mb-4">
<h2 class="text-xl font-semibold text-gray-800">Packet Details</h2>
<div class="relative">
<input type="text" id="packet-search" placeholder="Search packets..." class="pl-8 pr-4 py-2 border rounded-md text-sm focus:outline-none focus:ring-2 focus:ring-green-500 font-mono">
<i class="fas fa-search absolute left-3 top-3 text-gray-400"></i>
</div>
</div>
<div class="overflow-x-auto">
<table class="min-w-full divide-y divide-gray-200">
<thead class="bg-gray-50">
<tr>
<th scope="col" class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">No.</th>
<th scope="col" class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Time</th>
<th scope="col" class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Source</th>
<th scope="col" class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Destination</th>
<th scope="col" class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Protocol</th>
<th scope="col" class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Length</th>
<th scope="col" class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Info</th>
</tr>
</thead>
<tbody id="packet-table-body" class="bg-white divide-y divide-gray-200 packet-details">
<tr>
<td colspan="7" class="px-6 py-4 text-center text-gray-500">Upload a file to analyze network packets</td>
</tr>
</tbody>
</table>
</div>
<div class="mt-4 flex items-center justify-between">
<div class="text-sm text-gray-500">
Showing <span id="packet-start">0</span> to <span id="packet-end">0</span> of <span id="packet-total">0</span> packets
</div>
<div class="flex space-x-2">
<button id="prev-page" class="px-3 py-1 border rounded-md text-sm disabled:opacity-50" disabled>
<i class="fas fa-chevron-left"></i>
</button>
<button id="next-page" class="px-3 py-1 border rounded-md text-sm disabled:opacity-50" disabled>
<i class="fas fa-chevron-right"></i>
</button>
</div>
</div>
</div>
<!-- Threat Analysis -->
<div id="threat-analysis" class="bg-white rounded-xl shadow-md p-6 hidden">
<h2 class="text-xl font-semibold text-gray-800 mb-4">Threat Analysis</h2>
<div id="threat-list" class="space-y-3">
<!-- Threats will be populated here -->
</div>
</div>
</div>
</div>
</div>
<!-- Help Modal -->
<div id="help-modal" class="fixed inset-0 bg-black bg-opacity-50 flex items-center justify-center z-50 hidden">
<div class="bg-white rounded-xl shadow-xl max-w-2xl w-full max-h-[90vh] overflow-y-auto">
<div class="p-6">
<div class="flex items-center justify-between mb-4">
<h3 class="text-xl font-bold text-gray-800">Help & Documentation</h3>
<button id="close-help" class="text-gray-500 hover:text-gray-700">
<i class="fas fa-times"></i>
</button>
</div>
<div class="space-y-4">
<div>
<h4 class="font-medium text-gray-800 mb-2">Supported File Formats</h4>
<ul class="list-disc pl-5 space-y-1 text-gray-600">
<li><strong>PCAP</strong> - Packet capture files from tools like Wireshark or tcpdump</li>
<li><strong>CSV</strong> - Comma-separated values with packet data (timestamp, source, destination, protocol, etc.)</li>
<li><strong>TXT</strong> - Plain text files with packet information in a structured format</li>
</ul>
</div>
<div>
<h4 class="font-medium text-gray-800 mb-2">Analysis Features</h4>
<ul class="list-disc pl-5 space-y-1 text-gray-600">
<li><strong>Protocol Distribution</strong> - Visual breakdown of different network protocols in your capture</li>
<li><strong>Packet Details</strong> - Comprehensive view of individual packets with filtering capabilities</li>
<li><strong>Threat Detection</strong> - Identification of potential security threats in the network traffic</li>
<li><strong>Geo IP Lookup</strong> - Geographic location mapping of IP addresses (when enabled)</li>
</ul>
</div>
<div>
<h4 class="font-medium text-gray-800 mb-2">Usage Tips</h4>
<ul class="list-disc pl-5 space-y-1 text-gray-600">
<li>For best results with PCAP files, ensure they're not too large (&lt;50MB recommended)</li>
<li>Use the search function to quickly find specific packets by IP, protocol, or other criteria</li>
<li>Enable "Deep Packet Inspection" for more detailed analysis of packet contents</li>
<li>Click on any packet row to view more detailed information</li>
</ul>
</div>
</div>
</div>
</div>
</div>
<!-- Packet Detail Modal -->
<div id="packet-modal" class="fixed inset-0 bg-black bg-opacity-50 flex items-center justify-center z-50 hidden">
<div class="bg-white rounded-xl shadow-xl max-w-4xl w-full max-h-[90vh] overflow-y-auto">
<div class="p-6">
<div class="flex items-center justify-between mb-4">
<h3 class="text-xl font-bold text-gray-800">Packet Details</h3>
<button id="close-packet" class="text-gray-500 hover:text-gray-700">
<i class="fas fa-times"></i>
</button>
</div>
<div class="mb-6">
<div class="grid grid-cols-1 md:grid-cols-3 gap-4 mb-4">
<div class="bg-gray-50 p-3 rounded-lg">
<p class="text-sm text-gray-500">Source</p>
<p id="modal-source" class="font-mono">192.168.1.100:54321</p>
</div>
<div class="bg-gray-50 p-3 rounded-lg">
<p class="text-sm text-gray-500">Destination</p>
<p id="modal-dest" class="font-mono">8.8.8.8:53</p>
</div>
<div class="bg-gray-50 p-3 rounded-lg">
<p class="text-sm text-gray-500">Protocol</p>
<p id="modal-protocol" class="font-mono">UDP</p>
</div>
</div>
<div class="grid grid-cols-1 md:grid-cols-2 gap-4 mb-4">
<div class="bg-gray-50 p-3 rounded-lg">
<p class="text-sm text-gray-500">Timestamp</p>
<p id="modal-time" class="font-mono">2023-07-15 14:32:45.123456</p>
</div>
<div class="bg-gray-50 p-3 rounded-lg">
<p class="text-sm text-gray-500">Length</p>
<p id="modal-length" class="font-mono">78 bytes</p>
</div>
</div>
</div>
<div>
<h4 class="font-medium text-gray-800 mb-2">Packet Contents</h4>
<div class="bg-gray-900 text-green-400 p-4 rounded-lg overflow-x-auto">
<pre id="modal-contents" class="font-mono text-sm whitespace-pre-wrap"></pre>
</div>
</div>
</div>
</div>
</div>
<script>
// DOM Elements
const themeToggle = document.getElementById('theme-toggle');
const fileUpload = document.getElementById('file-upload');
const fileInput = document.getElementById('file-input');
const browseBtn = document.getElementById('browse-btn');
const analyzeBtn = document.getElementById('analyze-btn');
const helpBtn = document.getElementById('help-btn');
const helpModal = document.getElementById('help-modal');
const closeHelp = document.getElementById('close-help');
const packetModal = document.getElementById('packet-modal');
const closePacket = document.getElementById('close-packet');
const chartToggle = document.getElementById('chart-toggle');
const packetSearch = document.getElementById('packet-search');
const prevPage = document.getElementById('prev-page');
const nextPage = document.getElementById('next-page');
const threatAnalysis = document.getElementById('threat-analysis');
// State
let currentFile = null;
let packets = [];
let filteredPackets = [];
let currentPage = 1;
const packetsPerPage = 10;
let chartType = 'pie';
let protocolChart = null;
// Event Listeners
themeToggle.addEventListener('click', toggleTheme);
browseBtn.addEventListener('click', () => fileInput.click());
fileInput.addEventListener('change', handleFileSelect);
fileUpload.addEventListener('dragover', (e) => {
e.preventDefault();
fileUpload.classList.add('dragover');
});
fileUpload.addEventListener('dragleave', () => {
fileUpload.classList.remove('dragover');
});
fileUpload.addEventListener('drop', (e) => {
e.preventDefault();
fileUpload.classList.remove('dragover');
if (e.dataTransfer.files.length) {
fileInput.files = e.dataTransfer.files;
handleFileSelect({ target: fileInput });
}
});
analyzeBtn.addEventListener('click', analyzeFile);
helpBtn.addEventListener('click', () => helpModal.classList.remove('hidden'));
closeHelp.addEventListener('click', () => helpModal.classList.add('hidden'));
closePacket.addEventListener('click', () => packetModal.classList.add('hidden'));
chartToggle.addEventListener('click', toggleChartType);
packetSearch.addEventListener('input', filterPackets);
prevPage.addEventListener('click', () => {
if (currentPage > 1) {
currentPage--;
renderPacketTable();
}
});
nextPage.addEventListener('click', () => {
if (currentPage < Math.ceil(filteredPackets.length / packetsPerPage)) {
currentPage++;
renderPacketTable();
}
});
// Functions
function toggleTheme() {
document.body.classList.toggle('hacker-theme');
const icon = themeToggle.querySelector('i');
if (document.body.classList.contains('hacker-theme')) {
icon.classList.remove('fa-moon');
icon.classList.add('fa-sun');
themeToggle.title = "Switch to Normal Theme";
} else {
icon.classList.remove('fa-sun');
icon.classList.add('fa-moon');
themeToggle.title = "Switch to Hacker Theme";
}
}
function handleFileSelect(event) {
const file = event.target.files[0];
if (!file) return;
currentFile = file;
analyzeBtn.disabled = false;
// Update UI to show selected file
const fileUpload = document.getElementById('file-upload');
fileUpload.innerHTML = `
<div class="flex flex-col items-center justify-center space-y-2">
<i class="fas fa-file-alt text-4xl text-indigo-500"></i>
<p class="font-medium text-gray-800">${file.name}</p>
<p class="text-sm text-gray-500">${formatFileSize(file.size)}</p>
<button id="change-file" class="px-3 py-1 text-sm text-indigo-600 hover:text-indigo-800">
Change file
</button>
</div>
`;
document.getElementById('change-file').addEventListener('click', () => fileInput.click());
}
function formatFileSize(bytes) {
if (bytes === 0) return '0 Bytes';
const k = 1024;
const sizes = ['Bytes', 'KB', 'MB', 'GB'];
const i = Math.floor(Math.log(bytes) / Math.log(k));
return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + ' ' + sizes[i];
}
function analyzeFile() {
if (!currentFile) return;
analyzeBtn.innerHTML = '<i class="fas fa-spinner fa-spin"></i> Analyzing...';
analyzeBtn.disabled = true;
// Simulate analysis (in a real app, you'd process the file here)
setTimeout(() => {
// Generate mock data for demonstration
packets = generateMockPackets();
filteredPackets = [...packets];
// Update UI with results
updateSummaryCards();
renderProtocolChart();
renderPacketTable();
// Check for threats
checkForThreats();
analyzeBtn.innerHTML = '<i class="fas fa-search"></i> Analyze';
analyzeBtn.disabled = false;
}, 1500);
}
function generateMockPackets() {
const protocols = ['TCP', 'UDP', 'HTTP', 'HTTPS', 'DNS', 'ICMP', 'ARP'];
const mockPackets = [];
for (let i = 0; i < 50; i++) {
const sourceIp = `192.168.1.${Math.floor(Math.random() * 254) + 1}`;
const destIp = `${Math.floor(Math.random() * 223) + 1}.${Math.floor(Math.random() * 255)}.${Math.floor(Math.random() * 255)}.${Math.floor(Math.random() * 254) + 1}`;
const sourcePort = Math.floor(Math.random() * 65535);
const destPort = Math.floor(Math.random() * 65535);
const protocol = protocols[Math.floor(Math.random() * protocols.length)];
const length = Math.floor(Math.random() * 1500) + 50;
const timestamp = new Date(Date.now() - Math.floor(Math.random() * 3600000)).toISOString();
mockPackets.push({
id: i + 1,
time: timestamp,
source: `${sourceIp}:${sourcePort}`,
destination: `${destIp}:${destPort}`,
protocol: protocol,
length: length,
info: generatePacketInfo(protocol, sourceIp, destIp),
contents: generatePacketContents(protocol, length)
});
}
// Add some potential threats
mockPackets.push({
id: mockPackets.length + 1,
time: new Date().toISOString(),
source: `192.168.1.100:54321`,
destination: `45.33.12.42:4444`,
protocol: 'TCP',
length: 1024,
info: 'Potential reverse shell detected',
contents: 'SYN packet to known malicious IP with suspicious port',
isThreat: true,
threatType: 'Reverse Shell'
});
mockPackets.push({
id: mockPackets.length + 1,
time: new Date().toISOString(),
source: `10.0.0.5:1234`,
destination: `192.168.1.1:80`,
protocol: 'HTTP',
length: 2048,
info: 'Possible SQL injection attempt',
contents: 'GET /login.php?user=admin\'-- HTTP/1.1',
isThreat: true,
threatType: 'SQL Injection'
});
return mockPackets;
}
function generatePacketInfo(protocol, sourceIp, destIp) {
const actions = {
'TCP': ['SYN', 'ACK', 'FIN', 'RST', 'PSH'],
'UDP': ['DNS query', 'NTP request', 'DHCP', 'SNMP'],
'HTTP': ['GET', 'POST', 'PUT', 'DELETE'],
'HTTPS': ['TLS Handshake', 'Encrypted traffic'],
'DNS': ['Query', 'Response'],
'ICMP': ['Echo request', 'Echo reply', 'Destination unreachable'],
'ARP': ['Request', 'Reply']
};
const action = actions[protocol][Math.floor(Math.random() * actions[protocol].length)];
return `${action} ${protocol === 'DNS' ? 'for' : 'to'} ${destIp}`;
}
function generatePacketContents(protocol, length) {
const contents = {
'TCP': `4500 ${length} 1a2b 4000 4006 a1b2 ${generateHex(length - 20)}`,
'UDP': `${generateHex(8)} ${generateHex(length - 8)}`,
'HTTP': `GET /index.html HTTP/1.1\r\nHost: example.com\r\nUser-Agent: MockBrowser/1.0\r\nAccept: */*\r\n\r\n`,
'HTTPS': `16 03 01 ${generateHex(length - 5, 2)} 01 ${generateHex(length - 6, 2)}`,
'DNS': `${generateHex(12)} ${generateHex(length - 12)}`,
'ICMP': `08 00 ${generateHex(length - 2)}`,
'ARP': `0001 0800 06 04 0001 ${generateHex(length - 8)}`
};
return contents[protocol] || `Raw packet data (${length} bytes)`;
}
function generateHex(length, bytesPerGroup = 4) {
const hexChars = '0123456789abcdef';
let result = '';
const groups = Math.ceil(length / bytesPerGroup);
for (let i = 0; i < groups; i++) {
for (let j = 0; j < bytesPerGroup; j++) {
if (i * bytesPerGroup + j < length) {
result += hexChars[Math.floor(Math.random() * 16)];
result += hexChars[Math.floor(Math.random() * 16)];
if (j < bytesPerGroup - 1) result += ' ';
}
}
if (i < groups - 1) result += ' ';
}
return result;
}
function updateSummaryCards() {
document.getElementById('total-packets').textContent = packets.length;
// Count unique protocols
const protocolSet = new Set(packets.map(p => p.protocol));
document.getElementById('protocol-count').textContent = protocolSet.size;
// Count threats
const threatCount = packets.filter(p => p.isThreat).length;
document.getElementById('threat-count').textContent = threatCount;
}
function renderProtocolChart() {
const ctx = document.getElementById('protocol-chart').getContext('2d');
// Count packets by protocol
const protocolCounts = {};
packets.forEach(packet => {
protocolCounts[packet.protocol] = (protocolCounts[packet.protocol] || 0) + 1;
});
const protocols = Object.keys(protocolCounts);
const counts = Object.values(protocolCounts);
// Colors for different protocols
const backgroundColors = [
'rgba(255, 99, 132, 0.7)',
'rgba(54, 162, 235, 0.7)',
'rgba(255, 206, 86, 0.7)',
'rgba(75, 192, 192, 0.7)',
'rgba(153, 102, 255, 0.7)',
'rgba(255, 159, 64, 0.7)',
'rgba(199, 199, 199, 0.7)'
];
if (protocolChart) {
protocolChart.destroy();
}
if (chartType === 'pie') {
protocolChart = new Chart(ctx, {
type: 'pie',
data: {
labels: protocols,
datasets: [{
data: counts,
backgroundColor: backgroundColors,
borderWidth: 1
}]
},
options: {
responsive: true,
maintainAspectRatio: false,
plugins: {
legend: {
position: 'right'
}
}
}
});
} else {
protocolChart = new Chart(ctx, {
type: 'bar',
data: {
labels: protocols,
datasets: [{
label: 'Packet Count',
data: counts,
backgroundColor: 'rgba(79, 70, 229, 0.7)',
borderColor: 'rgba(79, 70, 229, 1)',
borderWidth: 1
}]
},
options: {
responsive: true,
maintainAspectRatio: false,
scales: {
y: {
beginAtZero: true
}
}
}
});
}
}
function toggleChartType() {
chartType = chartType === 'pie' ? 'bar' : 'pie';
chartToggle.innerHTML = chartType === 'pie'
? '<i class="fas fa-chart-pie mr-1"></i> Pie'
: '<i class="fas fa-chart-bar mr-1"></i> Bar';
renderProtocolChart();
}
function renderPacketTable() {
const tableBody = document.getElementById('packet-table-body');
tableBody.innerHTML = '';
if (filteredPackets.length === 0) {
tableBody.innerHTML = `
<tr>
<td colspan="7" class="px-6 py-4 text-center text-gray-500">No packets match your search criteria</td>
</tr>
`;
return;
}
const startIdx = (currentPage - 1) * packetsPerPage;
const endIdx = Math.min(startIdx + packetsPerPage, filteredPackets.length);
const pagePackets = filteredPackets.slice(startIdx, endIdx);
pagePackets.forEach(packet => {
const row = document.createElement('tr');
row.className = 'packet-row hover:bg-gray-50 cursor-pointer';
row.innerHTML = `
<td class="px-6 py-4 whitespace-nowrap text-sm font-medium text-gray-900">${packet.id}</td>
<td class="px-6 py-4 whitespace-nowrap text-sm text-gray-500">${formatTime(packet.time)}</td>
<td class="px-6 py-4 whitespace-nowrap text-sm text-gray-500 font-mono">${packet.source}</td>
<td class="px-6 py-4 whitespace-nowrap text-sm text-gray-500 font-mono">${packet.destination}</td>
<td class="px-6 py-4 whitespace-nowrap text-sm">
<span class="px-2 inline-flex text-xs leading-5 font-semibold rounded-full ${
getProtocolColorClass(packet.protocol)
}">
${packet.protocol}
</span>
</td>
<td class="px-6 py-4 whitespace-nowrap text-sm text-gray-500">${packet.length} B</td>
<td class="px-6 py-4 text-sm text-gray-500">${packet.info}</td>
`;
row.addEventListener('click', () => showPacketDetails(packet));
tableBody.appendChild(row);
});
// Update pagination info
document.getElementById('packet-start').textContent = startIdx + 1;
document.getElementById('packet-end').textContent = endIdx;
document.getElementById('packet-total').textContent = filteredPackets.length;
// Update pagination buttons
prevPage.disabled = currentPage === 1;
nextPage.disabled = currentPage === Math.ceil(filteredPackets.length / packetsPerPage);
}
function getProtocolColorClass(protocol) {
const colors = {
'TCP': 'bg-blue-100 text-blue-800',
'UDP': 'bg-green-100 text-green-800',
'HTTP': 'bg-yellow-100 text-yellow-800',
'HTTPS': 'bg-purple-100 text-purple-800',
'DNS': 'bg-indigo-100 text-indigo-800',
'ICMP': 'bg-red-100 text-red-800',
'ARP': 'bg-gray-100 text-gray-800'
};
return colors[protocol] || 'bg-gray-100 text-gray-800';
}
function formatTime(isoString) {
const date = new Date(isoString);
return date.toLocaleTimeString();
}
function filterPackets() {
const searchTerm = packetSearch.value.toLowerCase();
if (!searchTerm) {
filteredPackets = [...packets];
} else {
filteredPackets = packets.filter(packet =>
packet.source.toLowerCase().includes(searchTerm) ||
packet.destination.toLowerCase().includes(searchTerm) ||
packet.protocol.toLowerCase().includes(searchTerm) ||
packet.info.toLowerCase().includes(searchTerm)
);
}
currentPage = 1;
renderPacketTable();
}
function showPacketDetails(packet) {
document.getElementById('modal-source').textContent = packet.source;
document.getElementById('modal-dest').textContent = packet.destination;
document.getElementById('modal-protocol').textContent = packet.protocol;
document.getElementById('modal-time').textContent = new Date(packet.time).toLocaleString();
document.getElementById('modal-length').textContent = `${packet.length} bytes`;
document.getElementById('modal-contents').textContent = packet.contents;
packetModal.classList.remove('hidden');
}
function checkForThreats() {
const threatList = document.getElementById('threat-list');
threatList.innerHTML = '';
const threats = packets.filter(p => p.isThreat);
if (threats.length === 0) {
threatList.innerHTML = '<p class="text-gray-500">No threats detected in the network traffic.</p>';
} else {
threats.forEach(threat => {
const threatItem = document.createElement('div');
threatItem.className = 'p-3 rounded-lg bg-red-50 border border-red-200';
threatItem.innerHTML = `
<div class="flex items-start justify-between">
<div>
<h4 class="font-medium text-red-800">${threat.threatType || 'Suspicious Activity'}</h4>
<p class="text-sm text-gray-600">${threat.info}</p>
<div class="mt-2 flex space-x-2">
<span class="text-xs px-2 py-1 bg-red-100 text-red-800 rounded">${threat.protocol}</span>
<span class="text-xs px-2 py-1 bg-gray-100 text-gray-800 rounded">Packet #${threat.id}</span>
</div>
</div>
<button class="text-red-600 hover:text-red-800">
<i class="fas fa-exclamation-triangle"></i>
</button>
</div>
`;
threatList.appendChild(threatItem);
});
}
threatAnalysis.classList.remove('hidden');
}
</script>
<p style="border-radius: 8px; text-align: center; font-size: 12px; color: #fff; margin-top: 16px;position: fixed; left: 8px; bottom: 8px; z-index: 10; background: rgba(0, 0, 0, 0.8); padding: 4px 8px;">Made with <img src="https://enzostvs-deepsite.hf.space/logo.svg" alt="DeepSite Logo" style="width: 16px; height: 16px; vertical-align: middle;display:inline-block;margin-right:3px;filter:brightness(0) invert(1);"><a href="https://enzostvs-deepsite.hf.space" style="color: #fff;text-decoration: underline;" target="_blank" >DeepSite</a> - 🧬 <a href="https://enzostvs-deepsite.hf.space?remix=jojithefoji/l" style="color: #fff;text-decoration: underline;" target="_blank" >Remix</a></p></body>
</html>