Perl Net::SNMP returns noSuchName when snmpwalk works - perl

I am new to perl, but I am trying to write a plug-in for nagios. I have a simple get request that fails, but if I try the same request with snmpwalk it works.
My code is:
#!/usr/bin/perl -w
use strict;
use Net::SNMP;
my $host = '10.10.10.203';
my $community = 'myComm';
my $session;
my $error;
my $response = undef;
($session, $error) = Net::SNMP->session(
-hostname => $host,
-version => 2,
-community =>$community,
-port => 161,
-timeout => 20
);
my $uptimeOID = '1.3.6.1.2.1.1.3.0';
my $myOID = '1.3.6.1.4.1.7933';
if( !defined( $response = $session->get_request($myOID)))
{
if( $session->error_status == 2)
{
my $sessionError = $session->error;
print ("($sessionError) OID not supported ($myOID).\n");
}
}
else
{
print ("$response");
}
If I run this script it will fail saying noSuchName, but if a run:
snmpwalk -v 2c -c myComm 10.10.10.203 1.3.6.1.4.1.7933
I get the response I want. Does anybody know why this wont work?
If I check the uptime OID with this script it will work the way it should.

You've already identified that via the command-line you're doing a "walk" rather than a "get". If there's a specific value you want to "get" in your script, put in the full OID identifying the target.
There's something in a table record that you probably want to get at (and it seems like everything in FASTTRAKIDERAID-MIB is in fact tabular), so a simple get isn't enough. Look at the snmpwalk.pl script that comes with Net::SNMP or see if SNMP::Util can easily provide the functionality you're looking for.

Use get_next_request, not get_request. It will return the first valid oid after the one you pass it.

I found my problem. When I use snmpwalk, it will grab the whole tree and return a value. The perl module will not. It doesn't traverse the tree to the end even thought there is only one thing below it, it just says no.

Related

Error: ' Can't use string ("") as a HASH ref while "strict refs" ' in combination with google recaptcha v2. Works on local machine but not on webhost

