DeterministicESPAsyncWebServer v6.27.1
Zero-allocation, bounded-execution async HTTP server for ESP32
Loading...
Searching...
No Matches
snmp_notify.h
Go to the documentation of this file.
1// Copyright (C) 2026 Douglas Quigg (dstroy0) <dquigg123@gmail.com>
2// SPDX-License-Identifier: AGPL-3.0-or-later
3
4/**
5 * @file snmp_notify.h
6 * @brief Outbound SNMP notifications - Trap and InformRequest (DETWS_ENABLE_SNMP_TRAP).
7 *
8 * Lets the agent push events to a manager instead of only answering polls:
9 * SNMPv2c (RFC 3416) and, when DETWS_ENABLE_SNMP_V3 is set, SNMPv3 USM (authPriv)
10 * notifications. Every notification carries the mandatory `sysUpTime.0` and
11 * `snmpTrapOID.0` bindings plus any caller varbinds. Split, like the other
12 * services, into a host-testable PDU builder and an ESP32 UDP send:
13 *
14 * - snmp_notify_build_v2c() is a pure BER function, unit-tested on the host
15 * (env:native_snmp_trap).
16 * - snmp_trap_v2c() / snmp_inform_v2c() (and the v3 variants) build and send to
17 * a manager over the transport-layer UDP service (port 162 by convention).
18 */
19
20#ifndef DETERMINISTICESPASYNCWEBSERVER_SNMP_NOTIFY_H
21#define DETERMINISTICESPASYNCWEBSERVER_SNMP_NOTIFY_H
22
23#include "ServerConfig.h"
24#include <stddef.h>
25#include <stdint.h>
26
27#if DETWS_ENABLE_SNMP_TRAP
28
29/** @brief Variable-binding value types accepted in a notification. */
30enum class SnmpVbType : uint8_t
31{
32 SNMP_VB_INT = 0, ///< INTEGER (ival)
33 SNMP_VB_STRING = 1, ///< OCTET STRING (bytes/blen)
34 SNMP_VB_OID = 2, ///< OBJECT IDENTIFIER (oid_val/oid_val_len)
35 SNMP_VB_COUNTER32 = 3, ///< Counter32 (ival)
36 SNMP_VB_GAUGE32 = 4, ///< Gauge32 (ival)
37 SNMP_VB_TIMETICKS = 5, ///< TimeTicks (ival)
38 SNMP_VB_IPADDR = 6, ///< IpAddress (bytes, 4 octets)
39};
40
41/** @brief One caller-supplied variable-binding (OID + typed value). */
42struct SnmpVarbind
43{
44 const uint32_t *oid; ///< binding OID arcs
45 size_t oid_len; ///< number of arcs
46 uint8_t type; ///< SnmpVbType
47 long ival; ///< INTEGER / Counter32 / Gauge32 / TimeTicks
48 const uint8_t *bytes; ///< OCTET STRING / IpAddress bytes
49 size_t blen; ///< byte length
50 const uint32_t *oid_val; ///< OID-valued binding arcs
51 size_t oid_val_len; ///< OID-valued arc count
52};
53
54// ---------------------------------------------------------------------------
55// Pure builder (host-testable; no sockets)
56// ---------------------------------------------------------------------------
57
58/**
59 * @brief Build an SNMPv2c notification message (Trap or InformRequest).
60 *
61 * Emits `SEQUENCE { version(1), community, [pdu_tag] { request-id, 0, 0,
62 * varbinds } }` where the varbinds begin with `sysUpTime.0` = @p uptime_ticks and
63 * `snmpTrapOID.0` = @p trap_oid, followed by the @p n caller @p vbs.
64 *
65 * @param pdu_tag SnmpTag::SNMP_PDU_TRAPV2 (0xA7) for a trap, 0xA6 for an InformRequest.
66 * @return total message length, or 0 if it would not fit @p cap.
67 */
68size_t snmp_notify_build_v2c(uint8_t *out, size_t cap, const char *community, uint8_t pdu_tag, uint32_t request_id,
69 const uint32_t *trap_oid, size_t trap_oid_len, uint32_t uptime_ticks,
70 const SnmpVarbind *vbs, size_t n);
71
72struct BerEnc; // (snmp_ber.h)
73
74/**
75 * @brief Append a notification PDU (request-id, 0, 0, varbinds) under @p pdu_tag
76 * to an open encoder; the varbinds begin with sysUpTime.0 + snmpTrapOID.0.
77 *
78 * Used by snmp_notify_build_v2c() and by the SNMPv3 notifier, which wraps this
79 * PDU in a scopedPDU. @return the encoder's running length.
80 */
81size_t snmp_notify_build_pdu(BerEnc *e, uint8_t pdu_tag, uint32_t request_id, const uint32_t *trap_oid,
82 size_t trap_oid_len, uint32_t uptime_ticks, const SnmpVarbind *vbs, size_t n);
83
84// ---------------------------------------------------------------------------
85// Transport (ESP32 only; returns false on a host build)
86// ---------------------------------------------------------------------------
87
88/**
89 * @brief Send an SNMPv2c Trap to @p dst_ip:@p port (sysUpTime.0 is taken from millis()).
90 * @return true if the datagram was queued.
91 */
92bool snmp_trap_v2c(const char *dst_ip, uint16_t port, const char *community, const uint32_t *trap_oid,
93 size_t trap_oid_len, const SnmpVarbind *vbs, size_t n);
94
95/**
96 * @brief Send an SNMPv2c InformRequest to @p dst_ip:@p port.
97 *
98 * Fire-and-forget at this layer (the manager's Response is not awaited or
99 * retransmitted); @p request_id lets the caller match a Response if it listens.
100 * @return true if the datagram was queued.
101 */
102bool snmp_inform_v2c(const char *dst_ip, uint16_t port, const char *community, uint32_t request_id,
103 const uint32_t *trap_oid, size_t trap_oid_len, const SnmpVarbind *vbs, size_t n);
104
105#if DETWS_ENABLE_SNMP_V3
106/**
107 * @brief Send an SNMPv3 USM Trap (authPriv) using the configured engine + user.
108 *
109 * Builds an authenticated (and, if a privacy password is set, encrypted) v3
110 * notification from the engine ID and localized keys configured via
111 * snmp_v3_init() / snmp_v3_set_user(). @return true if the datagram was queued.
112 */
113bool snmp_trap_v3(const char *dst_ip, uint16_t port, const uint32_t *trap_oid, size_t trap_oid_len,
114 const SnmpVarbind *vbs, size_t n);
115
116/**
117 * @brief Send an SNMPv3 USM InformRequest (authPriv) - the confirmed counterpart
118 * to snmp_trap_v3(), symmetric with snmp_inform_v2c().
119 *
120 * Builds an authenticated (and, if a privacy password is set, encrypted) v3
121 * InformRequest. @p request_id is echoed by the receiver in its Response; the
122 * caller owns it and, for confirmed delivery, retransmits until that Response
123 * arrives. @return true if the datagram was queued.
124 */
125bool snmp_inform_v3(const char *dst_ip, uint16_t port, uint32_t request_id, const uint32_t *trap_oid,
126 size_t trap_oid_len, const SnmpVarbind *vbs, size_t n);
127#endif
128
129#endif // DETWS_ENABLE_SNMP_TRAP
130
131#endif // DETERMINISTICESPASYNCWEBSERVER_SNMP_NOTIFY_H
User-facing configuration for DeterministicESPAsyncWebServer.