Go Down

### Topic: SNMP BER question (Read 2410 times)previous topic - next topic

#### CharlesLinquist

##### Mar 06, 2011, 05:10 am
I realize I'm asking a lot, but I am writing an SNMP agent for a different processor (not Arduino), so I wouldn't be surprised if I get kicked out, but I DO use Arduino sometimes.

I'm confused about the BER rules for the various data types.  Could someone  please help me? I don't know where else to turn.

As I understand it -

If I send an integer that is 0x7F or smaller, I send one byte.
If it is 0x80, I would send two bytes, the first being 0x00, the second would be 0x80.
If it is 0xFF, I would send two bytes, the first being 0x00, the second being 0xFF.
If I want to send 0x7FFF, I would send two bytes, the first being 0x7F, the second 0xFF.
If I want to send 0x8000,I would send three bytes, the first being 0x00, the second 0x80, and the third 0x00

Is this correct?  If not, what is the answer?

And are timer ticks encoded in the same manner?

#### PaulS

#1
##### Mar 06, 2011, 02:48 pm
On the Arduino, a byte is 8 bits. It can hold a value from 0 to 255 (0x00 to 0xFF).

Quote
If I send an integer that is 0x7F or smaller, I send one byte.

Yes.

Quote
If it is 0x80, I would send two bytes, the first being 0x00, the second would be 0x80.

No.

Quote
If it is 0xFF, I would send two bytes, the first being 0x00, the second being 0xFF.

No.

An int is 4 bytes. It can hold a value from -32767 to 32767. An unsigned int is 4 bytes, and can hold a value from 0 to 65535 (0x0000 to 0xFFFF).

Quote
If I want to send 0x7FFF, I would send two bytes, the first being 0x7F, the second 0xFF.

Yes.

Quote
If I want to send 0x8000,I would send three bytes, the first being 0x00, the second 0x80, and the third 0x00

No.

#### CharlesLinquist

#2
##### Mar 06, 2011, 03:15 pm
I understand the relationship between Bytes, Words, and Longs.  But those rules do not apply to SNMP.

Check out

http://luca.ntop.org/Teaching/Appunti/asn1.html

And note that the rules apply no matter what processor you are using - AVR or Apple A5 or Intel.  They are part of the SNMP protocol.

I can't understand this well enough to find the answer myself.  I was hoping one of the people on the Agentuino project could

#### gardner

#3
##### Mar 08, 2011, 11:42 pm
There are way better places to find guidance on ASN.1 and BER.  Than in Arduino forums.  Google for one.

In BER, integers are (typically) encoded as:

Tag 0x02
Length (one octet)
Integer value (some number of octets).
The value is encoded MSB first.

Generally the minimum number of octets should be used, though I have seen working implementations that just always use the number of octets in their machine word.

Some examples:

Integer
Code: [Select]
`value BER encoding0 02 01 00127 02 01 7F128 02 02 00 80256 02 02 01 00-128 02 01 80-129 02 02 FF 7F`

#### CharlesLinquist

#4
##### Mar 09, 2011, 12:47 pm
I agree, and I saw the scheme you posted above, but it doesn't seem to work for timer ticks.

Desperate people start looking everywhere there could possibly be help.

#### punk

#5
##### Mar 09, 2011, 11:04 pmLast Edit: Mar 09, 2011, 11:06 pm by punk Reason: 1
from RFC2578

-- hundredths of seconds since an epoch
TimeTicks ::=
[APPLICATION 3]
IMPLICIT INTEGER (0..4294967295)

and length and value are encoded as implicit INTEGER
i.e. MSoctet first, minimal number of octets, two's complement

#### westfw

#6
##### Mar 10, 2011, 03:30 am
Quote
the minimum number of octets should be used,

Really?  Not even the number of octets needed to hold the range defined in the MIB?

Eww!

#### punk

#7
##### Mar 10, 2011, 10:26 am
From ITU-T X.690

Code: [Select]
`8.3        Encoding of an integer value8.3.1      The encoding of an integer value shall be primitive. The contents octets shall consist of one or more octets.8.3.2      If the contents octets of an integer value encoding consist of more than one octet, then the bits of the first octetand bit 8 of the second octet:           a)     shall not all be ones; and           b)     shall not all be zero.                NOTE - These rules ensure that an integer value is always encoded in the smallest possible number of octets.`

#### westfw

#8
##### Mar 10, 2011, 06:55 pm
(I'll just add it to my list of "things I don't like about SNMP.")
((minimizing packet size.  How ... quaint.))

#### gardner

#9
##### Mar 11, 2011, 10:27 pm
This has got me thinking...

From ITU-T X.690
Code: [Select]
` NOTE - These rules ensure that an integer value is always encoded in the smallest possible number of octets.`

I definitely recall something bogus in the specs that allows you to encode things in way more bytes than is actually needed.  I had to look it up....

From ITU-T X.690
Code: [Select]
`8.1.3.3 For the definite form, the length octets shall consist of one or more octets, and shall represent the number ofoctets in the contents octets using either the short form (see 8.1.3.4) or the long form (see 8.1.3.5) as a sender's option.   :8.1.3.5 In the long form, the length octets shall consist of an initial octet and one or more subsequent octets.   :NOTE 2 - In the long form, it is a sender's option whether to use more length octets than the minimum necessary.`

So it is legal to use 2, 3 or 100 octets to describe the length of a 3-octet integer.

Where this is actually of use is where you can carry out a long nested encoding, possibly of a constructed type and correctly determine all the lengths, then go back and update the length octets accordingly.  This only works if you can know in advance how many octets are needed to encode the lengths, and so it is common to leave 2 or 3 octet lengths to then be filled in later.

I thought I had wrung all this garbage from my brain, but it all comes rushing back.  This is why my encoder used a depth-first right-to-left approach, so I never had to go back and adjust length fields -- I could always encode the length near the end, after all the content was encoded.

Go Up