Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[BUG] Unable to set 64 bit integer on 32 bit ARM device #177

Open
oschwartz10612 opened this issue Sep 7, 2022 · 10 comments
Open

[BUG] Unable to set 64 bit integer on 32 bit ARM device #177

oschwartz10612 opened this issue Sep 7, 2022 · 10 comments
Labels

Comments

@oschwartz10612
Copy link

oschwartz10612 commented Sep 7, 2022

EasySNMP release version: 0.2.6

Operating System and Version

  • OS: Ubuntu hirsute-20211107 Docker container
  • Python 3.7

Net-SNMP Library Version

  • 5

Describe the bug
When running a set command on an integer larger than 32 bits, it gets truncated to 2147483647 and sent on 32 bit devices. For example I have a ARM device running easysnmp and when I try to set 4294967295, the manager receives 2147483647. When I try this on my x86_64 desktop it works fine and sets the value as expected.

I suspect this is a 32 bit int problem with the net-snmp wrapper but I dont know for sure. I have only tested this with snmp v1.

To Reproduce
Steps to reproduce the behavior:
On an arm32 (Raspberry Pi) device create a snmp session and run the following command: session.set(oid="1.3.6.1.4.1.1206.4.2.6.3.3.2.1.4.1", value="4294967295", snmp_type="INTEGER")

Expected behavior
The correct integer should be sent.

@oschwartz10612
Copy link
Author

If someone can point me to where this might be triggered in the wrapper I can take a look at fixing it.

@carlkidcrypto
Copy link
Contributor

@oschwartz10612 Just out of curiosity does it work on V0.2.6 ?: https://github.com/easysnmp/easysnmp/releases/tag/0.2.6
What python version are you running?

I would expect what you are doing to work. Maybe something to do with the net-snmp compiled for your arm32 arch...
what OS does your x86_64 system run?

@oschwartz10612
Copy link
Author

Thanks for the response.

Forgive me, I am using 0.2.6; I forgot to put that in the post. It does not work on 0.2.6. I am using Python 3.7.On x86_64 it is Pop_OS!. This is running in an Ubuntu hirsute-20211107 Docker container using the libsnmp-dev straight from apt-get.

I am happy to do more testing, but you might need to point me in the right direction about what I should be changing. I can test newer versions of Ubuntu that might have a more updated net-snmp. Admittedly, this is a obscure armv7 device, but with docker this should not matter.

@kamakazikamikaze

This comment was marked as outdated.

@kamakazikamikaze

This comment was marked as outdated.

@kamakazikamikaze
Copy link
Collaborator

I did some local testing on a 64-bit Ubuntu 20.04 system using the command-line snmpget and snmpset tools. Here are the results when trying to send the value you provided:

$ snmpset -v2c -c public -m ALL localhost:11161 nsCacheTimeout.1.3.6.1.2.1.2.2 i 4294967295
    NET-SNMP-AGENT-MIB::nsCacheTimeout.1.3.6.1.2.1.2.2 = INTEGER: 4294967295
$ snmpget -v2c -c public -m ALL localhost:11161 nsCacheTimeout.1.3.6.1.2.1.2.2
    NET-SNMP-AGENT-MIB::nsCacheTimeout.1.3.6.1.2.1.2.2 = INTEGER: -1

I should also note the following output when you use other values:

$ snmpset -v2c -c public -m ALL localhost:11161 nsCacheTimeout.1.3.6.1.2.1.2.2 i 4294967296
    truncating integer value > 32 bits
    NET-SNMP-AGENT-MIB::nsCacheTimeout.1.3.6.1.2.1.2.2 = INTEGER: 0

$ snmpset -v2c -c public -m ALL localhost:11161 nsCacheTimeout.1.3.6.1.2.1.2.2 i -1
    Error in packet.
    Reason: wrongVallue (The set value is illegal or unsupported in some way)
    Failed object: NET-SNMP-AGENT-MIB::nsCacheTimeout.1.3.6.1.2.1.2.2

$ snmpset -v2c -c public -m ALL localhost:11161 nsCacheTimeout.1.3.6.1.2.1.2.2 i 2147483648
    NET-SNMP-AGENT-MIB::nsCacheTimeout.1.3.6.1.2.1.2.2 = INTEGER: 2147483648
