Skip to content

How Do You Get SNMPv3 authPriv on an ESP32-S3-ETH When ESP-IDF Has No Switch for It?

A server-room monitor on the Waveshare ESP32-S3-ETH serving SNMPv3 authPriv from lwIP's own agent, with commit-confirm network changes, set beside WIZnet's EOE-W55RP20 module.

Grace_Koo

Published October 23, 2026

Original author: vrngpbOriginal source (new tab)

How Do You Get SNMPv3 authPriv on an ESP32-S3-ETH When ESP-IDF Has No Switch for It?

Components

Hardware components

WIZnet parts

Project description

📚 Context: vrngpb/snmpv3_agent_s3eth — firmware for a Waveshare ESP32-S3-ETH that reports a server room's temperature, water leak and door state over SNMPv3 authPriv, and takes network settings by SNMP SET with a five-minute confirm-or-revert.


01 — What the repository builds

A monitoring node that sits in a server room. It reads three sensors, serves them over SNMP, and a management system collects them with SNMPv3.

SensorPartHow it is read
TemperatureDS18B201-Wire, every 2 s
Water leakGidrolock WSPGPIO behind a 2N3904 transistor
Two doorsreed switchesdry contact, pull-up

The README is firm that the leak sensor must never be wired straight to a GPIO: its loop runs at 5–24 V and burns the port.

Pins

GPIOUse
11 / 12 / 13 / 14W5500 MOSI / MISO / SCK / CS
10 / 9W5500 INT / RST
16DS18B20 data, 4.7 kΩ pull-up
17leak input
18 / 21door 1 / door 2
2 / 1network LED / alarm LED
8factory-reset button, hold 5 s

GPIO 4–7 belong to the TF slot, 33–37 to the octal PSRAM and 19/20 to USB, so the design routes around them. The button is on 8 because 5 is the TF card's MISO.

The MIB

Standard MIB-2 plus one enterprise subtree at .1.3.6.1.4.1.9999.1.

Last OIDTypeAccessMeaning
1INTEGERROtemperature × 10 (246 = 24.6 °C)
2GAUGE32ROfree heap, bytes
3TIMETICKSROuptime
4GAUGE32ROheap used, %
5OCTET STRINGROMAC
6INTEGERROleak (1 = alarm)
7 / 8INTEGERROdoor 1 / door 2 (1 = open)
10 / 11 / 12OCTET STRINGRWIP / gateway / mask
13INTEGERRWconfig confirm — GET reports trial mode, SET 1 confirms

The alarm LED blinks on a leak, an open door or anything above 45 °C. The README ships a bash monitor for net-snmp and a Python one pinned to pysnmp 4.4.12.


02 — ESP-IDF has no switch for SNMP

lwIP carries an SNMP agent, but ESP-IDF exposes no Kconfig option to turn it on. So the repository adds a component that pulls lwIP's own sources into the build.

set(LWIP_PATH "$ENV{IDF_PATH}/components/lwip/lwip")
file(GLOB SNMP_SOURCES
    "${LWIP_PATH}/src/apps/snmp/*.c"
    "${LWIP_PATH}/src/apps/snmp/snmp_mib2/*.c")
idf_component_register(SRCS ${SNMP_SOURCES} INCLUDE_DIRS "." REQUIRES lwip mbedtls)
target_compile_definitions(${COMPONENT_LIB} PUBLIC
    -DLWIP_SNMP=1 -DSNMP_LWIP=1 -DSNMP_USE_RAW=1
    -DLWIP_SNMP_V3=1 -DLWIP_SNMP_V3_MBEDTLS=1
    -DMIB2_STATS=1 -DLWIP_STATS=1)
  • It globs apps/snmp and snmp_mib2 out of the lwIP tree that IDF already ships.
  • SNMP_USE_RAW=1 — the agent attaches through lwIP's raw API, not sockets.
  • LWIP_SNMP_V3_MBEDTLS=1 — SHA-1 and AES come from IDF's mbedTLS.
  • A line converting Windows backslashes and a -Wno-dangling-pointer are the traces of it not building cleanly as-is.

