Files
mNetVisualizer/frontend/src/utils.js
T

88 lines
3.0 KiB
JavaScript

export function formatBytes(bytes) {
if (!bytes || bytes === 0) return '0 B';
const units = ['B', 'KB', 'MB', 'GB', 'TB'];
const i = Math.floor(Math.log(bytes) / Math.log(1024));
return `${(bytes / Math.pow(1024, i)).toFixed(1)} ${units[i]}`;
}
export function formatUptime(seconds) {
if (!seconds) return '—';
const h = Math.floor(seconds / 3600);
const m = Math.floor((seconds % 3600) / 60);
if (h > 0) return `${h}h ${m}m`;
return `${m}m`;
}
export function protoName(n) {
const PROTOS = { 1:'ICMP', 2:'IGMP', 6:'TCP', 17:'UDP', 41:'IPv6', 47:'GRE', 50:'ESP', 51:'AH', 58:'ICMPv6', 89:'OSPF', 132:'SCTP' };
return PROTOS[n] || (n ? `IP/${n}` : '—');
}
export function protoColor(n) {
const COLORS = { 6:'#38bdf8', 17:'#a78bfa', 1:'#fbbf24', 58:'#fb923c' };
return COLORS[n] || '#64748b';
}
export function serviceLabel(port, proto) {
const TCP = {
20:'FTP-data', 21:'FTP', 22:'SSH', 23:'Telnet', 25:'SMTP', 53:'DNS',
80:'HTTP', 110:'POP3', 143:'IMAP', 443:'HTTPS', 465:'SMTPS', 587:'SMTP',
993:'IMAPS', 995:'POP3S', 1194:'OpenVPN', 1883:'MQTT', 3306:'MySQL',
3389:'RDP', 5900:'VNC', 6443:'K8s API', 8080:'HTTP-alt', 8443:'HTTPS-alt',
8883:'MQTT-TLS', 9000:'Custom', 51820:'WireGuard',
};
const UDP = {
53:'DNS', 67:'DHCP', 68:'DHCP', 123:'NTP', 161:'SNMP', 500:'IKE',
514:'Syslog', 1194:'OpenVPN', 4500:'IPsec', 5353:'mDNS', 51820:'WireGuard',
};
if (proto === 6 && TCP[port]) return TCP[port];
if (proto === 17 && UDP[port]) return UDP[port];
if (TCP[port]) return TCP[port];
return port ? `port ${port}` : '';
}
export const DEVICE_GROUPS = ['IoT', 'Servers', 'Mobile', 'Network', 'Desktop', 'Media'];
export const GROUP_COLORS = {
IoT:'#f59e0b', Servers:'#3b82f6', Mobile:'#ec4899',
Network:'#10b981', Desktop:'#8b5cf6', Media:'#f97316',
};
export function timeAgo(ms) {
if (!ms) return '—';
const sec = Math.floor((Date.now() - ms) / 1000);
if (sec < 10) return 'just now';
if (sec < 60) return `${sec}s ago`;
const min = Math.floor(sec / 60);
if (min < 60) return `${min}m ago`;
return `${Math.floor(min / 60)}h ago`;
}
export function deviceIcon(device) {
if (device.is_wired) return '🖥';
const oui = (device.oui || '').toLowerCase();
if (oui.includes('apple')) return '🍎';
if (oui.includes('samsung')) return '📱';
if (oui.includes('sony')) return '🎮';
if (oui.includes('lg')) return '📺';
if (oui.includes('intel')) return '💻';
if (oui.includes('raspberry')) return '🍓';
return '📡';
}
// Map app/category codes to readable names
const APP_NAMES = {
0: 'Other', 1: 'Instant messaging', 2: 'P2P', 3: 'Thumbnails',
4: 'Streaming media', 5: 'VoIP', 6: 'Gaming', 7: 'Remote access',
8: 'News feeds', 9: 'Streaming video', 10: 'Email', 11: 'News',
12: 'Downloads', 13: 'Business apps', 14: 'Social networking',
15: 'Web browsing', 255: 'Unknown',
};
export function appName(cat) {
if (typeof cat === 'number') return APP_NAMES[cat] || `Cat ${cat}`;
return cat || 'Unknown';
}
export const OUT_COLOR = '#38bdf8';
export const IN_COLOR = '#f472b6';