SNMP++ Non-Default Port Number Connections

I am attempting to connect to a device that is using a non-standard port number with SNMP (501) using the SNMP++ library. When I create the Snmp object using any port other than 161, I get timeout errors. However, I am still able to use the netsnmp snmp_get using port 501 successfully.

Am I missing something with setting the port number? Does SNMP++ only support port 161?

Thank you!

Hi,

snmp++ does not have any special restrictions on the ports. You could use the snmpNext example to access the device. If SNMPv1 with public community is configured, the command “./snmpNext 1.2.3.4 -P501” should work.

Some more details:

  • When constructing a Snmp object, you should pass “0” as the port number, so a (random) free client port will be used. This is OK for your use case, as this port is used as the source port for the communication to the device.
  • To access a device that listens on port 501 you have to create a SnmpTarget (either CTarget or UTarget) object with a UdpAddress that has been set to the port 501.

You should easily find the relevant code in the snmpNext.cpp example.

Regards,
Jochen

Thank you very much @jkatz! I had missed the port on the CTarget I was using for the connection.

I ended up setting the port to 501 on both the Snmp object and the CTarget object. But it sounds like I really only need to set it in the CTarget? Am I reading that correctly?

Yes, you would only need to set the port on the Snmp object if the source port for outgoing requests of you application shall be set to a specific port.

Regards,
Jochen

Hello again. I have a follow up question now that I’m getting deeper into using this library. I am trying to send a set command, but am struggling to get it correct.

int status;
Snmp snmp = new Snmp(status, 501);  // I have also tried 0 for the port, status indicates success

Snmp_pp::UdpAddress address("<address>");
address.set_port(501);

Snmp_pp::CTarget target_address;
target_address.set_address(address);
target_address.set_readcommunity("public"); 
target_address.set_writecommunity("public");

Snmp_pp::Pdu pdu;
Snmp_pp::Vb vb(<oid>);
vb.set_value(6);  // Also tried using Snmp_pp::SnmpInt32 and casting to int explicitly here

pdu += vb;

int retval = snmp->set(pdu, target_address);

retval indicates SNMP_CLASS_SUCCESS but when I get that same oid the value has not changed. I am able to successfully set this oid when using net-snmp command

snmpset -v1 -c public <address>:501 <oid> i 6

Any tips on what I have missed?

Thank you!

Hi,

for your use case the port passed to the Snmp class constructor does not matter and you should set it to 0, so a random free port is used.

The code looks ok. Do you pass the oid as “1.3…”? You must not use a leading dot in the oid string but a trailing “.0” is needed for scalars.

Did you try the snmpSet example of snmp++? You could also turn on logging to see what snmp++ is doing.

Kind Regards,
Jochen

Thank you for the quick reply @jkatz. I’ve tried with the port as 0 in the constructor as well. I am not using a leading dot in the oid string (however in my gets I am) and it has a trailing .0

I should have logging on and all I’m getting is

20200608.16:42:44: 4658388416: (4)DEBUG  : SNMPMessage: return value for build message: (0)

I haven’t tried the snmpSet example of snmp++ as I’m not familiar with that. Is that a code example or a command line example?

Ah I figured out my issue. I have been using a wrapper class and had copied a get into the set function. :woman_facepalming:t3:

Thanks for your time!

Good that you found the well known copy-paste-error :wink:

In the consoleExamples directory there are small samples. They can be used as a reference and on the command line.

To send a set request for oid “1.3.6” to an agent on port 501 you can use the following command line:
./snmpSet hostname-or-ip 1.3.6 -P501

Kind regards,
Jochen

The well-known, yet elusive, copy-paste-error :slight_smile:

Thanks for pointing me to the examples, I had missed those! I’m also curious, earlier you said that I should not have a leading . in the oid string. I do have those on some of my gets and they seem to be working fine. Why should the sets not have that? (Or should I really not have them at all?)

Thanks!

Hi,

you’re right: the Oid class ignores the leading dot when parsing the oid string (get or set request does not matter). But if you want to be on the safe side, do not use them. I’m pretty sure that a leading dot has caused problems at some time.

Kind regards,
Jochen

Good to know. Thanks again for your time @jkatz!