【Rust/ESP32】W5500を2枚使った「ループ未然検知ツール」の開発記録
Stop the Broadcast Storm Before It Starts — A Network Loop Pre-Detection Tool Built with ESP32, Dual W5500, and Rust
요약
ESP32 한 장에 W5500 두 개를 연결해, 네트워크 루프가 발생하기 전에 감지하는 진단 툴입니다. LwIP(소프트웨어 네트워크 스택)를 우회해 W5500을 SPI 디바이스로 직접 제어함으로써, OS 의존 툴이 수 초 걸리는 재연결을 마이크로초 단위로 처리합니다. Rust의 소유권 모델을 활용한 안전한 SPI 버스 공유와, W5500 소켓 레지스터를 직접 감시하는 자기 수복(Self-Healing) 구조가 이 프로젝트의 핵심입니다.
개요
네트워크 관리자에게 브로드캐스트 스톰은 악몽 같은 장애입니다. 스위치의 두 포트가 같은 세그먼트에 연결(루프 구성)되면, 패킷이 두 포트 사이를 무한 순환하며 트래픽이 폭주합니다. 순식간에 네트워크 전체가 다운되고, 원인을 파악하는 데도 상당한 시간이 걸립니다.
이 프로젝트는 그 상황이 벌어지기 전에 위험을 알려주는 것을 목표로 합니다. 케이블을 꽂기 전에 두 포트가 같은 네트워크에 연결되어 있는지 확인하고, LED 하나로 즉시 결과를 표시합니다. DHCPサーバ가 없는 공장 현장이나 임시 배선 환경에서도 바로 쓸 수 있도록, APIPA(169.254.x.x) 고정 IP를 사용해 별도 네트워크 설정 없이 동작합니다.
아키텍처
하드웨어 구성
감지 흐름
핵심 기술
① UDP 브로드캐스트 — 미지의 네트워크를 탐색하는 방법
루프를 감지하려면 "두 포트가 같은 네트워크에 있는지"를 확인해야 합니다. 그런데 미지의 환경에서는 상대방의 IP 주소를 알 수 없습니다. 이 문제를 UDP 브로드캐스트로 해결합니다.
- 전방위 송신:
255.255.255.255수신처로 패킷을 보내면 같은 세그먼트의 모든 기기에 도달합니다 - L2 플러딩 활용: L2 스위치는 브로드캐스트를 모든 포트에 전달하므로, 두 포트가 같은 스위치에 연결되어 있으면 Unit B가 수신합니다
- MAGIC 문자열로 오탐 방지:
CHECK_LOOP라는 식별자를 페이로드에 포함해, 다른 기기의 패킷을 루프로 잘못 판정하지 않도록 합니다
덕분에 ARP 없이, DHCP 없이, 상대방 IP 정보 없이도 즉시 감지가 가능합니다.

