⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 storage.pm

📁 开发snmp的开发包有两个开放的SNMP开发库
💻 PM
字号:
#########################################################################package AnyData::Storage::SNMP;########################################################################### XXX: TODO:##   scalar sets?##   multi-hosts$AnyData::Storage::VERSION = '5.0401';use strict;use vars qw(@basecols);@AnyData::Storage::SNMP::basecols = qw(hostname iid);$AnyData::Storage::SNMP::iidptr = 1; # must match array column of above@AnyData::Storage::SNMP::basetypes = qw(OCTETSTR OBJECTID);$AnyData::Storage::SNMP::debug = 0;$AnyData::Storage::SNMP::debugre = undef;use Data::Dumper;use AnyData::Storage::File;use SNMP;SNMP::init_snmp("AnyData::SNMP");sub new {#    DEBUG("calling AnyData::Storage::SNMP new\n");#    DEBUG("new storage: ",Dumper(\@_),"\n");    my $class = shift;    my $self  = shift || {};    $self->{open_mode} = 'c';    return bless $self, $class;}sub open_table {    DEBUG("calling AnyData::Storage::SNMP open_table\n");    my ($self, $parser, $table, $mode, $tname) = @_;    $self->{'process_table'} = $tname;    DEBUG("open_table: ",Dumper(\@_),"\n");}sub get_col_names {    DEBUG("calling AnyData::Storage::SNMP get_col_names\n");    my ($self, $parser, $tname) = @_;    DEBUG("get_col_names\n",Dumper(\@_),"\n");    $tname = $self->{'process_table'} if (!$tname);    # get cached previous results    return $self->{col_names}{$tname} if (defined($self->{col_names}{$tname}));    # table name    $tname = $self->{'process_table'} if (!$tname);    # mib node setup    my $mib = $SNMP::MIB{$tname} || return warn "no such table $tname";    my $entry = $mib->{'children'}[0];    # base columns and types    my @cols = @AnyData::Storage::SNMP::basecols;    my @types = @AnyData::Storage::SNMP::basetypes;    my %donecol;    my $count = $#cols;    foreach my $index (@{$entry->{'indexes'}}) {	push @cols, $index;	push @types, $SNMP::MIB{$index}{type};	$donecol{$index} = 1;	$count++;	if ($SNMP::MIB{$index}{parent}{label} eq $entry->{label}) {	    # this index is a member of this table	    $self->{columnmap}[$count] = $index;	    $self->{coloffset} += 1;	}    }    # search children list    foreach my $child  ( sort { $a->{'subID'} <=> $b->{'subID'} } @{$entry->{'children'}}) {	push @{$self->{real_cols}}, $child->{'label'};	next if ($donecol{$child->{label}});	push @cols, $child->{'label'};	push @types, $child->{'type'};	$count++;	$self->{columnmap}[$count] = $child->{'label'};    }    # save for later.    $parser->{col_names} = \@cols;    $self->{col_types} = \@types;    $self->{col_names} = \@cols;    map { $self->{col_uc_map}{uc($_)} = $_ } @cols;    return \@cols;}sub set_col_nums {    DEBUG("calling AnyData::Storage::SNMP set_col_nums\n");    DEBUG("set_col_nums\n",Dumper(\@_),"\n");    my ($self, $tname) = @_;    return $self->{col_nums} if (defined($self->{col_nums}));    my $mib = $SNMP::MIB{$tname};    my $entry = $mib->{'children'}[0];    my (%cols, %mibnodes);    my $cnt = -1;    foreach my $i (@{$self->{col_names}}) {	$cols{$i} = ++$cnt;    }    $self->{col_nums} = \%cols;    return \%cols;}# not needed?sub get_file_handle {    DEBUG("calling AnyData::Storage::SNMP get_file_handle\n");    DEBUG("get_file_handle\n",Dumper(\@_),"\n");    return shift;}# not needed?sub get_file_name {    DEBUG("calling AnyData::Storage::SNMP get_file_name\n");    DEBUG("get_file_name\n",Dumper(\@_),"\n");    my $self = shift;    return $self->{process_table} || $self->{table_name};}sub truncate {    DEBUG("calling AnyData::Storage::SNMP truncate\n");    my ($self) = @_;    DEBUG("trunacte, ", Dumper(@_));    # We must know how to delete rows or else this is all pointless.#     return $self->{col_nums}{$tname} if (defined($self->{col_nums}{$tname}));    my $tablemib = $SNMP::MIB{$self->{process_table}};    my $entrymib = $tablemib->{'children'}[0];    my ($delcolumn, $delcolumnname, $delcolumnvalue);    foreach my $child  (@{$entrymib->{'children'}}) {	if ($child->{'textualConvention'} eq 'RowStatus') {	    $delcolumn = $child->{subID};	    $delcolumnname = $child->{label};	    $delcolumnvalue = 6; # destroy	    last;	}    }    if (!$delcolumn) {	return warn "Can't (or don't know how to) delete from table $self->{process_table}.  Failing.\n";    }    # we should have a session, or else something is really wierd but...    $self->{'sess'} = $self->make_session() if (!$self->{'sess'});    # for each key left in our cache, delete it    foreach my $key (keys(%{$self->{'existtest'}})) {	# xxx: fullyqualified oid better	my $vblist = new SNMP::VarList([$delcolumnname, $key,					$delcolumnvalue]);	DEBUG("truncate $key: \n", Dumper($vblist));	$self->{'sess'}->set($vblist) || warn $self->{'sess'}->{ErrorStr};    }    return;}sub make_session {    DEBUG("calling AnyData::Storage::SNMP make_session\n");    my $self = shift;    my @args = @_;    my @sessions;    foreach my $key (qw(SecName Version SecLevel AuthPass Community RemotePort Timeout Retries RetryNoSuch SecEngineId ContextEngineId Context AuthProto PrivProto PrivPass)) {	push @args, $key, $self->{$key} if ($self->{$key});    }    foreach my $host (split(/,\s*/,$self->{DestHost})) {	push @sessions, new SNMP::Session(@args, 'DestHost' => $host);    }    return \@sessions;}sub file2str {    DEBUG("calling AnyData::Storage::SNMP file2str\n");    my ($self, $parser, $uccols) = @_;    my ($cols, @retcols);    DEBUG("file2str\n",Dumper(\@_),"\n");  restart:    if (!$self->{lastnode}) {#	my @vbstuff = @{$parser->{'col_names'}};#	splice (@vbstuff,0,1+$#AnyData::Storage::SNMP::basecols);#	map { $_ = [ $_ ] } @vbstuff;#	$self->{lastnode} = new SNMP::VarList(@vbstuff);#	splice (@$cols,0,1+$#AnyData::Storage::SNMP::basecols);	map { push @$cols,$self->{col_uc_map}{$_} } @$uccols;	if ($#$cols == -1) {	    $cols = $self->{'col_names'};	    # remove base columns	    splice (@$cols,0,1+$#AnyData::Storage::SNMP::basecols);	    # remove not accessible columns	    foreach my $col (@$cols) {		my $mib = $SNMP::MIB{$col};		push @retcols, $col if ($mib->{'access'} =~ /Read|Create/);	    }	} else {	    @retcols = @$cols;	    # remove base columns	    foreach my $c (@AnyData::Storage::SNMP::basecols) {		@retcols = grep(!/^$c$/, @retcols);	    }	    # remove non-accessible columns	    @retcols = grep {$SNMP::MIB{$_}{'access'} =~ /Read|Create/} @retcols;	}	map { $_ = [ $_ ] } @retcols;	$self->{lastnode} = new SNMP::VarList(@retcols);    }    if (!$self->{'sess'}) {	$self->{'sess'} = $self->make_session();	if ($#{$self->{'sess'}} == 0 && $self->{'silence_single_host'}) {	    $self->{'hostname'} = '';	} else {	    $self->{'hostname'} = $self->{'sess'}[0]{'DestHost'};	}    }    # perform SNMP operation    my $lastnode = $self->{'lastnode'}[0][0];    my $result;    $result = $self->{'sess'}[0]->getnext($self->{lastnode});    if (!defined($result)) {	warn " getnext of $self->{lastnode}[0][0] returned undef\n";    }    DEBUG(" result: ",Dumper($self->{lastnode}),"\n");    # XXX: check for holes!    # need proper oid compare here for all nodes    if ($self->{'lastnode'}[0][0] ne $lastnode) {	if ($#{$self->{'sess'}} > 0) {	    shift @{$self->{'sess'}};	    delete($self->{'lastnode'});	    @$cols = ();	    $self->{'hostname'} = $self->{'sess'}[0]{'DestHost'} if($self->{'hostname'});	    goto restart;	}	return undef;    }        # add in basecols information:    my @ret = ($self->{'hostname'}, $self->{'lastnode'}[0][1]);    DEBUG("Dump row results: ",Dumper($self->{'lastnode'}),"\n");    # build result array from result varbind contents    map { $ret[$self->{'col_nums'}{$_->[0]}] = map_data($_); } @{$self->{'lastnode'}};    # store instance ID for later use if deletion is needed later.    $self->{'existtest'}{$self->{'lastnode'}[0][1]} = 1;    DEBUG("Dump row results2: ",Dumper(\@ret),"\n");    return \@ret;}sub map_data {    if ($_->[3] eq "OBJECTID") {	$_->[2] = pretty_print_oid(@_);    }    return $_->[2];}sub pretty_print_oid {    use NetSNMP::default_store qw(:all);    netsnmp_ds_set_boolean(NETSNMP_DS_LIBRARY_ID, 			   NETSNMP_DS_LIB_DONT_BREAKDOWN_OIDS,0);    my $new = SNMP::translateObj($_->[2], 0);    netsnmp_ds_set_boolean(NETSNMP_DS_LIBRARY_ID, 			   NETSNMP_DS_LIB_DONT_BREAKDOWN_OIDS,1);    my $new2 = SNMP::translateObj($_->[2], 0);    if ($new) {	$_->[2] = $new2 . "$new";    } else {	$_->[2] = $_->[0] . $_->[1];    }    return $_->[2];}sub push_row {    DEBUG("calling AnyData::Storage::SNMP push_row\n");    DEBUG("push_row: ",Dumper(\@_),"\n");    DEBUG("push_row\n");    my ($self, $values, $parser, $cols) = @_;    my @callers = caller(3);    my $mode = $callers[3];    if ($mode =~ /DELETE/) {	DEBUG("not deleting $values->[$AnyData::Storage::SNMP::iidptr]\n");	delete $self->{'existtest'}{$values->[$AnyData::Storage::SNMP::iidptr]};	return;    }    my @origvars;    if ($#$cols == -1) {	# no column info passed in.  Update everything (mode probably INSERTS).#	@origvars = @{$self->{'col_names'}}};#	splice (@origvars,0,1+$#AnyData::Storage::SNMP::basecols);		map { push @origvars, $_ if $SNMP::MIB{$_}{'access'} =~ /Write|Create/; } @{$self->{'real_cols'}} ;	DEBUG("set cols: ", Dumper(\@origvars));    } else {	# only update the columns in question.  (mode probably UPDATE)	map { push @origvars, $self->{col_uc_map}{$_} } @$cols;    }    my @vars;    foreach my $var (@origvars) {	my $access = $SNMP::MIB{$var}{'access'};	# not in this table, probably (hopefully) an index from another:	next if ($SNMP::MIB{$var}{'parent'}{'parent'}{'label'} ne 		 $self->{process_table});	DEBUG("$var -> $access\n");	if ($access =~ /(Write|Create)/) {	    push @vars, $var;	} elsif ($mode eq 'insert') {	    DEBUG("XXX: error if not index\n");	} elsif ($mode eq 'update') {	    DEBUG("update to non-writable column attempted (SNMP error coming)\n");		}    }    # generate index OID component if we don't have it.    if ($values->[$AnyData::Storage::SNMP::iidptr] eq '') {	$values->[$AnyData::Storage::SNMP::iidptr] = 	    $self->make_iid($self->{process_table}, $values);    }    # add in values to varbind columns passed in from incoming parameters    my @newvars;    foreach my $v (@vars) {	my $num = $self->{'col_nums'}{$v};	DEBUG("types: $v -> $num -> ", $self->{'col_types'}[$num], 	      " -> val=", $values->[$num], "\n");	next if (!defined($values->[$num]));	# build varbind: column-oid, instance-id, value type, value	push @newvars, [$v, $values->[1], $values->[$num],			$self->{'col_types'}[$num]];    };    # create the varbindlist#    print STDERR Dumper(\@newvars);    my $vblist = new SNMP::VarList(@newvars);#    print STDERR Dumper($vblist);    DEBUG("set: ", Dumper($vblist));    $self->{'sess'} = $self->make_session() if (!$self->{'sess'});    if (!$self->{'sess'}[0]) {	warn "couldn't create SNMP session";    } elsif (!$self->{'sess'}[0]->set($vblist)) {	my $err = "$self->{process_table}: " . $self->{'sess'}[0]->{ErrorStr};	if ($self->{'sess'}[0]->{ErrorInd}) {	    $err = $err . " (at varbind #" 		. $self->{'sess'}[0]->{ErrorInd}  . " = " ;	    my $dump = Data::Dumper->new([$vblist->[$self->{'sess'}[0]->{ErrorInd} -1]]);	    $err .= $dump->Indent(0)->Terse(1)->Dump;	}	warn $err;    }}sub seek {    DEBUG("calling AnyData::Storage::SNMP seek\n");    my ($self, $parser) = @_;    DEBUG("seek\n",Dumper(\@_),"\n");}sub make_iid {    DEBUG("calling AnyData::Storage::SNMP make_iid\n");    my ($self, $tname, $vals) = @_;        # Get indexes    my $mib = $SNMP::MIB{$tname};    my $entry = $mib->{'children'}[0];    my $indexes = $entry->{'indexes'};    my $iid;    # XXX: implied#    print STDERR "INDEXES: ", Dumper($vals),"\n";    foreach my $index (@$indexes) {	warn "A null index value was found, which I doubt is correct." if (!defined($vals->[$self->{col_nums}{$index}]));	my $val = $vals->[$self->{col_nums}{$index}];	my $type = $SNMP::MIB{$index}->{'type'};	DEBUG("index type: $index -> $type -> $val -> " . length($val) . "\n");	if ($type eq "OCTETSTR") {	    $iid .= "." . length($val) . "." . join(".", unpack("c*", $val));	} elsif ($type eq "OBJID") {	    $iid .= "." . (scalar grep(/\./,$val) + 1) . "." . $val;	} else {	    # should be only an INTEGER?	    $iid .= "." . $val;	}    }    DEBUG("made iid: $iid\n");    return $iid;}sub DEBUG {    my @info = caller(1);    if ($AnyData::Storage::SNMP::debug	|| ($AnyData::Storage::SNMP::debugre &&	    $_[0] =~ /$AnyData::Storage::SNMP::debugre/)) {	DEBUGIT(\@info, @_);    }}sub DEBUGIT {    my $info;    if (ref($_[0]) eq 'ARRAY') {	$info = shift @_;    } else {	my @y;	my $c=0;	print STDERR "debug chain: ";	for(@y = caller($c); $#y > -1; $c++, @y = caller($c)) {	    print STDERR "  $c: $y[3]\n";	}	my @x = caller(1);	$info = \@x;    }    print STDERR "$info->[3]: ";    print STDERR @_;}1;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -