ProtoCore v0.0.2
Deterministic, zero-heap network stack for embedded targets
Loading...
Searching...
No Matches
snmp_ber.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 pc_snmp_ber.h
6 * @brief Zero-heap ASN.1 BER encoder/decoder for the SNMP agent (PC_ENABLE_SNMP).
7 *
8 * A minimal, bounded TLV codec covering exactly the types SNMP uses: INTEGER,
9 * OCTET STRING, NULL, OBJECT IDENTIFIER, SEQUENCE, and the SNMP application
10 * types (Counter32/Gauge32/TimeTicks/IpAddress/Counter64) and PDU context tags.
11 * Encoder and decoder both operate over caller-provided fixed buffers - no heap.
12 * This is the shared base for SNMP v1/v2c and (later) v3; it is unit-tested on
13 * its own (env:native_snmp) since it needs no lwIP.
14 */
15
16#ifndef PROTOCORE_SNMP_BER_H
17#define PROTOCORE_SNMP_BER_H
18
19#include "protocore_config.h"
20#include <stddef.h>
21#include <stdint.h>
22
23#if PC_ENABLE_SNMP
24
25// ASN.1 / SNMP tags
26enum class SnmpTag : uint8_t
27{
28 BER_INTEGER = 0x02,
29 BER_OCTET_STRING = 0x04,
30 BER_NULL = 0x05,
31 BER_OID = 0x06,
32 BER_SEQUENCE = 0x30,
33 // SNMP application types (RFC 2578)
34 SNMP_IPADDRESS = 0x40,
35 SNMP_COUNTER32 = 0x41,
36 SNMP_GAUGE32 = 0x42,
37 SNMP_TIMETICKS = 0x43,
38 SNMP_OPAQUE = 0x44,
39 SNMP_COUNTER64 = 0x46,
40 // VarBind exception markers (RFC 3416)
41 SNMP_NO_SUCH_OBJECT = 0x80,
42 SNMP_NO_SUCH_INSTANCE = 0x81,
43 SNMP_END_OF_MIB_VIEW = 0x82,
44 // PDU tags (context-specific, constructed)
45 SNMP_PDU_GET = 0xA0,
46 SNMP_PDU_GETNEXT = 0xA1,
47 SNMP_PDU_RESPONSE = 0xA2,
48 SNMP_PDU_SET = 0xA3,
49 SNMP_PDU_GETBULK = 0xA5,
50 SNMP_PDU_TRAPV2 = 0xA7,
51 SNMP_PDU_REPORT = 0xA8,
52};
53
54// ---------------------------------------------------------------------------
55// Encoder - forward writer over a caller buffer. Constructed types reserve a
56// 3-byte long-form length that is back-patched at close (valid BER; accepted by
57// net-snmp etc.), so no buffering or shifting is needed.
58// ---------------------------------------------------------------------------
59struct BerEnc
60{
61 uint8_t *buf;
62 size_t cap;
63 size_t len;
64 bool ok;
65};
66
67void pc_ber_enc_init(BerEnc *e, uint8_t *buf, size_t cap);
68
69bool pc_ber_put_integer(BerEnc *e, long v); ///< INTEGER (signed, minimal)
70bool pc_ber_put_uint(BerEnc *e, uint8_t tag, uint32_t v); ///< non-negative int with @p tag
71bool pc_ber_put_octet_string(BerEnc *e, uint8_t tag, const uint8_t *d,
72 size_t n); ///< OCTET STRING / IpAddress / Opaque
73bool pc_ber_put_null(BerEnc *e); ///< NULL
74bool pc_ber_put_oid(BerEnc *e, const uint32_t *arcs, size_t n); ///< OBJECT IDENTIFIER (n >= 2)
75bool pc_ber_put_tlv(BerEnc *e, uint8_t tag, const uint8_t *val, size_t n); ///< raw primitive TLV
76bool pc_ber_put_raw(BerEnc *e, const uint8_t *bytes, size_t n); ///< append pre-encoded bytes verbatim
77
78size_t pc_ber_seq_begin(BerEnc *e, uint8_t tag); ///< open a constructed type; returns a token
79void pc_ber_seq_end(BerEnc *e, size_t token); ///< close it (back-patch the length)
80
81// ---------------------------------------------------------------------------
82// Decoder - forward reader over a buffer.
83// ---------------------------------------------------------------------------
84struct BerDec
85{
86 const uint8_t *buf;
87 size_t len;
88 size_t pos;
89 bool ok;
90};
91
92void pc_ber_dec_init(BerDec *d, const uint8_t *buf, size_t len);
93
94/** @brief Read a tag + length; on success @p d->pos is left at the value. */
95bool pc_ber_read_header(BerDec *d, uint8_t *tag, size_t *length);
96/** @brief Read an INTEGER into @p out. */
97bool pc_ber_read_integer(BerDec *d, long *out);
98/** @brief Read an OBJECT IDENTIFIER into @p arcs (capacity @p max); count in @p n. */
99bool pc_ber_read_oid(BerDec *d, uint32_t *arcs, size_t max, size_t *n);
100/** @brief Advance the cursor past @p length value bytes. */
101bool pc_ber_skip(BerDec *d, size_t length);
102
103#endif // PC_ENABLE_SNMP
104
105#endif // PROTOCORE_SNMP_BER_H
User-facing configuration for ProtoCore.