esp-twin
Source: github.com/read-docs/esp-twin
What it is
A Wi-Fi repeater for a home network, running on an ESP32-S3-DevKitC-1. The chip joins the home router as a station (STA) and runs its own access point (AP) at the same time. Clients on the AP get addresses from the ESP and reach the internet through it.
It’s no_std Rust on esp-hal, with the
Embassy async executor, embassy-net and smoltcp for networking,
and edge-dhcp for the DHCP server.
Why NAT
The router only accepts frames from the ESP’s own STA MAC address, so a plain bridge won’t
work. The repeater has to do what a home router does: rewrite the source MAC, IP address and
port of each outgoing packet, keep a table of translations, map replies back to the right
client, and recompute the IPv4 and TCP/UDP checksums. No no_std NAT crate exists, so this
part is written from scratch on top of smoltcp::wire and heapless.
Frames from AP clients are classified in a wrapper around the AP network driver: traffic for the ESP itself goes to its own stack, and everything else is passed to the NAT task through a zero-copy channel.
What works so far
- AP and STA running at the same time
- DHCP server for AP clients (
192.168.2.0/24) - Classifying client traffic into “for the ESP” and “to forward”
- UDP NAT in both directions, tested with DNS queries from a phone
What’s next
- TCP, then ICMP
- Expiring NAT table entries and removing them when a client disconnects
- Handing out the router’s DNS server to AP clients