patricklaf / SNMP

Simple Network Management Protocol library for Arduino
MIT License
10 stars 1 forks source link

BooleanBER bug #11

Open AliReshadF opened 5 days ago

AliReshadF commented 5 days ago

Hello In my code there is a section for sending 3 different kinds of message for sending to a received message (This code has been inspired form Agent example).

`

include

include

include

include

// Enter a MAC address and IP address for your controller below.The IP address will be dependent on your local network: byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED }; IPAddress ip(192, 168, 11, 177); EthernetUDP udp; SNMP::Agent snmp;

const char SYSNAME_OID1 = "1.3.6.1.2.1.1.5.0"; const char SYSNAME_VALUE1 = "ESP32 DEV KIT V1"; // Name of the board. Replace if needed.

const char *SYSNAME_OID2 = "1.3.6.1.2.1.1.5.1";

const char *SYSNAME_OID3 = "1.3.6.1.2.1.1.5.2";

const char *SYSNAME_OID4 = "1.3.6.1.2.1.1.5.3";

// Use some SNMP classes using SNMP::OctetStringBER; using SNMP::BooleanBER; using SNMP::IntegerBER; using SNMP::VarBind; using SNMP::VarBindList;

// Event handler to process SNMP messages void onMessage(const SNMP::Message message, const IPAddress remote, const uint16_t port) { int a =54; bool b = false; // Get the variable binding list from the message. VarBindList varbindlist = message->getVarBindList(); for (unsigned int index = 0; index < varbindlist->count(); ++index) { // Each variable binding is a sequence of 2 objects: // - First one is and ObjectIdentifierBER. It holds the OID // - Second is the value of any type VarBind varbind = (varbindlist)[index]; // There is a convenient function to get the OID as a const char const char name = varbind->getName(); if (strcmp(SYSNAME_OID1, name) == 0) { // System name is requested. We have to send a response. // Create an SNMP message for response SNMP::Message response = new SNMP::Message(SNMP::VERSION2C, "public", SNMP::TYPE_GETRESPONSE); // The response must have the same request-id as the request response->setRequestID(message->getRequestID()); // SYSNAME // Create an OctetStringBER to hold the variable binding value OctetStringBER value1 = new OctetStringBER(SYSNAME_VALUE1); IntegerBER value2 = new IntegerBER(a); BooleanBER value3 = new BooleanBER(b); // Add the variable binding to the message response->add(SYSNAME_OID1, value1); response->add(SYSNAME_OID2, value2); response->add(SYSNAME_OID3, value3); // Send the response to remote IP and port snmp.send(response, remote, port); // Avoid memory leak delete response; } } } EthernetServer server(80);

void setup() { Ethernet.init(15); SPI.begin(14,12,13,15); Serial.begin(115200); Ethernet.begin(mac); // Check for Ethernet hardware present if (Ethernet.hardwareStatus() == EthernetNoHardware) { Serial.println("Ethernet shield was not found. Sorry, can't run without hardware. :("); while (true) { delay(1); // do nothing, no point running without Ethernet hardware } } if (Ethernet.linkStatus() == LinkOFF) { Serial.println("Ethernet cable is not connected."); }

// Start UDP server.begin(); Serial.println(Ethernet.localIP()); udp.begin(161); // SNMP snmp.begin(&udp); snmp.onMessage(onMessage); }

void loop() { // Agent loop function must be called to process incoming messages snmp.loop(); } `

The problem is when I send a GET SNMP request by NETworkManager , I can't receive any response. Here is my result in Wireshark: Untitled The red rectangular indicates (probably) there is something wrong about type indicator. I would greatly appreciate any help with this issue. Thank you in advance!

More information about code : Development board = ESP 32 Devkit V1 IDE = Platform IO

patricklaf commented 4 days ago

Hello @AliReshadF ,

I compiled your code and I have the same result:

image

The request is done with snmp-get:

snmpget -v 2c -c public 192.168.2.2 SNMPv2-MIB::sysName.0 -r0 -d

This is the output of the command:

Sending 43 bytes to UDP: [192.168.2.2]:161->[0.0.0.0]:58346
0000: 30 29 02 01  01 04 06 70  75 62 6C 69  63 A0 1C 02    0).....public...
0016: 04 6C 72 5A  34 02 01 00  02 01 00 30  0E 30 0C 06    .lrZ4......0.0..
0032: 08 2B 06 01  02 01 01 05  00 05 00                    .+.........

Received 89 byte packet from UDP: [192.168.2.2]:161->[0.0.0.0]:58346
0000: 30 57 02 01  01 04 06 70  75 62 6C 69  63 A2 4A 02    0W.....public.J.
0016: 04 6C 72 5A  34 02 01 00  02 01 00 30  3C 30 1C 06    .lrZ4......0<0..
0032: 08 2B 06 01  02 01 01 05  00 04 10 45  53 50 33 32    .+.........ESP32
0048: 20 44 45 56  20 4B 49 54  20 56 31 30  0D 06 08 2B     DEV KIT V10...+
0064: 06 01 02 01  01 05 01 02  01 36 30 0D  06 08 2B 06    .........60...+.
0080: 01 02 01 01  05 02 01 01  00                          .........

bad type returned (1)
Timeout: No Response from 192.168.2.2.

SNMP uses SMI, a subset of ASN.1 and the type BOOLEAN type is not part of SMI (see RFC 2578). That's why Wireshark shows it as Unknown and snmp-get tells bad type returned (1). The timeout is questionnable because in fact, the command succeeded.

It is part of the library because some MIBs use it as you can see from examples.

I don't know what tool is NETworkManager and why it doesn't get any response.

Best regards, Patrick