We recently made the transition from 32 bits to 64 bits, and I find that
under 64 bits, I can no longer snmpwalk our MIBs. I get lots of this in
the log when I try:
snmpd err send response: Error building ASN.1 representation (build int
size 4: s/b 8)
Looking at our code, I see that for rows in the MIB that are of type
INTEGER, we appropriately define fields in structs of type int. Then,
when we process an snmpget, we construct the variable with code like this:
[in some .h file]
int fred;
[actual code]
snmp_set_var_typed_value(var, ASN_INTEGER,
(u_char *) &fred,
sizeof(fred));
But later, deep in the net-snmp code, at the top of the routine
asn_build_int(), we fail this sanity test:
if (intsize != sizeof(long)) {
_asn_size_err(errpre, intsize, sizeof(long));
return NULL;
}
Now unless I am misunderstanding something, (and I hope I am) the
intsize here is the sizeof(fred) I passed into snmp_set_var_typed_value,
and in both 32 bit and 64 bit environments, that's 4 bytes (i.e.
sizeof(int)). But while under 32 bits, sizeof(long) is also 4, under 64
bits, sizeof(long) is 8 bytes. So under 64 bits, the sanity test in
asn_build_int() will always fail, and I see the error messages in my log
and my snmpwalk times out.
INTEGER is 4 bytes, now and forever, right? The ASN.1 protocol doesn't
change just because the underlying machine architecture changes. So
surely I should use a (4 byte) int in my internal structs to hold values
that are declared as INTEGER in the MIB files. But the code seems to
insist that I use longs, and pass them into snmp_set_var_typed_value()
as such. Is this so? If so, why? Please tell me I'm missing something
basic here. We have lots of incumbent structs with the INTEGERs defined
to be ints, not longs.
-John Gregg
------------------------------------------------------------------------------
This SF.net email is sponsored by Sprint
What will you do first with EVO, the first 4G phone?
Visit sprint.com/first -- http://p.sf.net/sfu/sprint-com-first
_______________________________________________
Net-snmp-coders mailing list
Net-snm...@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/net-snmp-coders
Just change those longs to int32_t.
JG> INTEGER is 4 bytes, now and forever, right? The ASN.1 protocol doesn't
JG> change just because the underlying machine architecture changes.
Yep, but long is used almost everywhere in the code, and a decision was made
not to try and change them to a 32bit type. There are probably many many more
32/64 bit issues in that release, waiting to byte you. (sorry, couldn't
resist!)
Robert
So my question really remains: what is the normal, expected way to deal
with this? How do most people compile net-snmp on 64 bit systems? Do
they simply use longs (rather than ints, as we did) internally in all
their structs to hold values that are ultimately declared to be INTEGER
in all the MIB files? As hard as it would be to perform surgery on the
net-snmp code, it would be about as bad to convert all our application
level structs in this way. As I said (and it sounds like you agree) it
looks like this issue is just as alive with the current code as it is
with the old release I'm working with.
I'm still holding out hope that my whole take on this situation is
wrong, and there is a simple way to deal with this. Surely other systems
using net-snmp who store their INTEGERs as int have cut over to 64 bits?
-John Gregg
No, just in that one place to fix the error you currently face.
JG> So my question really remains: what is the normal, expected way to deal
JG> with this?
Upgrade to a more recent release. :-)
JG> As hard as it would be to perform surgery on the
JG> net-snmp code, it would be about as bad to convert all our application
JG> level structs in this way. As I said (and it sounds like you agree) it
JG> looks like this issue is just as alive with the current code as it is
JG> with the old release I'm working with.
I suggest just letting the compiler do the conversion where it will, and use
temporary variables where it won't. For the most part, the compiler will
handle it for you.
Neither option seems elegant. Am I correct that everyone must do one of
these, that net-snmp, even in its most recent version, forbids calling
snmp_set_var_value() and snmp_set_var_typed_value() with INTEGERS given
as 32 bits, if compiled for a 64-bit machine? You must use longs for
INTEGERs in your internal structs, even when INTEGER is defined to be 32
bits and a long is 64 bits? This seems implausible to me, but true
nevertheless. If I have to, I'll go with my dumb little wrapper idea,
but I still hope I'm missing something.
-John Gregg