② LwIP 바이패스 — OS 스택을 우회하는 이유
ESP32(ESP-IDF)에는 LwIP라는 강력한 소프트웨어 네트워크 스택이 기본 탑재되어 있습니다. 그러나 이 프로젝트에서는 의도적으로 LwIP를 사용하지 않습니다.
이유는 명확합니다. 같은 서브넷(169.254.x.x/16)을 가진 두 인터페이스를 OS에 등록하면, OS가 "이 패킷을 어느 포트로 내보낼까?"를 혼동해 의도한 감지가 불가능해집니다.
대신 W5500을 독립된 SPI 디바이스로 직접 제어합니다.
- 라우팅 간섭 없음: OS 관리 밖에 있으므로 두 W5500이 완전히 독립적으로 동작
- 하드웨어 UDP 오프로딩: UDP 패킷 생성과 체크섬 계산을 W5500 하드웨어가 처리 → ESP32 CPU 부하를 최소화하면서 10ms 단위 고속 폴링 유지
- 소켓 레지스터 직접 접근: W5500의
Sn_SR레지스터를 직접 읽어 소켓 상태를 실시간 감시
③ Rust 소유권 모델 — SPI 버스 공유의 안전장치
단일 SPI2 버스에 W5500 두 개를 공유하는 구성에서, CS(Chip Select) 핀 충돌은 치명적 오류로 이어집니다. 이 프로젝트는 Rust 언어의 소유권 모델로 이 문제를 언어 차원에서 해결합니다.
SpiDeviceDriver를 Unit A(CS: GPIO25)와 Unit B(CS: GPIO13)에 각각 인스턴스화- 물리적 CS 핀 전환이 드라이버 내부에서 자동 처리됨
- 두 칩을 동시에 접근하는 코드는 컴파일 타임에 오류 → 런타임 버그 원천 차단
W5500 듀얼 구성이 이 프로젝트를 가능하게 한다
이 프로젝트에서 W5500은 2개 사용됩니다. 각각 Unit A(송신), Unit B(수신)로 역할을 분리하고, ESP32 하나에서 SPI를 통해 제어합니다.
W5500을 선택한 핵심 이유는 하드웨어 TCP/IP 스택의 독립성입니다. 각 W5500은 ESP32의 OS 스택과 무관하게 독자적인 MAC, IP, 소켓 상태를 유지합니다. 이 독립성 덕분에 LwIP 없이도 두 포트가 완전히 분리된 네트워크 인터페이스로 동작할 수 있습니다.
또한 W5500의 소켓 상태 레지스터(Sn_SR)를 직접 읽고 쓸 수 있는 구조가, 아래 "좀비 소켓 문제"를 해결하는 자기 수복 로직의 근간이 됩니다.
| 항목 | Unit A | Unit B |
|---|---|---|
| CS 핀 | GPIO25 | GPIO13 |
| IP 주소 | 169.254.1.1 | 169.254.1.2 |
| MAC 주소 | 00:08:DC:01:00:01 | 00:08:DC:01:00:02 |
| 소켓 역할 | UDP 송신 (Port 8887) | UDP 수신 (Port 8888) |
개발 난관: 좀비 소켓 현상과 자기 수복
개발 후반, 루프 감지 직후 일정 시간이 지나면 물리 링크는 UP인데 수신이 완전히 멈추는 현상이 발생했습니다.
원인은 L2 스위치의 루프 방지 기능이었습니다. 툴이 루프를 유발하자 스위치가 포트를 순간 차단 → 마이크로초 단위의 순단(瞬斷) 발생 → W5500 내부 소켓이 강제로 Closed (0x00) 상태로 전환. 이것이 "좀비 소켓" 의 정체입니다.
이를 해결한 것이 상태 머신 기반 자기 수복(Self-Healing) 구조입니다.
- 즉시 감지: 메인 루프마다 W5500의
Sn_SR레지스터를 직접 폴링 - 자동 재바인드: 소켓이
Closed상태임을 감지한 순간, 즉시udp_bind를 재발행 - "대기 복귀" 성공: 스위치가 포트 차단을 해제하는 0.수 초 후, 장치는 이미 수신 대기 상태로 복귀 완료
OS 기반 툴이라면 재연결에 수 초가 걸릴 상황을, 레지스터 직접 접근으로 컴마 초 이내에 복구합니다. 이 회복력(Resilience)이 현장에서의 확실한 감지를 가능하게 합니다.
비즈니스 가치 및 활용 시나리오
네트워크 루프는 특정 업종에 국한된 문제가 아닙니다. 배선이 복잡한 현장이라면 어디서든 발생할 수 있습니다.
- 공장 및 산업 현장: 배선 작업 중 실수로 루프 구성이 생기면 생산 라인 전체의 네트워크가 마비됩니다. 배선 전 확인 루틴에 이 툴을 도입하면 장애를 원천 차단할 수 있습니다.
- IT 현장 유지보수: 네트워크 엔지니어의 점검 장비로, 전용 진단 장비 없이 저비용으로 도입 가능합니다. ESP32 + W5500 BOM 비용만으로 구성되므로 소형·휴대용 제작도 용이합니다.
- 임시 네트워크 구성 환경: 이벤트 회장, 전시장 등 임시 배선이 많은 환경에서 케이블 연결 전 루프 위험을 빠르게 확인할 수 있습니다.
- W5500 듀얼 포트 응용 레퍼런스: "단일 MCU에서 독립 이더넷 포트 2개"라는 구성은 네트워크 브리지, 데이터 릴레이, 이중화 구성 등 다양한 산업용 애플리케이션의 기반 아키텍처로 활용 가능합니다.
한계 및 개선 방향
현재 한계
- 단방향 감지: Unit A → B 방향만 검사합니다. 역방향(B → A)은 독립적으로 검사하지 않아, 비대칭적 루프 구성에서는 감지 누락 가능성이 있습니다.
- 관리형 스위치 환경 제약: 브로드캐스트를 차단하도록 설정된 관리형 스위치 환경에서는 이 방식이 동작하지 않습니다.
- 단일 MAGIC 문자열: 동일 현장에 이 툴이 여러 대 존재하면 서로의 패킷을 루프로 잘못 판정할 가능성이 있습니다.
- 소켓 1개 고정: 양쪽 모두
Sn0만 사용하므로 향후 멀티 소켓 확장 시 구조 변경이 필요합니다.
개선 방향
- 양방향 감지: Unit B에서 Unit A 방향으로도 프로브를 송신하는 양방향 구성으로 감지 신뢰도를 높일 수 있습니다. W5500의 멀티 소켓 기능을 활용하면 구현 가능합니다.
- MAGIC 문자열 동적 생성: 장치 고유 UUID나 MAC 주소 기반으로 MAGIC 식별자를 동적 생성하면 다중 장치 혼재 환경에서의 오탐을 방지할 수 있습니다.
- VLAN/관리형 스위치 대응: LLC(Logical Link Control) 프레임이나 커스텀 이더타입을 활용한 L2 프레임 직접 송수신으로 브로드캐스트 제한 환경에도 대응 가능합니다. W5500의 RAW 소켓 모드가 이 방향의 출발점이 됩니다.
- 결과 로그 출력: 현재는 LED만으로 표시하지만, UART 또는 소형 OLED 디스플레이를 추가해 감지 이력을 기록하면 현장 보고서 작성에 활용할 수 있습니다.
FAQ
Q. LwIP를 사용하지 않으면 불편하지 않나요?
이 프로젝트의 용도에 한정하면, LwIP는 오히려 장애물입니다. 같은 서브넷의 두 인터페이스를 OS에 등록하면 라우팅이 혼란스러워져 원하는 포트에서 패킷을 내보낼 수 없습니다. W5500을 직접 SPI 제어하면 이 제약이 없고, 하드웨어 오프로딩 덕분에 코드도 훨씬 단순해집니다.
Q. W5500이 왜 2개 필요한가요? 1개로는 안 되나요?
루프 감지는 "송신 포트"와 "수신 포트"가 물리적으로 분리되어 있어야 합니다. W5500 1개는 이더넷 포트 1개에 대응하므로, 두 독립 포트를 동시에 운용하려면 2개가 필요합니다.
Q. ESP32 외 다른 MCU에도 적용할 수 있나요?
w5500_hl 크레이트는 embedded-hal 트레이트 기반이므로, SPI 인터페이스를 지원하는 MCU라면 이식 가능합니다. STM32, RP2040 등 Rust 지원 MCU에서도 동일한 아키텍처를 구현할 수 있습니다.
Q. 현장 도입 난이도는 어느 정도인가요?
하드웨어는 ESP32 개발 보드 + W5500 모듈 2개 + LED로 구성되며, BOM 비용은 수만 원 수준입니다. 소프트웨어는 Rust + ESP-IDF 환경 구축이 필요하지만, 저자가 GitHub에 전체 소스코드와 sdkconfig를 공개하고 있어 재현성은 높습니다.
Q. 좀비 소켓 현상은 W5500 고유의 문제인가요?
W5500에 국한된 문제라기보다, 물리 링크 순단 시 소켓 상태가 리셋되는 것은 하드웨어 TCP/IP 스택 일반의 동작입니다. 중요한 점은 W5500이 소켓 상태 레지스터(Sn_SR)를 직접 읽을 수 있는 인터페이스를 제공하기 때문에, 이처럼 빠른 자기 수복 로직을 구현할 수 있었다는 것입니다.
Summary
This project connects two W5500 Ethernet controllers to a single ESP32 to detect network loops before they cause a broadcast storm. By bypassing LwIP and controlling the W5500 chips directly over SPI, the tool recovers from micro link-drops in microseconds — far faster than any OS-dependent diagnostic tool. The project showcases Rust's ownership model for safe SPI bus sharing and a self-healing socket architecture built on direct W5500 register access.
Overview
For network administrators, a broadcast storm is one of the worst failures imaginable. When two switch ports connect to the same segment — forming a loop — packets circulate endlessly between them. Traffic explodes, and the entire network goes down in seconds.
This tool's goal is to warn you before that happens. It checks whether two ports share the same network and reports the result instantly via LED — no complex setup required. By assigning fixed APIPA addresses (169.254.x.x), the tool works immediately even in environments without a DHCP server, making it practical for factory floors and temporary wiring setups.
Architecture
Hardware Layout
Detection Flow
Technical Highlights
① UDP Broadcast — Probing an Unknown Network
To detect a loop, the tool needs to determine whether two ports share the same network. In an unknown environment, the peer's IP address is unavailable. UDP broadcast solves this cleanly.
- Omnidirectional transmission: Sending to
255.255.255.255reaches every device on the same segment - L2 flooding: An L2 switch forwards broadcast packets to all ports, so Unit B receives the packet whenever both ports share the same switch
- MAGIC string prevents false positives: The payload
CHECK_LOOPacts as a fingerprint — Unit B only confirms a loop when the payload matches exactly
No ARP, no DHCP, no peer IP needed. Detection is immediate.

