PAT maps many hosts to 1 public IP
Port numbers distinguish connections. The NAT table tracks every active mapping.
SNMP monitors the network, but SNMP does not solve a fundamental addressing issue: the internet ran out of IPv4 addresses. NAT is the workaround.
NAT (Network Address Translation) maps private IP addresses (RFC 1918: 10.0.0.0/8, 172.16.0.0/12, 192.168.0.0/16) to public IP addresses. NAT exists because the IPv4 address space (4.3 billion addresses) is exhausted. Without NAT, every device needs a globally unique public IP.
PAT (Port Address Translation), also called NAT overload, maps many private addresses to a single public address by using different source port numbers to distinguish connections.
The router maintains a NAT translation table that maps each internal IP:port pair to an external IP:port pair. Return traffic is matched against this table and forwarded to the correct internal host.
NAT breaks protocols that embed IP addresses in the application payload. Modbus TCP works through NAT because Modbus TCP does not embed addresses. EtherNet/IP (CIP) breaks because the CIP layer carries IP addresses inside the payload, and NAT does not inspect or rewrite CIP data. OPC UA works through NAT when using TCP transport, but discovery services that return internal addresses are unsuccessful.
The following script reads the Linux NAT connection tracking table, showing active translations. Run the script on a Linux router or firewall to see which internal hosts have active NAT sessions.
import refrom pathlib import Path
def read_nat_table() -> list[dict]: conntrack = Path("/proc/net/nf_conntrack") if not conntrack.exists(): conntrack = Path("/proc/net/ip_conntrack") entries = [] for line in conntrack.read_text().splitlines(): m = re.search(r"src=(\S+) dst=(\S+) sport=(\d+) dport=(\d+).*" r"src=(\S+) dst=(\S+) sport=(\d+) dport=(\d+)", line) if m: entries.append({ "orig_src": m.group(1), "orig_dst": m.group(2), "orig_sport": m.group(3), "orig_dport": m.group(4), "reply_src": m.group(5), "reply_dst": m.group(6), }) return entries
for entry in read_nat_table()[:10]: print(f"{entry['orig_src']}:{entry['orig_sport']} -> " f"{entry['orig_dst']}:{entry['orig_dport']} " f"(reply from {entry['reply_src']})")Each line shows the original source, destination, and the reply path. When the reply source differs from the original destination, NAT is rewriting addresses.
PAT maps many hosts to 1 public IP
Port numbers distinguish connections. The NAT table tracks every active mapping.
NAT breaks EtherNet/IP and OPC UA discovery
Protocols that embed IP addresses in the payload are unsuccessful through NAT. Use routed VLANs with firewall rules in OT networks.
NAT solves the address exhaustion issue, but NAT does not solve the gateway redundancy issue. When the default gateway becomes inoperable, devices on the subnet lose connectivity. The next page covers FHRP, the protocol family that delivers gateway redundancy.