The component's own description reads "for IDF v6, no Kconfig option".


03 — The USM callbacks are filled in by hand

lwIP's SNMPv3 asks the application for the user table and the engine state through callbacks. snmpv3_usm.c supplies them.

Engine ID — exactly the RFC 3411 layout.

eid[0] = 0x80 | ((SNMP_ENTERPRISE >> 24) & 0x7F);   /* enterprise number, top bit set */
eid[1..3] = SNMP_ENTERPRISE;
eid[4] = 0x03;                                      /* format: MAC address */
memcpy(&eid[5], mac, 6);

Engine boots — kept in NVS and incremented on every boot. It is what replay protection relies on, so it has to survive a power cycle.

Engine time — a 1-second esp_timer. The comment notes that lwIP refreshes its internal time on every inbound message, so the tick deliberately does not call into the stack.

Keys — the passphrases are localized with lwIP's helper.

StepAction
1repeat the passphrase out to 1 MB
2SHA-1 → 20-byte Ku
3Kl = SHA-1(Ku ‖ engineID ‖ Ku)

The auth key is all 20 bytes; the privacy key uses the first 16 for AES-128. The two passphrases are independent.

There is one user. Its name and both passphrases go into the build through cmake -D. An empty username is treated as an engine-discovery probe and let through.


04 — Change the IP and you have five minutes to confirm it

This is the most carefully built part. Change a remote device's address over SNMP SET with a typo in it and the device is gone for good. So the repository borrows JunOS's commit confirmed.

StepWhat happens
SETIP, gateway and mask are stored in NVS as candidates; the live settings stay. Reboot after 1 s
Trial bootcomes up on the candidates. The state is moved from TRIAL to REVERT before they are applied
ConfirmSET 1 to .13 at the new address, within five minutes. Candidates become the main settings, no reboot
Not confirmedtimer expiry, a panic, the watchdog or a power loss — whichever it is, the next boot runs the old settings

The ordering is the point. The trial boot writes REVERT into NVS before it applies the candidates, so anything that dies during the trial leaves the next boot on the revert path. Confirmation runs the other way round — the main keys are written first and the NORMAL flag last, so a crash mid-confirm still leaves consistent main settings.

lwIP's two-phase scalar nodes are used as intended. test checks for a strict dotted quad, a contiguous mask and a length of 7 to 15; set stores. Sending IP, gateway and mask in one PDU calls the callback three times and schedules the reboot once. Confirming outside trial mode returns inconsistentValue.

Anything left out of the SET inherits the current value. Changing only the IP and leaving the gateway alone works.


05 — The W5500 side

ItemValue
DriverESP-IDF in-tree, CONFIG_ETH_SPI_ETHERNET_W5500 in sdkconfig
BusSPI2, 36 MHz, mode 0, queue 20
INT / RSTGPIO 10 / 9, PHY address 1
MACESP_MAC_ETH from the ESP32-S3 eFuse
IPstatic; on link-up, dhcpc is stopped and the NVS values are applied

The comment explains the eFuse MAC — the W5500 has no MAC burned in. If the driver fails to install, the log prints all six pins so wiring is the first thing checked.

The chip runs MACRAW and lwIP does TCP/IP. SNMP is UDP 161, one socket, and the agent itself lives inside that same lwIP.

The task watchdog is 5 s and panics into a reboot. Both the sensor task and the button task register with it.


06 — Beside WIZnet's EOE-W55RP20 SNMP module

There is a WIZnet module that does the same job. A W55RP20 packages an RP2040 and a W5500 together, and the host MCU exchanges AT commands over UART and nothing else. The overlap with this repository is large enough that putting them side by side shows who carries what.

