12#if PC_ENABLE_SNMP_TRAP
22static const uint32_t OID_SYSUPTIME_0[] = {1, 3, 6, 1, 2, 1, 1, 3, 0};
23static const uint32_t OID_SNMPTRAPOID_0[] = {1, 3, 6, 1, 6, 3, 1, 1, 4, 1, 0};
26static void put_varbind(BerEnc *e,
const SnmpVarbind *vb)
28 size_t t = pc_ber_seq_begin(e, (uint8_t)SnmpTag::BER_SEQUENCE);
29 pc_ber_put_oid(e, vb->oid, vb->oid_len);
32 case (uint8_t)SnmpVbType::SNMP_VB_INT:
33 pc_ber_put_integer(e, vb->ival);
35 case (uint8_t)SnmpVbType::SNMP_VB_STRING:
36 pc_ber_put_octet_string(e, (uint8_t)SnmpTag::BER_OCTET_STRING, vb->bytes, vb->blen);
38 case (uint8_t)SnmpVbType::SNMP_VB_OID:
39 pc_ber_put_oid(e, vb->oid_val, vb->oid_val_len);
41 case (uint8_t)SnmpVbType::SNMP_VB_COUNTER32:
42 pc_ber_put_uint(e, (uint8_t)SnmpTag::SNMP_COUNTER32, (uint32_t)vb->ival);
44 case (uint8_t)SnmpVbType::SNMP_VB_GAUGE32:
45 pc_ber_put_uint(e, (uint8_t)SnmpTag::SNMP_GAUGE32, (uint32_t)vb->ival);
47 case (uint8_t)SnmpVbType::SNMP_VB_TIMETICKS:
48 pc_ber_put_uint(e, (uint8_t)SnmpTag::SNMP_TIMETICKS, (uint32_t)vb->ival);
50 case (uint8_t)SnmpVbType::SNMP_VB_IPADDR:
51 pc_ber_put_octet_string(e, (uint8_t)SnmpTag::SNMP_IPADDRESS, vb->bytes, vb->blen);
63size_t pc_snmp_notify_build_pdu(BerEnc *e, uint8_t pdu_tag, uint32_t request_id,
const uint32_t *trap_oid,
64 size_t trap_oid_len, uint32_t uptime_ticks,
const SnmpVarbind *vbs,
size_t n)
66 size_t pdu = pc_ber_seq_begin(e, pdu_tag);
67 pc_ber_put_integer(e, (
long)request_id);
68 pc_ber_put_integer(e, 0);
69 pc_ber_put_integer(e, 0);
70 size_t vbl = pc_ber_seq_begin(e, (uint8_t)SnmpTag::BER_SEQUENCE);
73 size_t t = pc_ber_seq_begin(e, (uint8_t)SnmpTag::BER_SEQUENCE);
74 pc_ber_put_oid(e, OID_SYSUPTIME_0,
sizeof(OID_SYSUPTIME_0) /
sizeof(uint32_t));
75 pc_ber_put_uint(e, (uint8_t)SnmpTag::SNMP_TIMETICKS, uptime_ticks);
80 size_t t = pc_ber_seq_begin(e, (uint8_t)SnmpTag::BER_SEQUENCE);
81 pc_ber_put_oid(e, OID_SNMPTRAPOID_0,
sizeof(OID_SNMPTRAPOID_0) /
sizeof(uint32_t));
82 pc_ber_put_oid(e, trap_oid, trap_oid_len);
85 for (
size_t i = 0; i < n; i++)
87 put_varbind(e, &vbs[i]);
89 pc_ber_seq_end(e, vbl);
90 pc_ber_seq_end(e, pdu);
94size_t pc_snmp_notify_build_v2c(uint8_t *out,
size_t cap,
const char *community, uint8_t pdu_tag, uint32_t request_id,
95 const uint32_t *trap_oid,
size_t trap_oid_len, uint32_t uptime_ticks,
96 const SnmpVarbind *vbs,
size_t n)
98 if (!out || !community || !trap_oid)
103 pc_ber_enc_init(&e, out, cap);
104 size_t msg = pc_ber_seq_begin(&e, (uint8_t)SnmpTag::BER_SEQUENCE);
105 pc_ber_put_integer(&e, 1);
106 pc_ber_put_octet_string(&e, (uint8_t)SnmpTag::BER_OCTET_STRING, (
const uint8_t *)community,
108 pc_snmp_notify_build_pdu(&e, pdu_tag, request_id, trap_oid, trap_oid_len, uptime_ticks, vbs, n);
109 pc_ber_seq_end(&e, msg);
110 return e.ok ? e.len : 0;
124 uint32_t trap_reqid = 1;
126SnmpNotifyCtx s_notify;
129bool pc_snmp_trap_v2c(
const char *dst_ip, uint16_t port,
const char *community,
const uint32_t *trap_oid,
130 size_t trap_oid_len,
const SnmpVarbind *vbs,
size_t n)
133 uint32_t up = (uint32_t)(millis() / 10);
134 size_t len = pc_snmp_notify_build_v2c(buf,
sizeof(buf), community, (uint8_t)SnmpTag::SNMP_PDU_TRAPV2,
135 s_notify.trap_reqid++, trap_oid, trap_oid_len, up, vbs, n);
139bool pc_snmp_inform_v2c(
const char *dst_ip, uint16_t port,
const char *community, uint32_t request_id,
140 const uint32_t *trap_oid,
size_t trap_oid_len,
const SnmpVarbind *vbs,
size_t n)
143 uint32_t up = (uint32_t)(millis() / 10);
144 size_t len = pc_snmp_notify_build_v2c(buf,
sizeof(buf), community, 0xA6 , request_id, trap_oid,
145 trap_oid_len, up, vbs, n);
151bool pc_snmp_trap_v2c(
const char *, uint16_t,
const char *,
const uint32_t *,
size_t,
const SnmpVarbind *,
size_t)
155bool pc_snmp_inform_v2c(
const char *, uint16_t,
const char *, uint32_t,
const uint32_t *,
size_t,
const SnmpVarbind *,
#define PC_SNMP_TRAP_BUF_SIZE
Static datagram buffer for an outbound SNMP notification, bytes.
#define SNMP_COMMUNITY_MAX
Maximum SNMP community-string length (including null terminator).
bool pc_udp_sendto(const char *dst_ip, uint16_t dst_port, const uint8_t *data, size_t len)
Send a UDP datagram to an arbitrary destination (outbound client).
Layer 4 (Transport) - connectionless UDP datagram service.