?
Solved

Sending hex characters with Perl NET::SNMP set_request

Posted on 2011-10-01
6
Medium Priority
?
2,057 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
  • 3
  • 3
6 Comments
 
LVL 85

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 85

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
Free Tool: Port Scanner

Check which ports are open to the outside world. Helps make sure that your firewall rules are working as intended.

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.

 

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 85

Accepted Solution

by:
ozo earned 2000 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

Receive 1:1 tech help

Solve your biggest tech problems alongside global tech experts with 1:1 help.

Question has a verified solution.

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

A year or so back I was asked to have a play with MongoDB; within half an hour I had downloaded (http://www.mongodb.org/downloads),  installed and started the daemon, and had a console window open. After an hour or two of playing at the command …
Article by: Tammy
MySQLTuner is a script written in Perl that allows you to review a MySQL installation quickly and make adjustments to increase performance and stability. The current configuration variables and status data is retrieved and presented in a brief forma…
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…
Six Sigma Control Plans
Suggested Courses

594 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