Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

problem with 64 bits: "Error building ASN.1 representation"

585 views
Skip to first unread message

John Gregg

unread,
Jul 19, 2010, 12:03:00 PM7/19/10
to

For historic reasons, the project we are working on is stuck using a
very old version of net-snmp (5.1.2). However, looking at the more
recent code, it looks like the problem I am seeing exists there too.

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

Robert Story

unread,
Jul 19, 2010, 5:39:43 PM7/19/10
to
On Mon, 19 Jul 2010 12:03:00 -0400 John wrote:
JG> But later, deep in the net-snmp code, at the top of the routine
JG> asn_build_int(), we fail this sanity test:
JG>
JG> if (intsize != sizeof(long)) {
JG> _asn_size_err(errpre, intsize, sizeof(long));
JG> return NULL;
JG> }

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

John Gregg

unread,
Jul 19, 2010, 6:04:06 PM7/19/10
to
Thanks. But are you suggesting that I change the longs to int32_t
throughout the baseline net-snmp code, the very exercise that the good
folks at net-snmp thought was too onerous to take on? I'm hesitant to
change that so far untouched code, although I did look into that very
possibility. Problem is, that you of course end up changing lots and
lots of things from long to int32_t far and wide throughout net-snmp.
I'm daunted at the prospect, what with regression testing the whole
library, destabilizing the working (if old) net-snmp, etc.

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

Robert Story

unread,
Jul 21, 2010, 11:59:59 AM7/21/10
to
On Mon, 19 Jul 2010 18:04:06 -0400 John wrote:
JG> Thanks. But are you suggesting that I change the longs to int32_t
JG> throughout the baseline net-snmp code, the very exercise that the good
JG> folks at net-snmp thought was too onerous to take on?

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.

John Gregg

unread,
Jul 21, 2010, 12:11:45 PM7/21/10
to

Looking at the most current net-snmp code, it sure looks like upgrading
will not help me. It looks like net-snmp demands that values defined as
INTEGER in the MIB must be handed into net-snmp (i.e. with
snmp_set_var_value() or snmp_set_var_typed_value()) using a long, i.e.
64 bits in a 64-bit environment. I have many, many variables in
proprietary MIBs that are integers, and so I would have to change them
all. Alternatively, I could write my own dumb little wrapper around
snmp_set_var_value() and snmp_set_var_typed_value() that merely declared
a long temp variable, set it equal to the passed-in int, and called the
underlying net-snmp function with the new long and sizeof(long). Then, I
figure, net-snmp would be happy.

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

0 new messages