NAT/PAT Table Visualizer

function calcPat() { const hosts = parseInt(document.getElementById('insideHosts').value); const ips = parseInt(document.getElementById('outsideIps').value); const sessPerHost = parseInt(document.getElementById('sessPerHost').value); const proto = document.getElementById('natProto').value; const section = document.getElementById('patResult'); const content = document.getElementById('patResultContent'); section.style.display = 'block'; if (isNaN(hosts) || isNaN(ips) || isNaN(sessPerHost) || hosts < 1 || ips < 1 || sessPerHost < 1) { content.innerHTML = '
Invalid input. All fields must be positive numbers.
'; return; } const poolSize = proto === 'both' ? PAT_PORTS * 2 * ips : PAT_PORTS * ips; const totalSessions = hosts * sessPerHost; const utilPct = Math.min((totalSessions / poolSize) * 100, 100); const isExhausted = totalSessions > poolSize; const overflow = isExhausted ? totalSessions - poolSize : 0; const barColor = utilPct > 90 ? '#dc3545' : utilPct > 70 ? '#f7971e' : '#4CAF50'; content.innerHTML = `
${poolSize.toLocaleString()}
Total PAT slots (pool)
${totalSessions.toLocaleString()}
Sessions required
${utilPct.toFixed(1)}%
Pool utilization
${isExhausted ? `
${overflow.toLocaleString()}
Sessions DROPPED (overflow)
` : ''}
${utilPct.toFixed(1)}%
${isExhausted ? `Port exhaustion! Need ${Math.ceil(totalSessions / PAT_PORTS)} outside IPs to support current session load.` : `Sufficient capacity. ${(poolSize - totalSessions).toLocaleString()} PAT slots remaining.`}
Formula: ${ips} IP(s) × ${proto === 'both' ? '2 × ' : ''}64,512 ports = ${poolSize.toLocaleString()} slots
`; } function addNatEntry() { const insideIp = document.getElementById('simInsideIp').value.trim(); const insidePort = parseInt(document.getElementById('simInsidePort').value); const outsideIp = document.getElementById('simOutsideIp').value.trim(); const dstIpPort = document.getElementById('simDstIpPort').value.trim(); if (!insideIp || !outsideIp || !dstIpPort || isNaN(insidePort)) { alert('Fill in all simulator fields.'); return; } const patPort = nextPatPort++; if (patPort > 65535) { alert('PAT pool exhausted (port 65535 reached).'); return; } natEntries.push({ insideIp, insidePort, outsideIp, patPort, dstIpPort, proto: 'TCP' }); renderNatTable(); // Auto-increment inside port for easy demo document.getElementById('simInsidePort').value = insidePort + 1; } function clearNatTable() { natEntries = []; nextPatPort = 1024; renderNatTable(); } function renderNatTable() { const div = document.getElementById('natTable'); const section = document.getElementById('natTableSection'); if (!natEntries.length) { section.style.display = 'none'; div.innerHTML = ''; return; } section.style.display = 'block'; let rows = natEntries.map((e, i) => ` ${i + 1} ${e.insideIp}:${e.insidePort} ${e.outsideIp}:${e.patPort} ${e.dstIpPort} ${e.proto} `).join(''); div.innerHTML = ` ${rows}
# Inside Local Inside Global (PAT) Destination Proto
${natEntries.length} entries | Next PAT port: ${nextPatPort}
`; }