# [mrtg] Re: Conversion code for hex to integer

Dan Lynch dan.lynch at placer.ca.gov
Tue Oct 26 23:50:29 MEST 2004

```Well that was a learning experience. Here's what I've found (code follows):

-- Yep, "shift" is correct as what's passed by the main MRTG PERL routine into my sub is an array. Shift returns the first value from that array, which is the value returned by the SNMP device under query.

-- What is returned by SNMP needs to be unpacked from binary to hex.

-- In the result, no separators are included, only a string of hex characters IN REVERSE WORD ORDER! An independent monitoring tool also displays these values, and while that tool shows the integer value <78187493530>, SNMP returns hex <9a78563412>. But my integer value in hex is <123456789a>.

So here's what I ended up with. Let me know if there's a more efficient way.

# Return an integer for a hex value
sub hextoint {
my \$value = shift;
\$value=unpack ('H*', \$value);
my \$new = join( '', substr(\$value,-2,1), substr(\$value,-1,1) );
\$new = join( '', \$new, substr(\$value,-4,1), substr(\$value,-3,1) );
\$new = join( '', \$new, substr(\$value,-6,1), substr(\$value,-5,1) );
\$new = join( '', \$new, substr(\$value,-8,1), substr(\$value,-7,1) );
\$new = join( '', \$new, substr(\$value,-10,1), substr(\$value,-9,1) );
my \$val2=hex(\$new);
return \$val2;
}

Now with that, the correct values are returned and I'm able to graph Novell BorderManager's HTTP proxy cache hit and miss volume. I've learned to ignore the errors returned every single time:
Integer overflow in hexadecimal number at (eval 6) line 26.
Hexadecimal number > 0xffffffff non-portable at (eval 6) line 26.

I also had to devise this sanity check for the values, as the host will frequently return just plain stoopid data. This is the best I could come up with on the spur of the moment:

if (length (\$value) < 4) {
return 0;
}

Thanks to O'Reilly's PERL in a Nutshell, Learning PERL, and PERL Cookbook, and Rex Swain's HTMLified PERL 5 Reference Guide.

Dan Lynch, CISSP
Information Technology Analyst
County of Placer
Auburn, CA

>>> "Dan Lynch" <dan.lynch at placer.ca.gov> 10/20/04 11:03AM >>>
Good suggestions (thanks Bill and Takumi), but I wonder what the values passed into my sub by MRTG are. When I capture the data with TCPdump, there doesn't seem to be dots encoded between values, only the hex itself. As in,

0405D6DC20DE0D

When read by an interpreter like Ethereal, or an SNMP MIB browser application, the 0405 prefix is stripped off, and dots inserted:

D6.DC.20.DE.0D

But in my PERL subroutine, the values look nothing like these examples. Here's my code right now:

# Return an integer for a hex value
open (STDERR, ">>error.txt");
sub hextoint {
my \$value = shift;
print STDERR \$value,"\n";
\$value =~ y/\.//d;
print STDERR \$value,"\n";
\$value = hex (\$value);
print STDERR \$value,"\n";
return \$value;
}

And a recent output into error.txt:

B**
B**
Illegal hexadecimal digit '****** ' ignored at (eval 6) line 21.
0
*&
*&
Illegal hexadecimal digit ' ' ignored at (eval 6) line 21.
0

>From this it looks like what's being passed into the subroutine by MRTG isn't right. I've captured MRTG's SNMP conversation, and I know the returned value is hex as above. Does MRTG convert the result to printable ASCII before passing it to the subroutine? That might explain what I see.

More likely, my means of declaring it as a string ( <my \$value = shift> ) is wrong. The PERL documentation for shift doesn't look like it does what I expect it to:

Shifts the first value of the array off and returns it...

Yet the MRTG-reference doc uses this specifically under the ConversionCode section:

# Return the length of the string argument
sub Length2Int {
my \$value = shift;
return length( \$value );
}

Thanks in advance for any help anyone can offer. As for me, it's back to the books.

Dan Lynch, CISSP
Information Technology Analyst
County of Placer
Auburn, CA

>>> Takumi Yamane <yamtak at b-session.com> 10/19/04 08:31PM >>>
On Tue, 19 Oct 2004 23:06:06 -0400 (EDT), "Bill Wichers" wrote
in <3506.209.115.5.164.1098241566.squirrel at 209.115.5.164>:
>
> >      40.05.D6.DC.20.DE.0D
> [snip]
> You need to write something that takes out the "." characters from
> between the hex digits.

\$val =~ s/\.//og;
or
\$val =~ y/\.//d;

Regards,
Takumi Yamane <yamtak at b-session.com>

--
Unsubscribe mailto:mrtg-request at list.ee.ethz.ch?subject=unsubscribe
Archive     http://www.ee.ethz.ch/~slist/mrtg
FAQ         http://faq.mrtg.org    Homepage     http://www.mrtg.org

--
Unsubscribe mailto:mrtg-request at list.ee.ethz.ch?subject=unsubscribe
Archive     http://www.ee.ethz.ch/~slist/mrtg
FAQ         http://faq.mrtg.org    Homepage     http://www.mrtg.org