Solved

Sending hex characters with Perl NET::SNMP set_request

Posted on 2011-10-01
6
1,868 Views
Last Modified: 2012-08-13
I'm having a bit of trouble with a perl script using the NET::SNMP module.
#!/usr/bin/perl -w

use strict;
use Net::SNMP;


# Initialize "session" object with ip address and community string
my ($session, $error) = Net::SNMP->session(
        Hostname => 'hostname',
        Community => 'private',
        Version => 2
);

die "session error: $error" unless ($session);

my $result = $session->set_request(
   -varbindlist => [
     "1.3.6.1.4.1.4115.1.20.1.1.2.5.14.0", OCTET_STRING, "\xfffffffc"
    ]);

$result or warn "error: @{[$session->error]}\n";

$session->close;

Open in new window


The MIB at line 18 that I am attempting to modify is an IPv4 subnet mask field.  The device will not accept the MIB value in string format, but instead requires the value to be sent in hexadecimal.   I have verfied this from a Linux shell with the following commands:
snmpset -v 2c -c private hostname 1.3.6.1.4.1.4115.1.20.1.1.2.5.14.0 s "255.255.255.252"
Error in packet.
Reason: wrongLength (The set value has an illegal length from what the agent expects)
Failed object: SNMPv2-SMI::enterprises.4115.1.20.1.1.2.5.14.0

snmpset -v 2c -c private hostname 1.3.6.1.4.1.4115.1.20.1.1.2.5.14.0 x "fffffffc"
SNMPv2-SMI::enterprises.4115.1.20.1.1.2.5.14.0 = Hex-STRING: FF FF FF FC
I am having trouble determining how to properly format the hex value in my perl code to pass it correctly to the SNMP agent on the device.  So far every method that I have attempted has resulted in the following error:
error: Received wrongLength(8) error-status at error-index 1
Please help
0
Comment
Question by:etcit
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 3
  • 3
6 Comments
 
LVL 84

Expert Comment

by:ozo
ID: 36898240
did you try "fffffffc"
0
 

Author Comment

by:etcit
ID: 36899393
Yes I've tried that but perl sends that as a string value instead of hex.  I need to know how to send hex values in the set_request.
0
 
LVL 84

Expert Comment

by:ozo
ID: 36899906
I'm not sure what you need to send, but it sounds like you are asking about string values like ""\xff\xff\xff\xfc"
0
Industry Leaders: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 

Author Comment

by:etcit
ID: 36901114
Thank you that works perfectly.  But to expand on the issue a little further the hex value (fffffffc in this example) is not a static value, but is instead a value returned from a subroutine.  Please see code below.

#!/usr/bin/perl -w

my $version=0.1;

use strict;
use Net::SNMP;

sub hexip {
        my @ARGV = @_;
        my $hex;
        foreach my $octet (split(/\./,$ARGV[0], 4)) {
                die "Invalid IP address given\n" if($octet < 0 || $octet > 255);
                $hex .= sprintf("%02x",$octet);
        }
        return $hex;
}

# Initialize "session" object with ip address and community string
my ($session, $error) = Net::SNMP->session(
        Hostname => 'hostname',
        Community => 'private',
        Version => 2
);

die "session error: $error" unless ($session);

my $result = $session->set_request(
   -varbindlist => [
     "1.3.6.1.4.1.4115.1.20.1.1.2.5.14.0", OCTET_STRING, hexip('255.255.255.252')
    ]);

$result or warn "error: @{[$session->error]}\n";

$session->close;

Open in new window


The subroutine hexip() accepts a standard dotted decimal notation subnet mask and returns its hexadecimal equivalent.  This is to prevent the end user having to perform the conversion in advance. How can I structure my code at line 29 so that the returned value is formatted like your previous example ("\xff\xff\xff\xfc"). If the value of $hex in the subroutine needs to be escaped prior to returning it, please provide those instructions as well.  Thank you for your assistance.
0
 
LVL 84

Accepted Solution

by:
ozo earned 500 total points
ID: 36901621
change
 sprintf("%02x",$octet)
to
 chr $octet;

btw, @ARGV may not be the best choice of local variable name to use, since perl already uses that name for the command line arguments.
You could just use
$_[0] or shift as the argument to the split.
or just
return pack"C*",grep{0<=$_&&$_<=255 or die"Invalid IP address given\n"}split/\./,shift

0
 

Author Comment

by:etcit
ID: 36902952
Thank you very much.  chr($octet) worked perfectly. I have also taken your advice and used $_[0] in lieu of @ARGV.
0

Featured Post

Free Tool: SSL Checker

Scans your site and returns information about your SSL implementation and certificate. Helpful for debugging and validating your SSL configuration.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

I've just discovered very important differences between Windows an Unix formats in Perl,at least 5.xx.. MOST IMPORTANT: Use Unix file format while saving Your script. otherwise it will have ^M s or smth likely weird in the EOL, Then DO NOT use m…
There are many situations when we need to display the data in sorted order. For example: Student details by name or by rank or by total marks etc. If you are working on data driven based projects then you will use sorting techniques very frequently.…
Explain concepts important to validation of email addresses with regular expressions. Applies to most languages/tools that uses regular expressions. Consider email address RFCs: Look at HTML5 form input element (with type=email) regex pattern: T…

752 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question