NAT/PAT Table Visualizer
NAT/PAT 表格視覺化器
模擬 PAT 負載映射、計算 NAT 表容量並可視化埠耗盡臨界值。
PAT 項目模擬器
模擬新增 NAT 項目,查看轉譯表如何增長。
埠耗盡參考
| 平台 | PAT 埠範圍 | 每 IP 埠數 | 最大轉譯次數 |
|---|---|---|---|
| Cisco IOS/IOS-XE | 1024–65535 | 64,512 | 64,512 × outside IPs |
| Cisco ASA | 1024–65535 (default) | 64,512 | 受限於 xlate 表記憶體 |
| Linux iptables/nftables | 1024–65535 (default) | 64,512 | 受限於 conntrack 表大小 |
| Windows Server NAT | 1025–5000 (legacy) / 1024–65535 | 63,511 | 透過登錄檔設定 |
| RFC 4787 (BEHAVE) | 建議保留來源埠 | — | 每個終端機對應埠 |
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}
`;
}