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 = '
${isExhausted ? `
` : ''}
${i + 1}
${e.insideIp}:${e.insidePort}
${e.outsideIp}:${e.patPort}
${e.dstIpPort}
${e.proto}
`).join('');
div.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
${overflow.toLocaleString()}
Sessions DROPPED (overflow)
${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) => `Formula: ${ips} IP(s) × ${proto === 'both' ? '2 × ' : ''}64,512 ports = ${poolSize.toLocaleString()} slots
| # | Inside Local | Inside Global (PAT) | Destination | Proto |
|---|
${natEntries.length} entries | Next PAT port: ${nextPatPort}
`;
}