100% Free Forever
AI-Powered Learning
Industry Expert Content
Certificates & Badges
Learn At Your Own Pace
Python

Network Address Translation (NAT)

See how NAT rewrites private IP addresses to public ones, conserving IPv4 addresses and hiding internal network structure.

Network SecurityIntermediate10 min readJul 8, 2026
Analogies

Introduction

Network Address Translation (NAT) lets many devices on a private network share one or a few public IP addresses to reach the internet. It was originally developed to slow the exhaustion of IPv4 addresses, and as a side effect it also hides internal network topology from the outside world, which has security benefits similar to a lightweight firewall.

🏏

Cricket analogy: NAT is like an entire domestic team sharing one national jersey number when playing internationally, letting many players (private IPs) be represented by one visible identity (public IP) to conserve limited international squad slots, while also hiding the domestic bench from opposition scouting.

Explanation

Private networks typically use address ranges reserved by RFC 1918 that are never routed on the public internet: 10.0.0.0/8, 172.16.0.0/12, and 192.168.0.0/16. A NAT-capable router sits at the boundary between this private network and the public internet. When an internal host sends a packet outbound, the router rewrites the packet's private source IP:port to the router's public IP and a chosen port, and records this mapping in a translation table. When a reply comes back addressed to that public IP:port, the router looks up the translation table and rewrites the destination back to the original private IP:port before forwarding it inward. There are three main NAT variants. Static NAT maps one private IP permanently to one public IP, a fixed one-to-one relationship often used to make an internal server reachable at a consistent public address. Dynamic NAT maps private IPs to public IPs from a pool, on a one-to-one basis but assigned as needed, useful when you have a pool of public addresses shared among more private hosts than addresses (with the drawback that if the pool is exhausted no more new mappings can be made). PAT (Port Address Translation), also called NAT overload, is a many-to-one mapping: many private hosts share a single public IP address, distinguished from each other by using different source ports, so the translation table tracks (private IP, private port) to (public IP, unique public port) simultaneously for many connections. PAT/NAT overload is by far the most common form in home and small-office routers.

🏏

Cricket analogy: The three RFC 1918 ranges are like three levels of domestic cricket (club, district, state) never broadcast internationally; a NAT router is like the selection committee that translates a domestic player's identity into a national jersey number (public IP:port) and records the mapping, restoring it when results come back, whether it's static (a permanent number for a star all-rounder), dynamic (numbers assigned from a pool as players are picked), or PAT (many domestic players sharing one national jersey, distinguished by squad position).

Example

python
# Conceptual NAT translation table (PAT / NAT overload)
translation_table = {
    # (public_ip, public_port): (private_ip, private_port)
    ("203.0.113.5", 40001): ("192.168.1.10", 51000),
    ("203.0.113.5", 40002): ("192.168.1.11", 51000),
    ("203.0.113.5", 40003): ("192.168.1.10", 51001),
}

def translate_inbound(pub_ip, pub_port):
    return translation_table.get((pub_ip, pub_port))

print(translate_inbound("203.0.113.5", 40002))
# -> ('192.168.1.11', 51000)  router restores the original private IP:port

Analysis

The reason PAT can support many private hosts behind one public IP is that TCP/UDP connections are identified by the full 4-tuple (source IP, source port, destination IP, destination port); by rewriting the source port as well as the source IP, the router can keep thousands of simultaneous outbound connections distinct even though they all appear to originate from the same public IP. This is also why NAT is inherently outbound-connection-oriented: without a pre-existing entry in the translation table (or a static/port-forwarding rule), an unsolicited inbound packet has nothing to match against and is dropped, which is why NAT is often mistaken for a firewall even though its real purpose is address conservation.

🏏

Cricket analogy: A stadium can host thousands of simultaneous conversations distinguished by seat number even though they all sound like they're coming from the same stand; similarly PAT distinguishes thousands of connections by port number even though they share one public IP, and without a prior mapping an unsolicited shout from outside the ground goes unheard, which is why NAT gets mistaken for security.

Key Takeaways

  • NAT rewrites private IP:port to public IP:port on the way out, and reverses it on the way back, using a translation table.
  • RFC 1918 private ranges: 10.0.0.0/8, 172.16.0.0/12, 192.168.0.0/16.
  • Static NAT is a fixed one-to-one mapping; Dynamic NAT is a pooled one-to-one mapping; PAT/NAT overload is many-to-one via port multiplexing.
  • PAT is the most common form, allowing an entire private network to share a single public IP.

Practice what you learned

Was this page helpful?

Topics covered

#Python#ComputerNetworksStudyNotes#ComputerNetworks#NetworkAddressTranslationNAT#Network#Address#Translation#NAT#Networking#StudyNotes#SkillVeris