Скрипт для формирования на основе опроса принтеров в сети по SNMP. (perl print snmp)
Ключевые слова: perl, print, snmp, (найти похожие документы)
From: Alex Software <http://diskless.kbpriroda.ru>
Date: Mon, 1 Oct 2007 14:31:37 +0000 (UTC)
Subject: Скрипт для формирования на основе опроса принтеров в сети по SNMP.
Оригинал: http://diskless.kbpriroda.ru/index.shtml?MENU=7
Для удобства настройки печати пользователю имеется способ
автоматической настройки его принтера согласно правилам, которые вы
можете сами установить.
Есть множество способов такой автоматической настройки, но для
удобства лучше всего использовать управляемые коммутаторы, где можно
подписать порт. В этом случае можно сделать универсальную утилиту,
которая будет настраивать cups исходя из модели принтера путем
получения информации посредством SNMP и сохранить "физическое"
местоположение принтера, а так же при логине пользователя выяснить на
каком порту он находится и согласно правилам выяснить ближайший к нему
принтер и установить его "по умолчанию".
Для удобства последующей работы я использую postgresql для хранения
информации о принтерах, чтобы каждый раз не сканировать сеть.
Пример скрипта для получения информации из принтеров (HP, других нет).
Скрипт работает на основе информации из портов коммутаторов (SMC и
3Com, возможно и из других будет брать, но надо подрисовать адреса и
функции опроса). Комментарии я специально оставил, чтобы донести
мысль.
Скрипт scan_printers.pl:
#!/usr/bin/perl
use Pg;
use Net::Telnet ();
#use strict;
use Net::SNMP;
my $qqq_ip=@ARGV[0];
#$qq_ip='-I eth1 10.0.0.';
#for $i (2 .. 254) {
#$qqq_ip=$qq_ip.$i;
#@rrr=get_iface_nets();
open(OUT_SQL,">","update_printers");
push @rrr,'eth1,10.0.0';
foreach $qqq (@rrr) {
#print $qqq;
@arr_rrr=split(/,/,$qqq);
print @arr_rrr[1].'.230-244';
@arr1=scan_nmap(@arr_rrr[1].'.230-244');
foreach $ip_host (@arr1) {
$dsc_pr=get_printer($ip_host);
#print $ip_host;
if ($dsc_pr=~/PRINTER/) {
print "IP host =".$ip_host." snmp name = ".get_printer_name($ip_host)."\n";
$printer_nom=get_printer_name($ip_host);
print "SNMP detail ".$dsc_pr."\n";
print "Driver:".get_drv($dsc_pr)."\n";
$prt_drv=get_drv($dsc_pr);
@drv_arr=split(/\;/,$prt_drv);
$qqq_mac=ip_to_mac($ip_host);
$fsmc_port=find_smc('192.168.100.144',$qqq_mac);
if ($fsmc_port > 0) {
#print "Mport=".$fsmc_port.",";
#print "port ".swsmc_port_descr('192.168.100.144',$fsmc_port)." ";
$port_descr=swsmc_port_descr('192.168.100.144',$fsmc_port);
if ($port_descr=~/room/) {
@t_arr=split(/\_/,$port_descr);
print "Room ".@t_arr[1]."\n";
if ($printer_nom=~/name/) {
} else {
print OUT_SQL "INSERT INTO printers (invn_printer,room_nom,mac_printer,ip_printer) VALUES ('".
$printer_nom."',".
@t_arr[1].",'".
$qqq_mac."'::macaddr,'".
$ip_host."'::inet);\n";
print "\n".'lpadmin -p '.'N-'.$printer_nom.' -L "KOMHATA-'.@t_arr[1].'" -D "'.@
drv_arr[0].'" -v socket://'.$printer_nom.'.mydomain.oao -m '.@drv_arr[1]." -E \n";
#system('lpadmin -p '.'N-'.$printer_nom.' -L "KOMHATA-'.@t_arr[1].'" -D "'.@drv_arr[0].'" -v socket://'.
$printer_nom.'.mydomain.oao -m '.@drv_arr[1].' -E');
#system('lpadmin -p '.'K'.@t_arr[1].' -L "KOMHATA-'.@t_arr[1].'" -D "'.@drv_arr[0].
# '" -v socket://'.$printer_nom.'.mydomain.oao -m '.@drv_arr[1].' -E');
}
}
}
$f3com_port=find_3com('192.168.100.121',$qqq_mac);
if ($f3com_port > 0) {
print "2fport=".$f3com_port." ";
print "port ".sw3com_port_descr('192.168.100.121',$f3com_port);
print "\n";
$port_descr=sw3com_port_descr('192.168.100.121',$f3com_port);
if ($port_descr=~/room/) {
@t_arr=split(/\_/,$port_descr);
print "Room ".@t_arr[1]."\n";
if ($printer_nom=~/name/) {
} else {
print OUT_SQL "INSERT INTO printers (invn_printer,room_nom,mac_printer,ip_printer) VALUES ('".
$printer_nom."',".
@t_arr[1].",'".
$qqq_mac."'::macaddr,'".
$ip_host."'::inet);\n";
print "\n".'lpadmin -p '.'N-'.$printer_nom.' -L "KOMHATA-'.@t_arr[1].'" -D "'.@
drv_arr[0].'" -v socket://'.$printer_nom.'.mydomain.oao -m '.@drv_arr[1]." -E \n";
#system('lpadmin -p '.'N-'.$printer_nom.' -L "KOMHATA-'.@t_arr[1].'" -D "'.
#@drv_arr[0].'" -v socket://'.$printer_nom.'.mydomain.oao -m '.@drv_arr[1].' -E');
#system('lpadmin -p '.'K'.@t_arr[1].' -L "KOMHATA-'.@t_arr[1].'" -D "'.
#@drv_arr[0].'" -v socket://'.$printer_nom.'.mydomain.oao -m '.@drv_arr[1].' -E');
}
}
}
$f3com_port=find_3com('192.168.100.120',$qqq_mac);
if ($f3com_port > 0) {
print "3fport=".$f3com_port." ";
print "port ".sw3com_port_descr('192.168.100.120',$f3com_port);
print "\n";
$port_descr=sw3com_port_descr('192.168.100.120',$f3com_port);
if ($port_descr=~/room/) {
@t_arr=split(/\_/,$port_descr);
print "Room ".@t_arr[1]."\n";
if ($printer_nom=~/name/) {
} else {
print OUT_SQL "INSERT INTO printers (invn_printer,room_nom,mac_printer,ip_printer) VALUES ('".
$printer_nom."',".
@t_arr[1].",'".
$qqq_mac."'::macaddr,'".
$ip_host."'::inet);\n";
print "\n".'lpadmin -p '.'N-'.$printer_nom.' -L "KOMHATA-'.@t_arr[1].'" -D "'.@
drv_arr[0].'" -v socket://'.$printer_nom.'.mydomain.oao -m '.@drv_arr[1]." -E \n";
#system('lpadmin -p '.'N-'.$printer_nom.' -L "KOMHATA-'.@t_arr[1].'" -D "'.
#@drv_arr[0].'" -v socket://'.$printer_nom.'.mydomain.oao -m '.@drv_arr[1].' -E');
#system('lpadmin -p '.'K'.@t_arr[1].' -L "KOMHATA-'.@t_arr[1].'" -D "'.
#@drv_arr[0].'" -v socket://'.$printer_nom.'.mydomain.oao -m '.@drv_arr[1].' -E');
}
}
}
print "\n";
}
}
}
close(OUT_SQL);
exit 0;
$qqq_mac=ip_to_mac($qqq_ip);
if ($qqq_mac=~/\:00\:00\:/) {
} else {
#print "Ip=".$qqq_ip." Finding_MAC=".$qqq_mac." ";
#print "3fport=".find_alied('10.0.0.244',$qqq_mac).",";
$fsmc_port=find_smc('192.168.100.144',$qqq_mac);
print "Mport=".$fsmc_port.",";
print "port Descr ".swsmc_port_descr('192.168.100.144',$fsmc_port)." ";
$f3com_port=find_3com('192.168.100.121',$qqq_mac);
print "2fport=".$f3com_port." ";
print "port Descr ".sw3com_port_descr('192.168.100.121',$f3com_port);
print "\n";
}
#}
#print "port=".find_alied('10.0.0.244','00:0C:46:F2:4A:41');
#print "port=".find_smc('192.168.100.144','00:0C:46:F2:4A:41');
#print "port=".find_3com('192.168.100.121','00:0C:46:F2:4A:41');
sub find_alied {
my $q_switch_ip=shift(@_);
my $q_mac=shift(@_);
my $t;
my $sss;
my $r_port=0;
$t=new Net::Telnet(prompt=>'/Manager|--More--/');
$t->open($q_switch_ip);
$t->login('manager','friend');
$t->errmode('return');
@lines=$t->cmd(String=>'show switch fdb address='.$q_mac);
foreach $sss (@lines) {
if ($sss=~'ynamic') {
#print " MAC=".$q_mac.' found on=>'.substr($sss,19,3)."\n";
$r_port=substr($sss,19,3);
}
}
@lines=$t->cmd(String=>'quit');
$t->close;
return $r_port;
}
sub find_3com {
my $q_switch_ip=shift(@_);
my $q_mac=shift(@_);
my $t;
my $sss;
my $r_port=0;
$t=new Net::Telnet(prompt=>'/ption:/');
$t->open($q_switch_ip);
$t->login('admin','');
$t->errmode('return');
$q_mac=~s/\:/\-/g;
@lines=$t->cmd(String=>'br add find '.$q_mac);
foreach $sss (@lines) {
if ($sss=~'ort') {
#print " MAC=".$q_mac.' found on=>'.substr($sss,12,3)."\n";
$r_port=substr($sss,12,3);
}
}
$r_port=~s/\ //g;
$t->close;
return $r_port;
}
sub find_smc {
my $q_switch_ip=shift(@_);
my $q_mac=shift(@_);
my $t;
my $sss;
my $r_port=0;
$t=new Net::Telnet(prompt=>'/Vty-[0123456789]|---More---/');
$t->open($q_switch_ip);
$t->login('admin','admin');
$t->errmode('return');
$q_mac=~s/\:/\-/g;
@lines=$t->cmd(String=>'show mac-address-table address '.$q_mac);
foreach $sss (@lines) {
if ($sss=~'earned') {
#print " MAC=".$q_mac.' found on=>'.substr($sss,index($sss,'/')+1,2)."\n";
$r_port=substr($sss,index($sss,'/')+1,2);
}
}
$r_port=~s/\ //g;
@lines=$t->cmd(String=>'quit');
$t->close;
return $r_port;
}
sub ip1_to_mac {
my $ip_dst=shift(@_);
my $tmp_str;
my @arr1;
my $r_mac='00:00:00:00:00:00';
open(IN_CMD,'arping -c 1 '.$ip_dst.' |');
while ($tmp_str=) {
if ($tmp_str=~/reply/) {
@arr1=split(' ',$tmp_str);
$r_mac=@arr1[4];
$r_mac=~s/\[//g;
$r_mac=~s/\]//g;
}
}
close IN_CMD;
return $r_mac;
}
sub ip_to_mac {
my $ip_dst=shift(@_);
my $tmp_str;
my $ip_adr;
my @arr1;
my $r_mac='00:00:00:00:00:00';
#print 'ping -c3 '.$ip_dst.' ';
system('ping -c1 '.$ip_dst.' > /dev/null ');
open(IN_CMD,'arp -n |');
while ($tmp_str=) {
$ip_adr=substr($tmp_str,0,15);
$ip_adr=~s/\ //g;
#192.168.100.15 ether 00:0D:61:20:2A:5A C eth0
if (index($ip_dst,$ip_adr) == 0) {
if (length($ip_dst) == length($ip_adr)) {
#@arr1=split(' ',$tmp_str);
#$r_mac=@arr1[4];
#$r_mac=~s/\[//g;
#$r_mac=~s/\]//g;
if ($tmp_str=~/incomplete/) {
$r_mac='00:00:00:00:00:00';
} else {
$r_mac=substr($tmp_str,33,17);
#print $tmp_str;
}
}
}
}
close IN_CMD;
return $r_mac;
}
sub sw3com_port_descr {
my ($session, $error) = Net::SNMP->session(
-hostname => shift(@_),
-community => 'public',
-port => 161
);
my $r_descr= "";
my $port_num=shift(@_);
if (!defined($session)) {
#printf("ERROR: %s.\n", $error);
return " Error";
}
#my $ifDescr = '1.3.6.1.2.1.2.2.1.2.101';
my $real_q=$port_num + 100;
my $ifDescr = '1.3.6.1.2.1.31.1.1.1.18.'.$real_q;
#print '******** '.$ifDescr.' **********';
my $result = $session->get_request(
-varbindlist => [$ifDescr]
);
if (!defined($result)) {
#printf("ERROR: %s.\n", $session->error);
$session->close;
return " Error";
}
#printf(" '%s' Port Descris %s\n",
#$session->hostname, $result->{$ifDescr}
#);
$r_descr=$result->{$ifDescr};
$session->close;
return $r_descr;
}
sub sw_smc_port_descr {
my $q_switch_ip=shift(@_);
my $q_port=shift(@_);
my $t;
my $sss;
my $r_port="";
$t=new Net::Telnet(prompt=>'/Vty-[0123456789]|---More---/');
$t->open($q_switch_ip);
$t->login('admin','admin');
$t->errmode('return');
$q_mac=~s/\:/\-/g;
@lines=$t->cmd(String=>'show interface status ethernet 1/'.$q_mac);
foreach $sss (@lines) {
if ($sss=~'Name:') {
#print " MAC=".$q_mac.' found on=>'.substr($sss,index($sss,'/')+1,2)."\n";
$r_port=substr($sss,index($sss,'Name:')+5,10);
}
}
$t->close;
return $r_port;
}
sub swsmc_port_descr {
my ($session, $error) = Net::SNMP->session(
-hostname => shift(@_),
-community => 'public',
-port => 161
);
my $r_descr= "";
my $port_num=shift(@_);
if (!defined($session)) {
#printf("ERROR: %s.\n", $error);
return " Error";
}
#my $ifDescr = '1.3.6.1.2.1.2.2.1.2.101';
my $real_q=$port_num + 100;
my $ifDescr = '1.3.6.1.2.1.31.1.1.1.18.'.$port_num;
#print '******** '.$ifDescr.' **********';
my $result = $session->get_request(
-varbindlist => [$ifDescr]
);
if (!defined($result)) {
#printf("ERROR: %s.\n", $session->error);
$session->close;
return " Error";
}
#printf(" '%s' Port Descris %s\n",
#$session->hostname, $result->{$ifDescr}
#);
$r_descr=$result->{$ifDescr};
$session->close;
return $r_descr;
}
sub get_iface_nets {
my @ret_arr;
my $dst_route;
my @arr_tmp;
open (CMD_NETSTAT_R,"netstat -r -n |");
while ($tmp_str=) {
#10.10.4.0 0.0.0.0 255.255.255.0 U 0 0 0 eth2.1001
if ($tmp_str=~/eth/) {
$dst_route=substr($tmp_str,17,15);
$dst_route=~s/\ //g;
if (index($tmp_str,'0.0.0.0') == 16) {
#print $tmp_str;
$iface_name=substr($tmp_str,73,15);
$iface_name=~s/\ //g;
$net_adr=substr($tmp_str,0,15);
$net_adr=~s/\ //g;
@arr_tmp=split(/\./,$net_adr);
$net_adr=@arr_tmp[0].'.'.@arr_tmp[1].'.'.@arr_tmp[2];
#print "Net ".$net_adr." ".$iface_name."\n";
push @ret_arr,$iface_name.','.$net_adr;
}
}
}
return @ret_arr;
}
#sub get_lis
sub scan_nmap {
my $req_adr=shift(@_);
my $tmp_str;
my @r_arr;
open (CMD_NMAP,'nmap -sP '.$req_adr.' |');
while ($tmp_str=) {
if ($tmp_str=~/Host/) {
if ($tmp_str=~/\(/) {
@arr_tmp=split(/ /,$tmp_str);
$ip_adr=@arr_tmp[2];
} else {
@arr_tmp=split(/ /,$tmp_str);
$ip_adr=@arr_tmp[1];
}
$ip_adr=~s/\(//g;
$ip_adr=~s/\)//g;
print $ip_adr."\n";
push @r_arr,$ip_adr;
}
}
return @r_arr;
}
sub get_printer {
my ($session, $error) = Net::SNMP->session(
-hostname => shift(@_),
-community => 'public',
-port => 161,
-timeout => 1
);
my $r_descr= "";
#my $port_num=shift(@_);
if (!defined($session)) {
#printf("ERROR: %s.\n", $error);
return " Error";
}
#my $ifDescr = '1.3.6.1.2.1.2.2.1.2.101';
#my $real_q=$port_num + 100;
#my $ifDescr = '1.3.6.1.2.1.31.1.1.1.18.'.$port_num;
my $ifDescr = '1.3.6.1.4.1.11.2.3.9.1.1.7.0';
#print '******** '.$ifDescr.' **********';
my $result = $session->get_request(
-varbindlist => [$ifDescr]
);
if (!defined($result)) {
#printf("ERROR: %s.\n", $session->error);
$session->close;
return " Error";
}
#printf(" '%s' Port Descris %s\n",
#$session->hostname, $result->{$ifDescr}
#);
$r_descr=$result->{$ifDescr};
$session->close;
if ($r_descr =~ /PRINTER/ ) {
} else {
return " Error";
}
return $r_descr;
}
sub get_printer_name {
my ($session, $error) = Net::SNMP->session(
-hostname => shift(@_),
-community => 'public',
-port => 161,
-timeout => 1
);
my $r_descr= "";
#my $port_num=shift(@_);
if (!defined($session)) {
#printf("ERROR: %s.\n", $error);
return " Error";
}
#my $ifDescr = '1.3.6.1.2.1.2.2.1.2.101';
#my $real_q=$port_num + 100;
#my $ifDescr = '1.3.6.1.2.1.31.1.1.1.18.'.$port_num;
my $ifDescr = '1.3.6.1.2.1.1.5.0';
#print '******** '.$ifDescr.' **********';
my $result = $session->get_request(
-varbindlist => [$ifDescr]
);
if (!defined($result)) {
#printf("ERROR: %s.\n", $session->error);
$session->close;
return " Error";
}
#printf(" '%s' Port Descris %s\n",
#$session->hostname, $result->{$ifDescr}
#);
$r_descr=$result->{$ifDescr};
return $r_descr;
}
sub get_drv {
my $dsc_str=shift(@_);
my @tmp_arr;
my $pos_mdl;
my $count_mdl;
my $name_drv;
my $drv_dsc;
my $tmp_str;
if (index($dsc_pr,'MDL:') > 0 ) {
$pos_mdl=index($dsc_pr,'MDL:');
$count_mdl=index($dsc_pr,';',$pos_mdl)-$pos_mdl;
$name_drv=substr($dsc_pr,$pos_mdl+4,$count_mdl-4);
} else {
$pos_mdl=index($dsc_pr,'MODEL:');
$count_mdl=index($dsc_pr,';',$pos_mdl)-$pos_mdl;
$name_drv=substr($dsc_pr,$pos_mdl+6,$count_mdl-6);
}
$name_drv=~s/HP\ //g;
$name_drv=~s/hp\ //g;
$name_drv=~s/series//g;
open(CMD_LPINFO,'lpinfo -m |');
while ($tmp_str=) {
if (index($tmp_str,$name_drv) > 0) {
$drv_dsc=substr($tmp_str,0,index($tmp_str,' '));
}
}
close(CMD_LPINFO);
return $name_drv.';'.$drv_dsc;
}
Скрипт формирует файл для postgres c информацией о принтерах. Скрипт
должен выполняться на маршрутизаторе или сервере, который имеет доступ
ко всем принтерам сети.