shortbloke / arduino_snmp_manager Goto Github PK
View Code? Open in Web Editor NEWSNMP Manager for ESP32/ESP8266 and Arduino
License: Other
SNMP Manager for ESP32/ESP8266 and Arduino
License: Other
Add unit test to at least cover the parsing of different packet types in order to avoid missing regressions (again).
Hello and thank you for this very useful library.
I think the word gauge is misspelt in many files as guage
I found it in BER.h, Arduino_SNMP_Manager.h and the three example file.
Hi there,
Thanks for your awesome SNMP library - you asked for people to send in projects they made using it
In combination with this library and your speed indicator, I adapted it to run a Dekatron - 1950s era neon counting tube technology which runs at 450Volts.
The dekatron spins based on the broadband utilisation rate, clockwise/anti-clockwise depending on utilisation.
https://github.com/elegantalchemist/dekatron-speed
A short video with it running a speed test (my SNMP agent isn't very fast so it lags a bit on these quick tests but works nice in real life situations) - https://youtu.be/qNa_jXh9za4
Cheers!
Hello,
Setting snmp version to version 1:
SNMPGet snmpRequest = SNMPGet(community, 0);
still gives version v2c, according to wireshark.
Using example ESP32_ESP8266_SNMP_Manager.ino.
Device I want to control apparently only supports version 1, and that works fine with other software, e.g. with Python.
Any ideas?
Regards,
Rob.
Hi,
I'm trying to walk through OIDs to get the alarms table on ".1.3.6.1.2.1.33.1.6.2".
Do you have any advice to how can I achieve it?
Thanks
I'm trying to read SNMP data from an equipment, using an ESP32 with ETHERNET over LAN8720. Abount 1 in 10 requests that i send is responded and the value is updated correctly, the rest i simple don't know what happens, just the value isn't updated by the callback...
And lastly, every time i get a FAILED TO PARSE response i get a Guru MEditation error (Load Prohibited).
When i measure the stack memory used in the application, and increase dramatically the size of the stack of the task, the error is gone, but the used memory in the stack is increased in more then 10k bytes.
I traced t he stack to the receivedpacket()
function, and, because the string SNMPGETRESPONSE: FAILED TO PARSE is fully printed before the error occurs, i believe that it has something to do with the delete snmpgetresponse;
line right after.
why this funcion is linline, and why to you have to delete the response after?
Hi,
I'm reading snmp information from a network printer, the printers MAC address seems to be stored as unicode characters but as a ASN_STRING. When i read the MAC some of the characters don't come through correctly.
This is the string i get when i do a SNMP walk using a windows software : œ“N¨D�
This is the string i get when using the ESP32 and this library: ⸮⸮N⸮D�
Any idea on how to correct this?
Given I have multiple devices
When I want to query the devices for data on the same OID
Then the data for each device should be correctly returned
Actual result: The value from the reply is written to the first variable that matches the OID. It does not take into a count the IP address of the responder.
Example (simplified - excludes network setup):
#include <ESP8266WiFi.h>
#include <WiFiUdp.h>
#include <Arduino_SNMP_Manager.h>
IPAddress testVM1(192, 168, 200, 187);
IPAddress testVM2(192, 168, 200, 167);
const char *community = "public";
const int snmpVersion = 1; // SNMP Version 1 = 0, SNMP Version 2 = 1
char *oidUptime = ".1.3.6.1.2.1.1.3.0"; // TimeTicks uptime (hundredths of seconds)
int uptimeTestVM1 = 0;
int uptimeTestVM2 = 0;
WiFiUDP udp; // UDP object used to send and recieve packets
SNMPManager snmp = SNMPManager(community); // Starts an SMMPManager to listen to replies to get-requests
SNMPGet snmpRequest1 = SNMPGet(community, snmpVersion); // Starts an SMMPGet instance to send requests
ValueCallback *callbackTestVM1Uptime;
ValueCallback *callbackTestVM2Uptime;
int pollInterval = 10000; // delay in milliseconds
char string[50]; // Maximum length of SNMP get response for String values
unsigned long pollStart = 0;
unsigned long intervalBetweenPolls = 0;
void setup()
{
// .... network setup etc
snmp.setUDP(&udp); // give snmp a pointer to the UDP object
snmp.begin(); // start the SNMP Manager
callbackTestVM1Uptime = snmp.addTimestampHandler(oidUptime, &uptimeTestVM1);
callbackTestVM2Uptime = snmp.addTimestampHandler(oidUptime, &uptimeTestVM2);
}
void loop()
{
// put your main code here, to run repeatedly:
snmp.loop();
intervalBetweenPolls = millis() - pollStart;
if (intervalBetweenPolls >= pollInterval)
{
pollStart += pollInterval; // this prevents drift in the delays
getSNMP();
}
}
void getSNMP()
{
// Build a SNMP get-request add each OID to the request
snmpRequest1.addOIDPointer(callbackTestVM1Uptime);
snmpRequest1.setIP(WiFi.localIP()); //IP of the arduino
snmpRequest1.setUDP(&udp);
snmpRequest1.setRequestID(rand() % 5555);
snmpRequest1.sendTo(testVM1);
snmpRequest1.clearOIDList();
snmpRequest1.addOIDPointer(callbackTestVM2Uptime);
snmpRequest1.setIP(WiFi.localIP()); //IP of the arduino
snmpRequest1.setUDP(&udp);
snmpRequest1.setRequestID(rand() % 5555);
snmpRequest1.sendTo(testVM2);
snmpRequest1.clearOIDList();
// Wait for responses to be sent and replied to.
delay(2000);
Serial.print("UptimeTestVM1: ");
Serial.println(uptimeTestVM1);
Serial.print("UptimeTestVM2: ");
Serial.println(uptimeTestVM2);
Serial.println("----------------------");
}
Hi, I'm trying to get a simple value of a printer snmp, but for some reason the value always returns blank, am I doing the setup wrong?
#if defined(ESP8266)
#include <ESP8266WiFi.h> // ESP8266 Core WiFi Library
#else
#include <WiFi.h> // ESP32 Core WiFi Library
#endif
#include <WiFiUdp.h>
#include <Arduino_SNMP_Manager.h>
//************************************
//* Your WiFi info *
//************************************
const char *ssid = "SSID";
const char *password = "password";
//************************************
//************************************
//* SNMP Device Info *
//************************************
IPAddress printer(192, 168, 0, 116);
const char *community = "public";
const int snmpVersion = 1; // SNMP Version 1 = 0, SNMP Version 2 = 1
// OIDs
const char *oidSysName = ".1.3.6.1.2.1.1.5.0";
//************************************
//************************************
//* Settings *
//************************************
int pollInterval = 10000; // delay in milliseconds
//************************************
//************************************
//* Initialise *
//************************************
// Variables
char sysName[50];
char *sysNameResponse = sysName;
unsigned long pollStart = 0;
unsigned long intervalBetweenPolls = 0;
unsigned int lastInOctets = 0;
// SNMP Objects
WiFiUDP udp; // UDP object used to send and receive packets
SNMPManager snmp = SNMPManager(community); // Starts an SMMPManager to listen to replies to get-requests
SNMPGet snmpRequest = SNMPGet(community, snmpVersion); // Starts an SMMPGet instance to send requests
// Blank callback pointer for each OID
ValueCallback *callbackSysName;
//************************************
//************************************
//* Function declarations *
//************************************
void getSNMP();
void printVariableValues();
//************************************
void setup()
{
Serial.begin(115200);
WiFi.begin(ssid, password);
Serial.println("");
// Wait for connection
while (WiFi.status() != WL_CONNECTED)
{
delay(500);
Serial.print(".");
}
Serial.println("");
Serial.print("Connected to SSID: ");
Serial.println(ssid);
Serial.print("IP address: ");
Serial.println(WiFi.localIP());
snmp.setUDP(&udp); // give snmp a pointer to the UDP object
snmp.begin(); // start the SNMP Manager
// Get callbacks from creating a handler for each of the OID
callbackSysName = snmp.addStringHandler(printer, oidSysName, &sysNameResponse);
}
void loop()
{
// put your main code here, to run repeatedly:
snmp.loop();
intervalBetweenPolls = millis() - pollStart;
if (intervalBetweenPolls >= pollInterval)
{
pollStart += pollInterval; // this prevents drift in the delays
getSNMP();
printVariableValues(); // Print the values to the serial console
}
}
void getSNMP()
{
// Build a SNMP get-request add each OID to the request
snmpRequest.addOIDPointer(callbackSysName);
snmpRequest.setIP(WiFi.localIP()); // IP of the listening MCU
// snmpRequest.setPort(501); // Default is UDP port 161 for SNMP. But can be overriden if necessary.
snmpRequest.setUDP(&udp);
snmpRequest.setRequestID(rand() % 5555);
snmpRequest.sendTo(printer);
snmpRequest.clearOIDList();
}
void printVariableValues()
{
Serial.printf("sysNameResponse: %s\n", sysNameResponse);
Serial.println("----------------------");
}
I'm using Platformio IDE on VScode, SNMP_Manager version 1.1.6(tried with all < versions, same problem)
Added "-Werror=reorder" on build_unflag because was breaking the build on warnings
Do you have any references or observations on making requests from IPs that are external to the network?
I implemented this library and it works perfectly on routers/devices on the local network, but when I enter public IPs it does not return packets at all.
I'm sure of the request because I tested it with other software.
Does anyone know anything about this?
Currently there is no possibility to check if snmp request had been processed. In the examples the call to "uptime" oid is used as sudo check. However many devices are updating this parameter not every 100ms but for instance every 1 second or something like this. And not all devices return this properly anyway.
As I understand the 'callback" classes are not real callbacks because no code is called back upon processing of received packet.
The solution would be to extend the ValueCallback class by "onReceive" field which can be used by the user to store a pointer to function which will be called after snmp request had been fulfilled.
If there is already some method of getting definite information that snmp request had been processed - please let know in a form of an example.
Investigate AsyncUDP to replace looping to check for new UDP packets.
I imagine this is more of a feature request than an issue, please forgive me.
I want to use an esp32 to poll the ifInOctets and ifOutOctets for up to 48 ports on a network switch, so I can control several addressable LED strips in the classroom to show where the network traffic is flowing.
Is there an easier way to create entire ranges of variables and callbacks and oid handlers and so on?
Currently, there is like 20 different locations that I have to create a new mention of each of the oid's I want to poll and process, and I would love to be able to just say "grab all the oid's from .1.3.6.1.2.1.2.2.1.10.1 through 48", but I don't know what I am doing . :(
can someone help us out here?
Regression in 1.1.3. Extra check for packet length was incorrect and unnecessary. Caused valid packets to be reported as corrupt if the length of the SNMP payload was > 127 bytes.
Example error: SNMPGETRESPONSE: FAILED TO PARSE Packet Corrupt. Expected Payload size: 130 - Actual size: 92
I was trying use this library to monitoring a TV Transmisor device, acctualy use a raspberry but I saw this library So I wanted to try using it on an Nodemcu ESP8266, I have adapted the example code to works with mi device, but when the code get in to the line
" snmpRequest.sendTo(my_IP_DEVice);"" I got a message in the serial monitor "wdt reset" I put a picture about this, I hope you see that.
The values that I want to get are type Integer. (posible values of the response are 1~5)
when asking for timestamp the fourth argument to addTimestampHandler should be unsigned int because timestamp is unsigned.
A question on Arduino Stack Exchange: https://arduino.stackexchange.com/questions/90178/snmp-manager-multiple-ip-address-issue
Demonstrates a need for a working example that can query multiple OID on multiple devices and store the data.
Wireshark show me that the "version"-part of the SNMP-block is coded as "02 04 00 00 00 01".
My Cisco router do accept this and in the reply it is sending the version as "02 01 01"
My pfSense does NOT handle the 4-byte version-block - No response. Using the snmpget command from a Raspberry Pi with "correct" one-byte version give positive response from pfSense....
I tried changing line 120 of SNMPGet.h to "packet->addValueToList(new IntegerType(_version));" but no - still a 4-byte integer in the SNMP request...
Any tips ??
Version: 1.1.10
Compiled for an Wemos D1 mini (ESP8266)
On trying to execute some sequential Gets, sometimes this error occurs, i don't know why....
Guru Meditation Error: Core 0 panic'ed (LoadProhibited). Exception was unhandled.
Core 0 register dump:
PC : 0x4008c3a4 PS : 0x00060f30 A0 : 0x800d4089 A1 : 0x3ffd1720
A2 : 0x3ffc23e0 A3 : 0x00000002 A4 : 0x00000032 A5 : 0x3ffc2412
A6 : 0x00000033 A7 : 0x00000003 A8 : 0x3ffc23e0 A9 : 0x00000000
A10 : 0x3ffde5cc A11 : 0x4008904c A12 : 0x3ffbaa28 A13 : 0x00000027
A14 : 0x00000026 A15 : 0x00000030 SAR : 0x00000004 EXCCAUSE: 0x0000001c
EXCVADDR: 0x00000002 LBEG : 0x4008b9b6 LEND : 0x4008b9c1 LCOUNT : 0x00000000
ELF file SHA256: 0000000000000000
Backtrace: 0x4008c3a4:0x3ffd1720 0x400d4086:0x3ffd1740 0x400d4177:0x3ffd1760 0x400d4441:0x3ffd17a0 0x400d47b4:0x3ffd17c0 0x400d4a13:0x3ffd17f0 0x400d4a8e:0x3ffd1850 0x4008e5c6:0x3ffd1870
#0 0x4008c3a4:0x3ffd1720 in strcat at /home/mak/e/p/newlib_old/newlib_xtensa-bin/newlib_xtensa-2.2.0/xtensa-esp32-elf/newlib/libc/string/../../../.././newlib/libc/string/strcat.c:73 (discriminator 1)
#1 0x400d4086:0x3ffd1740 in SNMPManager::findCallback(IPAddress, char const*) at src/power_source_controller.cpp:343
#2 0x400d4177:0x3ffd1760 in SNMPManager::parsePacket() at src/power_source_controller.cpp:343
#3 0x400d4441:0x3ffd17a0 in SNMPManager::receivePacket(int) at src/power_source_controller.cpp:343
(inlined by) SNMPManager::loop() at .pio/libdeps/esp-wrover-kit/SNMP Manager/src/Arduino_SNMP_Manager.h:158
#4 0x400d47b4:0x3ffd17c0 in power::ReadParameterInt(char const*, int*) at src/power_source_controller.cpp:199
#5 0x400d4a13:0x3ffd17f0 in power::ReadAlarms() at src/power_source_controller.cpp:299
#6 0x400d4a8e:0x3ffd1850 in power::PowerSourceReadTask(void*) at src/power_source_controller.cpp:339 (discriminator 1)
#7 0x4008e5c6:0x3ffd1870 in vPortTaskWrapper at /home/runner/work/esp32-arduino-lib-builder/esp32-arduino-lib-builder/esp-idf/components/freertos/port.c:355 (discriminator 1)
I have to read 41 values from a table on the snmp agent device, i decided that it was best to do it sequentially to save memory, and sometimes the CPU resets with this error wich points to SNMPManager::findCallback(IPAddress, char const*). I really don't know why...
Here's the part of the code that reads ONE value:
bool ReadParameterInt(const char *oid, int *out_value)
{
// debug_log::Verbose(F(POWER_SOURCE_LOG_TAG "Starting parameter Read..." CR));
delete int_callback;
*out_value = -1;
int_callback = snmp_manager.addIntegerHandler(power_source_ip, oid, out_value);
request.addOIDPointer(int_callback);
if (eth::connection_data.connected)
{
request.setIP(eth::connection_data.ip); // IP of the listening MCU
request.setUDP(ð::udp);
}
else
{
return false;
}
request.setRequestID(rand() % 5555);
request.sendTo(power_source_ip);
request.clearOIDList();
long start_time = millis();
for (;;)
{
snmp_manager.loop();
if (*out_value != -1)
{
// debug_log::Verbose(F(POWER_SOURCE_LOG_TAG "Success!" CR));
// debug_log::Verbose(F(POWER_SOURCE_LOG_TAG "%d" CR), *out_value);
eth::udp.flush();
return true;
}
if (millis() >= start_time + ReadParamTimeout)
{
debug_log::Warning(F("Timeout Reading Measurement!" CR));
return false;
}
delay(100);
}
}
It runs on a separate task, so i'ts fine to block waiting for the response.
SNMP v2 supports GETBULK in order to request a collection of data without multiple requests. I believe this would also ensure when collecting data it would be for the same time period.
Is it possible to use both agent and manager on the same device?
--- VM1 ---
inOctetsResponseTesVM1: 2463228363
sysNameResponseTestVM1: �Hardware: Intel64 Famil
UptimeTestVM1: 9736309
SysServicesTestVM1: 76
SysDescrTestVM1: �Hardware: Intel64 Famil
case STRING:
{
// Serial.println("Type: String");
memcpy(*((StringCallback *)callback)->value, String(((OctetType *)snmpgetresponse->varBindsCursor->value->value)->_value).c_str(), 25); // FIXME: this is VERY dangerous, I'm assuming the length of the source char*, this needs to change. for some reason strncpy didn't work, need to look into this. the '25' also needs to be defined somewhere so this won't break;
*(*((StringCallback *)callback)->value + 24) = 0x0; // close off the dest string, temporary
OctetType *value = new OctetType(*((StringCallback *)callback)->value);
// Serial.print("Value: "); Serial.println(value->_value);
delete value;
}
I use the "ESP8266 example" and mostly of it works fine except one thing:
I have one oid ".1.3.6.1.2.1.2.2.1.16.30010001", which is not translated correctly. With smtpget (on a pc) I got following bytes in the udp-packet to describe the oid: 06 0d 2b 06 01 02 01 02 02 01 10 8e a7 d5 11 05 00
With the ESP8266 I got: 06 0c 2b 06 01 02 01 02 02 01 10 a7 d5 11 05 00. That means the hex value "8e" is missing by interpretating 30010001 as an oid-part (and length is not 0d but 0c - as one byte is missing). Therefor not the correct oid is used. With the missing byte it's ".1.3.6.1.2.1.2.2.1.16.649873".
I assume - as oid bytes are representing only "7 bit" as a single "number" and the 8th bit is signal to take the next byte as well - the algorithm to calculate the the bytes from the oid value is limited only to 3 bytes.
Thank you in advance for taking care.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.