Improve company productivity with a Business Account.Sign Up

x
  • Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 2110
  • Last Modified:

Sending hex characters with Perl NET::SNMP set_request

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
etcit
Asked:
etcit
  • 3
  • 3
1 Solution
 
ozoCommented:
did you try "fffffffc"
0
 
etcitAuthor Commented:
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
 
ozoCommented:
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.

 
etcitAuthor Commented:
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
 
ozoCommented:
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
 
etcitAuthor Commented:
Thank you very much.  chr($octet) worked perfectly. I have also taken your advice and used $_[0] in lieu of @ARGV.
0
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

Join & Write a Comment

Featured Post

Free Tool: Site Down Detector

Helpful to verify reports of your own downtime, or to double check a downed website you are trying to access.

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.

  • 3
  • 3
Tackle projects and never again get stuck behind a technical roadblock.
Join Now