#字段:交换机名称,冲突ip地址,source by MAC,后MAC,时间
# Jul 25 11:59:52 2010 XSGY8-MDF-7506R ARP/5/DUPIP:IP address 10.8.40.16 collision detected, sourced by 001e-c905-00b0 on GigabitEthernet2/0/7 of VLAN2084 and 001b-b9d1-9e70 on GigabitEthernet2/0/7 of VLAN2084
use strict;
use Gtk2 '-init';
use Glib qw(TRUE FALSE);
use Net::Telnet;
use Encode qw(decode);
use constant CONF_FILE => 'conf.ini';
our $pass;
my @headers=('交换机名称','冲突IP','souece-by-MAC','MAC','时间');
my @attact_info;
#设置字体
Gtk2::Rc->parse_string(qq(style "default-font"\n{\nfont_name = "simsun 9"\n}\nwidget_class "*" style "default-font"\ngtk-font-name = "simsun 9"));
my $win=Gtk2::Window->new('toplevel');
$win->set_position('center_always');
$win->set_title(to_gbk('交换机ARP攻击日志检查' ));
$win->set_size_request(550,350);
#create Global hbox
my $g_hbox=Gtk2::HBox->new(FALSE,4);
#creat vbox_sider
my $vbox_sider=Gtk2::VBox->new(FALSE,4);
#create vbox
my $vbox=Gtk2::VBox->new(FALSE,4);
#create top hbox
my $top_hbox=Gtk2::HBox->new(FALSE,4);
#create sider button
my $btn_export=Gtk2::Button->new(to_gbk( '导出' ));
my $btn_description=Gtk2::Button->new(to_gbk( '说明' ));
my $btn_set_pass = Gtk2::Button->new(to_gbk('设置密码'));
#create label
my $lb=Gtk2::Label->new(to_gbk( '你想查哪栋:' ));
my $state_lb=Gtk2::Label->new();
$state_lb->set_justify('center');
#create search button
my $btn_search=Gtk2::Button->new(to_gbk( '我搜' ));
#create ScrolledWindow
my $sw = Gtk2::ScrolledWindow->new;
$sw->set_policy ('automatic', 'automatic');
#create entry
my $entry = Gtk2::Entry->new();
#create model
my $model=Gtk2::ListStore->new(split(" ", "Glib::String " x scalar(@headers)));
# create TreeView
my $treeview = Gtk2::TreeView->new_with_model($model);
#pack button into sider
$vbox_sider->pack_start($btn_export,FALSE,FALSE,0);
$vbox_sider->pack_start($btn_set_pass,FALSE,FALSE,0);
$vbox_sider->pack_start($btn_description,FALSE,FALSE,0);
#pack into top_hbox
$top_hbox->pack_start($lb,FALSE,FALSE,0);
$top_hbox->pack_start($entry,FALSE,FALSE,0);
$top_hbox->pack_start($btn_search,FALSE,FALSE,2);
$top_hbox->pack_start($state_lb,FALSE,FALSE,2);
#pack treeview into sw
$sw->add($treeview);
#pack top_hbox into vbox
$vbox->pack_start($top_hbox,FALSE,FALSE,0);
$vbox->pack_start($sw,TRUE,TRUE,0);
#pack sider
$g_hbox->pack_start($vbox_sider,FALSE,FALSE,4);
#pack hbox
$g_hbox->pack_start($vbox,TRUE,TRUE,0);
#pack g_hbox into window
$win->add($g_hbox);
#callback
$win->signal_connect('delete_event' => sub { Gtk2->main_quit; });
$btn_search->signal_connect(clicked => \&search);
$btn_set_pass->signal_connect(clicked => \&set_pass_word);
$btn_description->signal_connect(clicked => \&description);
$btn_export->signal_connect(clicked => \&export);
add_columns($treeview);
$pass = get_pwd_from_file();
$win->show_all();
Gtk2->main();
sub get_pwd_from_file
{
my $pwd;
-e CONF_FILE || open FH,">",CONF_FILE;
open FH,"<",CONF_FILE;
while(<FH>)
{
chomp;
next if /^\s+$/g;
next if /^[;\[]/g;
($pwd) = /^pwd=(.*)/;
}
close FH;
return $pwd||='switch'; #默认密码为switch
}
sub search
{
my $btn=shift;
$model->clear();#预防再次搜索时,结果重复
my $sushe=$entry->get_text();
# eval
# {
# my $telnet=&connect("172.17.$sushe.1");
# login($telnet,$pass);
# get_log($telnet);
# disconnect($telnet);
# };
# alert($@) if $@;
my $attact_counter=parse_arp_info();
foreach my $info (@attact_info)
{
my $iter = $model->append();
my ($time,$switcher,$ip_addr,$smac,$mac)=@$info;
$model->set($iter,0,$switcher,1,$ip_addr,2,$smac,3,$mac,4,$time);
}
$state_lb->set_text(to_gbk( "找到$attact_counter例ARP攻击" ));
}
sub set_pass_word
{
my $btn = shift;
my $top = $btn->get_toplevel;
my $dia = Gtk2::Dialog->new(
to_gbk('设置连接密码'), $top,
'modal',
'gtk-ok' => 'ok',
'gtk-cancel' => 'cancel',
);
$dia->set_size_request(200,100);
$dia->set_resizable(FALSE);
my $frame = Gtk2::Frame->new(to_gbk('设置新密码'));
my $vbox = $dia->vbox;
my $hbox = Gtk2::HBox->new(FALSE,2);
my $lb = Gtk2::Label->new(to_gbk('新密码:'));
my $pass_word = Gtk2::Entry->new();
$pass_word->set_visibility(FALSE);
$pass_word->set_invisible_char('*');
$hbox->pack_start($lb,FALSE,FALSE,0);
$hbox->pack_start($pass_word,TRUE,TRUE,0);
$frame->add($hbox);
$vbox->pack_start($frame,TRUE,TRUE,1);
$dia->show_all();
my $return_val = $dia->run();
if($return_val eq 'ok')
{
$pass = $pass_word->get_text();
save_to_config($pass);
}
$dia->destroy();
}
sub save_to_config
{
my $pwd = shift;
open OUT,">",CONF_FILE;
print OUT "pwd=$pwd\n";
close OUT;
}
sub add_columns
{
my $treeview=shift;
for(my $i=0;$i<=$#headers;$i++)
{
$treeview->insert_column_with_attributes($i, to_gbk( $headers[$i]),Gtk2::CellRendererText->new(),'text' ,$i );
$treeview->get_column($i)->set_sort_column_id($i);
}
}
sub connect
{
my $host=shift;
my $telnet=Net::Telnet->new(Timeout => 10);
$telnet->open($host);
return $telnet;
}
sub login
{
my $telnet=shift;
my $pwd = shift;
my $msg='密码错误';
$telnet->waitfor('/password:*$/i');
$telnet->print($pwd);
my $match=($telnet->waitfor(match =>'/wrong password/i',errmode => 'return',Timeout => 3))[1];
die $match if $match;
return $telnet;
}
sub get_log
{
my $telnet=shift;
$telnet->print("dis log");
my $file='log.txt';
open OUT,">",$file;
while(1)
{
my ($line,$match)=$telnet->waitfor(match=>'/more/i',errmode => 'return');
last unless $match;
$telnet->print("\n");
print $line;
print OUT $line;
}
close OUT;
}
sub disconnect
{
$_[0]->close;
}
sub parse_arp_info
{
my $file='arp-log.txt';
undef @attact_info;
open IN,"<",$file;
while(<IN>)
{
s{!^%}{};
if(/arp\/5/i)
{
s{--.*%}{};
my @info=$_=~/(.*\d+)\s+(.*?)\s+.*?(\d{1,3}\.\d{1,3}.\d{1,3}.\d{1,3}).*by\s+(.*?)\s+.*\s+(.*)\s+on.*/ig;
push @attact_info,\@info;
}
}
close IN;
return scalar @attact_info;
}
sub description
{
my $btn = shift;
my $top = $btn->get_toplevel;
my $msg="字段source by MAC:可能是冲突主机\n字段MAC:可能是受害主机";
my $dia = Gtk2::MessageDialog->new(
$top, 'destroy-with-parent',
'info',
'ok',
"%s", to_gbk( $msg)
);
$dia->run();
$dia->destroy();
}
sub export
{
my $btn=shift;
my $top=$btn->get_toplevel();
my $save_dia=Gtk2::FileChooserDialog->new(to_gbk( '导出为' ), $top, 'save','gtk-cancel' => 'cancel','gtk-save' => 'ok');#可以将'=>'改为','
my $filter=create_filter();
$save_dia->add_filter($filter);
$save_dia->show();
$save_dia->signal_connect(response => \&save);
}
sub create_filter
{
my ($name,$file_type)=('文本文件','*.txt');
my $filter = Gtk2::FileFilter->new();
$filter->set_name(to_gbk( $name));
$filter->add_pattern($file_type);
return $filter;
}
sub save
{
my ($dia, $response_id) = @_;
if($response_id eq 'ok')
{
my $file_name=$dia->get_filename().'.txt';
if (is_file_exist($file_name))
{
over_write($dia,$file_name);
}
else
{
write2file($file_name);
$dia->destroy();
}
}
else
{
$dia->destroy();
}
}
sub alert
{
my $msg=shift;
$msg=~s{(at.*)}{}g;
my $dia = Gtk2::MessageDialog->new(
$win, 'destroy-with-parent',
'error',
'ok',
"%s", to_gbk($msg)
);
$dia->run();
$dia->destroy();
}
sub to_gbk
{
my $encoding = "gbk";
return decode($encoding,shift);
}
sub is_file_exist
{
my $file_name=shift;
return -e $file_name;
}
sub over_write
{
my ($parent_dia,$file_name) = @_;
my $msg= '"'.$file_name.'"已存在,是否覆盖?';
my $dia=Gtk2::MessageDialog->new($parent_dia,'destroy-with-parent','question','yes-no',"%s",to_gbk($msg));
$dia->show();
$dia->signal_connect(response => sub{
my ($dia,$re_id)=@_;
if ($re_id eq 'yes')
{
write2file($file_name);
$parent_dia->destroy();
}
$dia->destroy();}
);
}
sub write2file
{
open OUT,">",shift;
for (@attact_info)
{
my ($time,$switcher,$ip_addr,$smac,$mac)=@$_;
print OUT join ",",($switcher,$ip_addr,$smac,$mac,$time);
}
close OUT;
}
|