I am very new to Perl and was just assigned the quick task to change the reCAPTCHA to reCAPTCHA v2.
On my local machine this works fine, however when I push the new version of the login form to the webhost, the form does not seem to work. I get the following error:
AH01215: Can't use string ("") as a HASH ref while "strict refs" in use at login_new.cgi line 68, line 1.: [........]
The code snippet is based on the documentation I found here: https://metacpan.org/pod/Captcha::reCAPTCHA::V2
And according to the error log my error is somewhere in here (line 68):
if ($submit) {
my $response = $cgi->param('g-recaptcha-response');
my $result = $captcha->verify($captcha_private_key, $response );
if ($result->{success}) # This is line 68
{....}
This is quite confusing to me, especially since it is working on my local machine. Could you please help? Best regards and thank you in advance!
The Verify Function has a bug. I just looked at the implementation. in case that "$res" isn't 'successful' it wont give you back the wanted hash reference.
As a quick workaround I would check if your my $result is equal to "" if thats the case the verify function failed.
In the long run you should probably submit that bug to the creator of the module.
disclaimer: I havent downloaded the module and just looked at the source without actually trying my workaround so take it with a grain of salt and try it in a safe environment first
sub verify {
my ($self, $secret, $response, $remoteip) = #_;
# ... more code here, removed for better readability
my $res = $self->{ua}->post_form(
$self->{verify_api},
$params
);
if ($res->{success}) {
my $content = decode_json $res->{content};
if ($content->{success}){
return { success => 1 };
} else {
return { success => 0, error_codes => $content->{'error-codes'} };
}
}
}

Using Bitcoin's sendmany function with perl

I have been struggling with this one for a while and will be grateful if someone could offer a solution. Basically, I am trying to use bitcoin's 'sendmany' function (https://en.bitcoin.it/wiki/Original_Bitcoin_client/API_calls_list) to send mass payment with a perl script. I am running bitcoind on a vps and other functions are working fine but sendmany isn't. This is the code that I have :
use Finance::Bitcoin::API;
$ENV{PERL_LWP_SSL_VERIFY_HOSTNAME} = 0;
use Data::Dumper;
my %recipients = ("ADDRESS1" => sprintf("%.8f",0.00005460)+0, "ADDRESS2" => sprintf("%.8f",0.00005460)+0);
my $uri = "https://$rpcuser:$rpcpass\#$rpcip:8332/";
my $api = Finance::Bitcoin::API->new( endpoint => $uri );
my $action = $api->call('sendmany','',%recipients);
if ($api->error)
{
print Dumper($api->error->{message})."\n";
}
else
{
print Dumper($action)."\n";
}
I am able to send single payments using the 'sendtoaddress' function and I am able to use the sendmny function directly in the vps that is running bitcoind by executing it from the shell, but it fails when I try it using the perl script above. There is no error message, I just get the instructions for using sendmany from shell and using curl.
I am also open to scripts in any other language that will let me execute sendmany.
Thanks for the help.
I finally figured out the error in the above code. Replace the line my $action = $api->call('sendmany','',%recipients); with my $action = $api->call('sendmany','',\%recipients);
Basically just add a forward slash before %recipients. Hope this helps someone.

Perl -- 'Not a HASH reference' error when using JSON::RPC::Client

I'm a newbie in Perl.
I have a JSON-RPC server running at http://localhost:19000 and I need to call checkEmail() method.
use JSON::RPC::Client;
my $client = new JSON::RPC::Client;
my $url = 'http://localhost:19000';
my $callobj = {
method => 'checkEmail',
params => [ 'rprikhodchenko#gmail.com' ],
};
my $res = $client->call($url, $callobj);
if($res) {
if ($res->is_error) {
print "Error : ", $res->error_message;
}
else {
print $res->result;
}
}
else {
print $client->status_line;
}
When I try to launch it it tells following:
perl ./check_ac.pl
Not a HASH reference at /usr/local/share/perl/5.10.1/JSON/RPC/Client.pm line 193.
UPD:
Full stack-trace:
perl -MCarp::Always ./check_ac.pl
Not a HASH reference at /usr/local/share/perl/5.10.1/JSON/RPC/Client.pm line 193
JSON::RPC::ReturnObject::new('JSON::RPC::ReturnObject', 'HTTP::Response=HASH(0x9938d48)', 'JSON=SCALAR(0x96f1518)') called at /usr/local/share/perl/5.10.1/JSON/RPC/Client.pm line 118
JSON::RPC::Client::call('JSON::RPC::Client=HASH(0x944a818)', 'http://localhost:19000', 'HASH(0x96f1578)') called at ./check_ac.pl line 11
This error means that your JSON-RPC server is not actually one, inasmuch as it does not satisfy requirement 7.3. The error is triggered when JSON::RPC::Client assumes the document returned by the JSON-RPC service is well-formed (i.e., a JSON Object), and this assumptions turns out to have been in error. A bug report to the author of JSON::RPC::Client would be an appropriate way to request better error messaging.
I would attack this sort of problem by finding out what the server was returning that was causing JSON::RPC::Client to choke. Unfortunately, JRC fails to provide adequate hookpoints for finding this out, so you'll have to be a little bit tricky.
I don't like editing external libraries, so I recommend an extend-and-override approach to instrumenting traffic with the JSON-RPC server. Something like this (in check_ac.pl):
use Data::Dumper qw();
package JSON::RPC::InstrumentedClient;
use base 'JSON::RPC::Client';
# This would be better done with Module::Install, but I'm limiting dependencies today.
sub _get {
my ($self, #args) = #_;
return $self->_dump_response($self->SUPER::_get(#args));
}
sub _post {
my ($self, #args) = #_;
return $self->_dump_response($self->SUPER::_post(#args));
}
sub _dump_response {
my ($self, $response) = #_;
warn Data::Dumper::Dump([$response->decoded_content], [qw(content)]);
return $response;
}
package main;
my $client = JSON::RPC::InstrumentedClient->new();
my $url = 'http://localhost:19000';
... # rest of check_ac.pl
This wraps the calls to _get and _post that JSON::RPC::Client makes internally in such a way as to let you examine what the web server actually said in response to the request we made. The above code dumps the text content of the page; this might not be the right thing in your case and will blow up if an error is encountered. It's a debugging aid only, to help you figure out from the client code side what is wrong with the server.
That's enough caveats for now, I think. Good luck.
It seems to be a bug in method new of JSON::RPC::ReturnObject.
sub new {
my ($class, $obj, $json) = #_;
my $content = ( $json || JSON->new->utf8 )->decode( $obj->content );
#...
# line 193
$content->{error} ? $self->is_success(0) : $self->is_success(1);
#...
}
$content's value will be something returned from a JSON::decode() call. But looking at the documentation, it seems that JSON->decode() returns a scalar which could be a number, a string, an array reference, or a hash reference.
Unfortunately, JSON::RPC::ReturnObject->new() doesn't check what sort of thing JSON->decode() returned before trying to access it as a hashref. Given your error, I'm going to go ahead and assume what it got in your case was not one. :-)
I don't know if there's a way to force a fix from your code. I'd recommend contacting the author and letting him know about the issue, and/or filing a bug.

How do I use Perl's Google::Search to look for specific URLs?

The Google::Search module, which is based on the AJAX Search API, doesn't seems to work very well, or it is just me?
For example, I use firefox to search google for: http://bloggingheads.tv/forum/member.php?u=12129
It brings results.
But when I use the module this way:
$google_search = Google::Search->Web ( q => "http://bloggingheads.tv/forum/member.php?u=12129" );
#result = $google_search->all;
I get nothing in the array.
Any idea?
Seems like this API doesn't bring the same results like when searching manually, am I missing something?
I had a similar problem with cyrillic queries. Both Google::Search and REST::Google from CPAN didn't work for me - they were giving back fewer or no results compared to manual test.
Eventually I wrote a scraping module using WWW::Mechanize and HTML::TreeBuilder.
Here's a sample to get result stats:
my $tree = HTML::TreeBuilder->new_from_content($content);
if (my $div = $tree->look_down(_tag => 'div', id => 'resultStats')) {
my $stats = $div->as_text();
}
else { warn "no stats" }
Looking at the POD for Google::Search, it looks like it expects you to pass search terms to Web, instead of a URL. I downloaded a test script from CPAN, ran it, and it seems to produce expected results:
use strict;
use warnings;
use Google::Search;
my $search = Google::Search->Web(q => "rock");
my $result = $search->first;
while ($result) {
print $result->number, " ", $result->uri, "\n";
$result = $result->next;
}
print $search->error->reason, "\n" if $search->error;
__END__
0 http://www.rock.com/
1 http://en.wikipedia.org/wiki/Rock_music
2 http://en.wikipedia.org/wiki/Rock_(geology)
3 http://rockyourphone.com/
4 http://rockhall.com/
5 http://www.co.rock.mn.us/
6 http://www.co.rock.wi.us/
7 http://www.rockride.org/
etc...
I realize this does not specifically answer your question, but perhaps it steers you in the right direction.

"Can't call method "dir_path" on an undefined value" when running Mason component on the command line

Greetings,
I'm trying to develop some tests for Mason components which requires running them on the command line instead of the web server. When I try this, I get an error:
perl -MHTML::Mason::Request -MHTML::Mason::Interp -I./lib \
-e '$int = HTML::Mason::Interp->new( data_dir => "/home/friedo/cache", comp_root => "/home/friedo/comps" ); $m = HTML::Mason::Request->new( comp => "/dummy", interp => $int ); $m->comp("/dummy")'
Results in:
Can't call method "dir_path" on an undefined value at lib/HTML/Mason/Request.pm line 1123.
The error is thrown when the call to ->comp is attempted. I can't figure out what's wrong with the configuration. The component is there and appears to be compiled just fine, and it works via Apache.
This is using HTML::Mason 1.35.
Edit: Let's try a bounty for this one. The alternative is me having to dive deep into Mason's guts! :)
Edit again: Thanks very much to David for pointing out the crucial detail that I missed for getting this to work.
This was actually for a test framework that needed to exercise a module that calls some Mason comps -- under normal operation the module is provided with a Mason request object to use for that purpose, but I couldn't get that to work offline. The key was using an Interpreter object instead, so I ended up doing the following, which is a little silly but makes the tests work:
sub _mason_out {
...
my $buf;
if ( $ENV{MASON_TEST} ) {
my $int = HTML::Mason::Interp->new( comp_root => $self->{env}->comp_dir,
out_method => \$buf );
$int->exec( $comp, %args );
} else {
my $m = $self->{mason_object};
$m->comp( { store => \$buf }, $comp, %args );
}
return $buf;
}
I think this fails because your Request object hasn't built a component stack at the point that it is called. Use the Interp->exec() method instead as described in Using Mason from a Standalone Script
perl -MHTML::Mason::Interp -I./lib \
-e 'HTML::Mason::Interp->new( data_dir => "/home/friedo/cache", comp_root => "/home/friedo/comps" )->exec("/dummy")'