Itemsnmpv3_agent_s3ethEOE-W55RP20
Where SNMP runslwIP on the ESP32-S3inside the module
TCP/IPlwIP, chip in MACRAWW5500 hardware
What the host doeseverythingexchanges values over UART
Versionsv3 onlyv1 / v2c / v3, only v3 on by default
Auth / privacySHA-1 / AES-128SHA-1 or SHA-256 / AES-128
Usersone, fixed at buildup to 4, four roles, passwords not stored
Objects13, in codeup to 1024, created by number or from CSV
Dangerous SETs5-minute commit-confirmConfirmed SET — the host must approve
TrapsnoneTrap and Inform to 4 receivers, Informs retried
Configurationbuild options and SNMP SET61 AT commands, web UI off by default
Firmware updateidf.py flashverified, staged, installed at next boot

One problem gets two different answers: how to accept a write safely. The repository puts a clock on it — a confirmation at the new address within five minutes keeps the change, otherwise it reverts. The module puts a person on it — a written value is offered to the host MCU first and applied only on approval. For values that cut the connection the moment they change, like network settings, the first fits; for values with an immediate physical effect, like a relay, the second does.

The rest is division of labour. Here the ESP32-S3 carries the SNMP stack, the USM and TCP/IP. The module lifts all of that off and leaves the host with a UART. A small host, a need for SHA-256 and several users, or hundreds of objects point that way; a handful of sensors and one MIB is lighter done directly, as this repository does.


07 — Where it stands

  • There is no licence file. Reusing the code needs a word with the author.
  • The README is in Russian; the comments mix Russian and English.
  • One user, with passphrases baked into the build. Changing them means reflashing.
  • SHA-1 only. That is what lwIP supports; there is no SHA-256.
  • No traps. Alarms have to be polled with GET.
  • sysContact and sysLocation are fixed in code.
  • No DHCP, static IP only; the defaults live in ethernet_app.c.

It opens a door IDF leaves shut by building lwIP's sources directly, fills in the USM by hand, and bolts a revert onto address changes. The three places anyone bringing up SNMPv3 on ESP-IDF hits first are all left in the code.


08 — Similar Projects on WIZnet Makers


Q&A

Q. In what mode is the W5500 used?

MACRAW, through ESP-IDF's in-tree driver. lwIP handles TCP/IP and the SNMP agent runs inside that same lwIP. It is on SPI2 at 36 MHz, INT on GPIO10, RST on GPIO9, with the MAC taken from the ESP32-S3 eFuse.

Q. Why does enabling SNMP on ESP-IDF need its own step?

lwIP has an SNMP agent, but IDF does not expose a Kconfig option for it. The repository adds a component that globs the apps/snmp sources out of IDF's lwIP tree, compiles them directly, and attaches mbedTLS with LWIP_SNMP_V3_MBEDTLS=1.

Q. What happens when network settings are changed over SNMP?

The new values are stored as candidates in NVS and the device reboots into trial mode after one second. A SET of 1 to .13 at the new address within five minutes makes them permanent; without it the device returns to the previous settings. A panic, watchdog or power loss during the trial also lands on the revert path at the next boot.

Q. How does it differ from WIZnet's SNMP module?

In where SNMP and TCP/IP run. Here it is lwIP on the ESP32-S3; on the EOE-W55RP20 it is inside the module and the host only uses a UART. The module is broader on users, SHA-256, object count, traps and web configuration; for a few sensors and one MIB, doing it directly as this repository does is lighter.

Q. Can it be reused?

There is no licence file. The structure and settings can be read and applied; reusing the code needs the author's confirmation.


Original Link: https://github.com/vrngpb/snmpv3_agent_s3eth

lwIP SNMP build: components/snmp_lwip/CMakeLists.txt · USM: main/snmpv3_usm.c · commit-confirm: main/ethernet_app.c, main/main.c · Compared against: EOE-W55RP20 SNMP module

Comments

Similar projects you might like

Comments