$ snmpget -v2c -c public -m ALL localhost:11161 nsCacheTimeout.1.3.6.1.2.1.2.2
    NET-SNMP-AGENT-MIB::nsCacheTimeout.1.3.6.1.2.1.2.2 = INTEGER: -2147483648

The behavior of snmpset/snmpget show that sending a 64-bit value should be truncated first by the sending software, which we do not appear to be doing. But since Net-SNMP is essentially treating INTEGER as a uint32_t, our output behavior is pretty much spot-on with theirs.

However, what you experience with your value being truncated to 32-bits causes a difference in output. Instead of reading it as -1, it gets rolled down to 2147483647, which is not the same. I would not care if we were truncating values to 32-bit (to be compliant with RFC 2578) if it was at least consistent and correct, but this divergence from Net-SNMP will cause headaches for some.

(As a side note, the ever-ambiguous long int is being used here which is 32-bit on x86, 64-bit on x64, and 32-bit on ARM, which may come to bite us again in the future.)

I would still like to see what the output is from a 32-bit version of snmpset to compare the behavior, but for now we may look into our own codebase. I believe the following to be the source of inconsistency:

easysnmp/easysnmp/interface.c

Lines 3990 to 3995 in d014177

memset(tmp_val_str, 0, sizeof(tmp_val_str));
if (tmplen >= (long int)sizeof(tmp_val_str))
{
tmplen = sizeof(tmp_val_str) - 1;
}
memcpy(tmp_val_str, val, tmplen);

Since the value is out of bounds, the code appears to cap it instead of letting it overflow. I believe the best approach would be to allow the overflow for INTEGER and not for Counter, Timeticks, and Gauge. I'll need some time to test and think about it.

@oschwartz10612
Copy link
Author

This makes a lot of sense. Thanks for looking into it.

I am sorry I got caught up today and couldn't get any testing done. I will do it tomorrow and let you know what I find.

@carlkidcrypto
Copy link
Contributor

This makes a lot of sense. Thanks for looking into it.

I am sorry I got caught up today and couldn't get any testing done. I will do it tomorrow and let you know what I find.

@oschwartz10612 Just following up on this. Were you able to do the testing that @kamakazikamikaze mentioned?

@oschwartz10612
Copy link
Author

oschwartz10612 commented Nov 15, 2022

Shoot! Sorry; I got caught up and totally forgot to work on this. I will test this first thing tomorrow morning my time and get back to you! Thanks for pinging me.

@oschwartz10612
Copy link
Author

oschwartz10612 commented Nov 15, 2022

Okay, sorry for the delay. @kamakazikamikaze after testing snmpset/get on the ARM device:

snmpget -v1 -c public 127.0.0.1:5005 1.3.6.1.4.1.1206.4.2.6.3.3.2.1.4.1
iso.3.6.1.4.1.1206.4.2.6.3.3.2.1.4.1 = INTEGER: 0

snmpset -v1 -c public 127.0.0.1:5005 1.3.6.1.4.1.1206.4.2.6.3.3.2.1.4.1 i 4294967295
iso.3.6.1.4.1.1206.4.2.6.3.3.2.1.4.1 = INTEGER: 2147483647

snmpget -v1 -c public 127.0.0.1:5005 1.3.6.1.4.1.1206.4.2.6.3.3.2.1.4.1
iso.3.6.1.4.1.1206.4.2.6.3.3.2.1.4.1 = INTEGER: 2147483647

On 64 bit system:

snmpset -v1 -c public 192.168.1.153:5005 1.3.6.1.4.1.1206.4.2.6.3.3.2.1.4.1 i 4294967295
iso.3.6.1.4.1.1206.4.2.6.3.3.2.1.4.1 = INTEGER: 4294967295

snmpget -v1 -c public 192.168.1.153:5005 1.3.6.1.4.1.1206.4.2.6.3.3.2.1.4.1
iso.3.6.1.4.1.1206.4.2.6.3.3.2.1.4.1 = INTEGER: 4294967295

It looks like similar behavior to easysnmp which is interesting. What would you say is the next step?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

3 participants