② LwIP Bypass — Why Skip the OS Network Stack?
ESP32 (ESP-IDF) ships with LwIP, a capable software network stack. This project deliberately avoids it.
The reason is straightforward. Registering two interfaces with the same subnet (169.254.x.x/16) into the OS causes routing confusion — the OS cannot reliably decide which port to use for outgoing packets. Instead, each W5500 is controlled directly as an independent SPI device.
- No routing interference: Both W5500 chips operate completely independently, outside OS control
- Hardware UDP offloading: The W5500 handles UDP packet construction and checksum calculation in hardware, keeping ESP32 CPU load minimal while sustaining 10ms polling intervals
- Direct register access: The
Sn_SRsocket status register is read directly, enabling real-time socket health monitoring
③ Rust Ownership Model — Safe SPI Bus Sharing
Sharing a single SPI2 bus between two W5500 chips makes CS (Chip Select) conflicts a serious risk. This project eliminates that risk at the language level using Rust's ownership system.
SpiDeviceDriveris instantiated separately for Unit A (CS: GPIO25) and Unit B (CS: GPIO13)- Physical CS pin toggling is handled automatically inside the driver
- Any code that attempts to access both chips simultaneously fails at compile time — runtime bugs are structurally impossible
Where W5500 Fits
This project uses two W5500 chips — Unit A for transmission, Unit B for reception — both controlled from a single ESP32 over a shared SPI bus.
The key reason for choosing the W5500 is its independent hardwired TCP/IP stack. Each W5500 maintains its own MAC address, IP address, and socket state, completely separate from the ESP32's OS stack. This independence makes it possible for two ports to operate as fully isolated network interfaces without LwIP.
The W5500's direct socket status register (Sn_SR) access is also the foundation of the self-healing logic described below.
| Item | Unit A | Unit B |
|---|---|---|
| CS Pin | GPIO25 | GPIO13 |
| IP Address | 169.254.1.1 | 169.254.1.2 |
| MAC Address | 00:08:DC:01:00:01 | 00:08:DC:01:00:02 |
| Socket Role | UDP TX (Port 8887) | UDP RX (Port 8888) |
Engineering Challenge: The Zombie Socket Problem
Late in development, a strange failure appeared. After detecting a loop and waiting for a while, the physical link LED stayed green — but packet reception stopped completely.
The cause was the L2 switch's own loop-prevention feature. When the tool induced a loop, the switch temporarily blocked the port, causing a microsecond-scale link interruption. That micro-drop forced the W5500 socket into Closed (0x00) state internally. This is the "zombie socket."
The fix is a state machine-based self-healing architecture:
- Instant detection: Every main loop iteration reads the W5500's
Sn_SRregister directly - Automatic rebind: The moment a
Closedsocket is detected,udp_bindis reissued immediately - Seamless recovery: By the time the switch re-enables the port — a fraction of a second later — the device is already back in receive-ready state
Where an OS-based tool would take several seconds to reconnect, direct register access achieves recovery in milliseconds. This resilience is what makes reliable field detection possible.
Business Value and Use Cases
Network loops are not limited to any specific industry. Any environment with complex cabling is at risk.
- Factory and industrial sites: A wiring mistake during installation can bring down the network for an entire production line. Adding this tool to the pre-cabling checklist eliminates that risk at the source.
- IT field maintenance: Network engineers can carry this as a low-cost portable diagnostic tool — no dedicated test equipment required. The BOM is minimal: an ESP32 dev board and two W5500 modules.
- Temporary network setups: At event venues, exhibition halls, or temporary installations, engineers can verify cable safety before connecting — instantly, with a single LED read.
- W5500 dual-port reference design: "Two independent Ethernet ports on a single MCU" is a useful architecture for network bridges, data relays, and redundant link designs across industrial IoT applications.
Limitations and Future Improvements
Current Limitations
- One-way detection only: The tool probes from Unit A to Unit B. Reverse-direction detection (B → A) is not implemented, leaving asymmetric loop configurations potentially undetected.
- Managed switch constraints: Switches configured to block broadcast traffic will prevent this detection method from working.
- Single MAGIC string: If multiple units of this tool exist on the same network, they may misidentify each other's packets as loops.
- Single socket per chip: Both units use
Sn0only. Multi-socket expansion would require structural changes.
Future Improvements
- Bidirectional probing: Adding a reverse probe from Unit B to Unit A improves detection reliability. The W5500's multi-socket support makes this achievable without major redesign.
- Dynamic MAGIC string: Generating the MAGIC identifier from a device UUID or MAC address eliminates false positives in multi-device environments.
- Managed switch support: Sending custom L2 frames using a proprietary EtherType — supported via the W5500's MACRAW socket mode — would extend the tool to broadcast-restricted environments.
- Result logging: Adding UART output or a small OLED display to record detection history would make the tool more useful for generating field inspection reports.
FAQ
Q: Doesn't skipping LwIP cause problems?
For this use case, LwIP is actually an obstacle. Registering two interfaces with identical subnets into the OS causes routing conflicts, making targeted per-port packet control impossible. Direct W5500 SPI control avoids this entirely, and hardware offloading keeps the firmware simpler as a bonus.
Q: Why does this need two W5500 chips? Can't one do the job?
Loop detection requires physically separate transmit and receive ports. One W5500 provides one Ethernet port, so two are needed to operate two fully independent interfaces simultaneously.
Q: Can this be ported to other MCUs?
Yes. The w5500_hl crate is built on embedded-hal traits, so any MCU with SPI support can use it. The same architecture applies to STM32, RP2040, and other Rust-supported platforms.
Q: How difficult is it to build and deploy?
The hardware is an ESP32 dev board, two W5500 modules, and two LEDs — a minimal BOM costing a few dollars. The software requires a Rust + ESP-IDF toolchain. The author has published the full source code and sdkconfig on GitHub, so reproducibility is high.
Q: Is the zombie socket issue specific to the W5500?
Not really. Any hardwired TCP/IP stack will reset socket state when the physical link drops. What matters here is that the W5500 exposes the socket status register (Sn_SR) for direct read access — and that's exactly what makes sub-millisecond self-healing possible.

