IPv4 Network Address Translation for Steam (NAT4S)

TL;DR – I made Steam multiplayer possible with classic LAN games through a project called PartyLAN. It enables network address translation (NAT) between IPv4 and Steam IDs.

Network address translation (NAT) is not an obscure concept – it has been in use since 1994. The basic idea is simple: a router, either software or hardware, takes packets from an incoming IP address (e.g., 192.168.1.123), converts it to another address (e.g., 1.2.3.4), and sends it out. The router also performs the reverse process, converting packets from the outside address (IP 1.2.3.4) to the inside address (e.g., 192.168.1.123).

This concept is widely used, and there are several variants of NAT based on the address space it maps from and to:

  • NAT44 – the most common form of NAT, which converts between two IPv4 addresses, typically between a class A, B, or C private address space and the public IP address space (e.g., between 192.168.1.123 and 1.2.3.4). This is what home routers use.
Illustration of NAT44 (made by Michel Bakni)
  • NAT444 – a variant of NAT44 that adds an intermediate CGNAT address space. (e.g. 192.168.1.123, then 100.89.199.129, finally to 1.2.3.4).
  • NAT64 – converts an IPv6 address to an IPv4 address and is commonly used to provide IPv4 connectivity to IPv6-only devices

By applying the concept of NAT to Steam, which can be seen as a network with Steam user IDs as network addresses, it becomes technically feasible to perform network address translation between IPv4 and Steam IDs. I refer to this as NAT4S.

How is this useful?

For PC gamers, the standard method of playing multiplayer games is Steam Multiplayer. However, older games use the vanilla IP stack designed for LAN party-style multiplayer. Playing these games over the internet is challenging for non-technical individuals and often involves configuring the firewall on the home router. By implementing a network address translator that converts between IPv4 and Steam Networking, classic games can seamlessly communicate over Steam Networking.

The Implementation

I opted to use the CGNAT address space (100.64.0.0/10) for the mapping. Unlike traditional class A/B/C private addresses, this address space is rarely used by end-user devices.

However, a problem arises immediately: the CGNAT address space only contains about 4 million addresses, which may seem like a lot but is significantly smaller than the number of Steam accounts, exceeding 1 billion. So, how do we accommodate 1 billion accounts with just 4 million addresses? The answer is simple: we don’t. On average, a Steam user has fewer than 100 friends, and Valve limits the number to 250. By taking the Steam ID modulo 4 million, the chances of collision are incredibly small (around 0.1%) for the average user. In the unlikely event of a collision, we increment the address by 1 until a free address is found. This IP allocation method ensures relatively stable IPs that are likely to be the same on different computers. It is also stateless, eliminating the need for a DHCP-like protocol.

Leave a comment

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.