Layer 2 Address Translation

Building a Layer 2 Based Captive Access Structure

By Jordan Hrycaj
Date: Tue, Sep 22, 2015 (updated Thu, Sep 1, 2016)
Category: Architecture,
Tags: arp c network tun/tap
Updated: 31 Mar 2017

The Challenge

Years ago I was asked to develop and programme a gateway access system so that a customer can use an unconfigured laptop with WiFi enabled and connect automatically to our (captive) WiFi internet gateway.

Even as this kind of technology is not too hard to set up there are many reasons not to deploy such a system on a larger network:

  • The captive gateway must be the only gateway on this network.
  • It implies star topology: peer-to-peer connections might not work.
  • This approach does not scale well.

Most laptops are DHCP ready so it makes more sense to work with this technology. DHCP has been used for many years and is well understood.

Software on Sourceforge

Nevertheless, I published such a layer 2 gateway system called SHaT on Sourceforge but abandoned it more than a decade ago. SHaT stands for Source Hardware address Translation and was inspired by the abbreviation NAT.

Curiously, when I came back to Sourceforge and wanted to retire this supposedly dormant project I found that I had 500 downloads, year-to-today (~2015). This made me wonder.

I decided to leave the software as-is on Sourceforge and rather offer to move the project code base to GitHub so I can polish it. Please send me a message or drop me a note if you need to have SHaT re-factored. I will certainly not touch anything if there is only one request but for more general interest I will spend some time on it.

Technical Details

The basic idea is based on ARP-spoofing. This will attract any laptop connecting to the LAN (which might typically be WiFi and also called WLAN) to the SHaT gateway.

SHaT Gateway-Laptop Initial Conversation

When a laptop connects to a SHaT enabled network there are basically two possibilities:

  1. The laptop sends an initial DHCP configuration request
  2. The laptop tries to reach another computer with a particular IP address

In case 1, the laptop configures itself via DHCP. It sets an IP address and a default gateway which is the prerequisite for case 2.

Considering case 2, the laptop will be statically pre-configured for some other network. There is an IP address and a default gateway set. Trying to find out how to connect to a particular IP address on the internet, the laptop broadcasts so called WHO-HAS requests. SHaT will answer every request pretending to be the gateway for everything and everybody. It will proxy every possible IP address in the network that comes across.

So, a laptop on the LAN with the SHaT gateway running will send every data packet to that gateway believing it can forward the packet. The source IP address of the laptop will be irrelevant for forwarding (it can be anything) as explained below.

Internal Architecture of The SHaT Gateway

The SHaT tool service on the gateway is a Linux user space programme running between two interfaces called wlan0 and tun0.

        network       SHaT gateway
      |---------| |--------------------------------------------|
          \                ___________               /
          |   +-------+   /           \   +------+   | internal
      LAN |---| wlan0 |---| SHaT tool |---| tun0 |---|  TCP/IP
          |   +-------+   \___________/   +------+   | network
          /                                          \

The wlan0 interface to the left of the SHaT tool is a regular interface on a WiFi or Ethernet LAN (in case of Ethernet the interface would typically be named eth0 rather than wlan0). The tun0 interface to the right is special.

From the internal TCP/IP network (right hand) side, the tun0 interface looks like any other interface for TCP/IP routing and packet forwarding. At the other end it is directly attached to the SHaT tool which can directly read out and write network data packages from and into the tun0 interface.

When a data packet arrives at the wlan0 interface the SHaT tool reads this packet, modifies its IP addresses and forwards it to the tun0 gateway to be processed by other network tools on the internal TCP/IP network.

Reversely, when the other network tools on the internal TCP/IP network send a packet into the tun0 interface, the SHaT tool has to reverse addresses and forward them through the wlan0 interface onto the LAN. The SHaT implementation allows upstream connections only, i.e. connections from the laptop on the LAN into the internal TCP/IP network (which might be forwarded to the internet).

Hardware Address Translation

Even though the internal SHaT gateway architecture is deeply embedded into the Linux operating system structure its logic is straight forward.

The main challenge is the way IP and hardware addresses need to be mapped when travelling through the SHaT tool. The wlan0 an the tun0 interfaces are not symmetric. The network data packet address layout sort of looks like:

    LAN(wlan0)   -- source HW address          (a)
                 -- destination HW address     (b)
                 -- IP source address          (c)
                 -- source port                (d)
                 -- target IP address          (e)
                 -- target port (TCP/UDP only) (f)

    TCP/IP(tun0) -- IP source address          (g)
                 -- source port                (h)
                 -- target IP address          (i)
                 -- target port (TCP/UDP only) (j)

The SHaT tool has to associate and register MAC and IP addresses so that proper mapping can take place in either direction.

Travelling Left to Right

A data packet travelling (left to right) LAN to internal TCP/IP network maps data packets as follows:

   LAN(wlan0)   -- source HW address (a) is registered (MAC address of the laptop)
                -- dest. HW address  (b) is ignored/discarded
                -- IP source address (c) is registered
                -- source port       (d) is registered
                -- target IP address (e) is copied to (i)
                -- target port       (f) is copied to (j)

   TCP/IP(tun0) -- IP source address (g) => tun0 interface IP address
                -- source port       (h) => generated for registry look up
                -- target IP address (i) => copied from (e)
                -- target port       (j) => copied from (f)

Source IP address and port are replaced (as in NAT) and items (a), (c), and (d) registered with look up key (h).

Travelling Right to Left

Any data packet travelling (right to left) TCP/IP network to LAN must be a downstream packet belonging to an already existing connection.

   LAN(wlan0)   -- source HW address (a) => local MAC address
                -- dest. HW address  (b) => from registry (laptop MAC address)
                -- IP source address (c) => copied from (g)
                -- source port       (d) => copied from (h)
                -- target IP address (e) => from registry (laptop IP address)
                -- target port       (f) => from registry (was laptop source port)

   TCP/IP(tun0) -- IP source address (g) is copied to (c)
                -- source port       (h) is copied to (d)
                -- target IP address (i) is tun0 interface IP address
                -- target port       (j) is generated port

So its destination port (j) can be looked up in the registry and (b), (e) and (f) written into a layer 2 packet that is sent to destination MAC address (b).


The mapping scheme allows to place regular services on the internal TCP/IP network where tun0 is attached to. Services on that network see (laptop) clients transparently with the IP address of the tun0 interface.

After all, the mechanics used for mapping packets is similar to what modern virtual engines do with virtual NAT interfaces.