#!/usr/bin/perl -w
use strict; use Curses; use Curses::Widgets; use Curses::Widgets::Label; use Curses::Widgets::ListBox; use Net::PcapUtils; use Time::HiRes qw(sleep time); my %from_ip_byte; my %to_ip_byte; my $total_in=0; my $total_out=0; my $lasttime=0; my $localip="192.168.1.1"; my @pkg;
my $mwh=new Curses; #my %attr={
# A_ALTCHARSET=> "字符交替",
# A_ATTRIBUTES=>"",
# A_BLINK=>"闪动显示",
# A_BOLD=>"加亮加粗",
# A_CHARTEXT=>"字符掩盖",
# A_COLOR =>"",
# A_DIM =>"半亮显示",
# A_INVIS =>"空白显示模式",
# A_NORMAL=>"不加亮显示",
# A_PROTECT =>"保护模式",
# A_REVERSE =>"反白显示",
# A_STANDOUT =>"终端字符最亮",
# A_UNDERLINE=>"下划线",
# COLOR_PAIR=>"前景、背景色设置",
# };
initscr(); #初始化为curses模式,清屏
if(has_colors() == 0) { #判断是否支持颜色显示
endwin(); printf("Terminal does not support color\n"); } start_color(); #开启彩色显示功能
init_color(COLOR_RED,700,0,0); #改变模个颜色的RGB
init_pair(1,COLOR_WHITE,COLOR_BLUE); #raw(); #禁用行缓冲,控制字符将不作为终端程序处理的信号,交给程序处理
#cbreak(); #禁用行缓冲,控制字符将被认为是终端控制字符
#echo(); #字符在终端中显示
#noecho(); #字符不在终端中显示
#keypad(stdscr,1); #允许使用功能键(F1 F2 方向键等) stdscr为标准显示设备
#halfdelay(2); #启用半延时模式,没有有效输入返回ERR,常用于密码输入超时等
#addch/addstr/attrset/mvprintw/mvwprintw/wprintw #在c的curses中有,perl没有
#scanw/mvscanw/wscanw/mvwscanw/vwscanw/getstr #在c的curses中有,perl没有
#getyx
##subwin(20,80,0,0); #建立窗体
##box(0,0); #给$win绘制边框
##refresh(stdscr);
#delwin(stdscr);
noecho(); halfdelay(0.2); $mwh->keypad(1); $mwh->syncok(1); curs_set(0); leaveok(1); Net::PcapUtils::loop(\&process_pkt);
sub process_pkt { my($arg, $hdr, $pkt) = @_; my($packages)=unpack('H*', $pkt); ### START PACKAGE INFO ###
my(%PACKTYPE)=('0800'=>'IP', '0806'=>'ARP', '8035'=>'RARP'); my($source_mac)=substr($packages,0,12); my($dest_mac)=substr($packages,12,12); my($type)=substr($packages,24,4);
$type=$PACKTYPE{$type}; ### START IP HEAD ###
#if ($type eq IP) {
if (defined $type) { if ($type eq $PACKTYPE{'0800'}) { ## get ip head info ##
my($totlength)=hex(substr($packages,32,4)); my($protocol)=substr($packages,46,2); my($sourceipA)=hex(substr($packages,52,2)); my($sourceipB)=hex(substr($packages,54,2)); my($sourceipC)=hex(substr($packages,56,2)); my($sourceipD)=hex(substr($packages,58,2)); my($sourceip)=$sourceipA . "." . $sourceipB . "." . $sourceipC . "." . $sourceipD;
my($destipA)=hex(substr($packages,60,2)); my($destipB)=hex(substr($packages,62,2)); my($destipC)=hex(substr($packages,64,2)); my($destipD)=hex(substr($packages,66,2)); my($destip)=$destipA . "." . $destipB . "." . $destipC . "." . $destipD;
my(%TCPORUDP)=('06'=>'TCP', '17'=>'UDP'); $protocol=$TCPORUDP{$protocol}; ### END IP HEAD ###
### START TCP HEAD ###
if (defined $protocol) { if ($protocol eq $TCPORUDP{'06'}) { #if ($protocol eq TCP) {
my($sourceport)=hex(substr($packages,68,4)); my($destport)=hex(substr($packages,72,4)); my $pkg=sprintf("%16s:%-5s\t->\t%16s:%-5s\t%s",$sourceip,$sourceport,$destip,$destport,$protocol); push(@pkg,$pkg); ### END TCP HEAD ###
### PRINT INFO ###
if (!(defined $from_ip_byte{$sourceip})) { $from_ip_byte{$sourceip}=0; } if (!(defined $to_ip_byte{$destip})) { $to_ip_byte{$destip}=0; } if ($sourceip eq $destip) { #local
} elsif ($sourceip eq $localip) { #out
$total_out=$total_out+$totlength; if (!(defined $from_ip_byte{$destip})) { $from_ip_byte{$destip}=0; } if (!(defined $to_ip_byte{$destip})) { $to_ip_byte{$destip}=0; } $from_ip_byte{$destip}=$from_ip_byte{$destip}+0; $to_ip_byte{$destip}=$to_ip_byte{$destip}+$totlength; } elsif ($destip eq $localip) { #in
$total_in=$total_in+$totlength; if (!(defined $from_ip_byte{$sourceip})) { $from_ip_byte{$sourceip}=0; } if (!(defined $to_ip_byte{$sourceip})) { $to_ip_byte{$sourceip}=0; } $from_ip_byte{$sourceip}=$from_ip_byte{$sourceip}+$totlength; $to_ip_byte{$sourceip}=$to_ip_byte{$sourceip}+0; } } } } } ### END PACKAGE INFO ###
my @list; if ((time - $lasttime)>0.5) { my $y=2; my $x=1; attron(A_UNDERLINE | A_BOLD | COLOR_PAIR(1)); #开启字符修饰效果
move($y,$x); #将光标移动到 (行,列)
#printw(" IP: %s IN_BYTES:%12.2fKbyte\tOUT_BYTES:%12.2fKbyte",$localip,$total_in/1024,$total_out/1024);
my $head=sprintf(" IP: %s IN_BYTES:%.2fKbyte OUT_BYTES:%.2fKbyte",$localip,$total_in/1024,$total_out/1024); $y=$y+2; foreach my $key (keys %from_ip_byte) { my $in_per=0; my $out_per=0; if ($total_in > 0) { $in_per=$from_ip_byte{$key}*100/$total_in; } else { $in_per=0; } if ($total_out>0) { if (defined $to_ip_byte{$key}) { $out_per=$to_ip_byte{$key}*100/$total_out; } else { $out_per=0; } } else { $out_per=0; } #my $out="$key $from_ip_byte{$key}($in_per\%) \t$to_ip_byte{$key}($out_per\%)";
move($y,$x); #将光标移动到 (行,列)
#printw("%16s\tIN:%11.2fM (%5.2f%s)\tOUT:%11.2fM (%5.2f%s)",$key,$from_ip_byte{$key}/1024,$in_per,"%",$to_ip_byte{$key}/1024/1024,$out_per,"%");
if (!(defined $from_ip_byte{$key})) { $from_ip_byte{$key}=0; } if (!(defined $to_ip_byte{$key})) { $to_ip_byte{$key}=0; } my $in=$from_ip_byte{$key}/1048576; my $out=$to_ip_byte{$key}/1048576; my $line=sprintf("%16s\tIN:%11.2fM (%5.2f%s)\tOUT:%11.2fM (%5.2f%s)",$key,$in,$in_per,"%",$out,$out_per,"%"); push(@list,$line); $y++; } my $length=scalar(@list); $mwh->erase(); $mwh->attrset(COLOR_PAIR(select_color(qw(red blue)))); $mwh->box(ACS_VLINE, ACS_HLINE); $mwh->attrset(0); $mwh->standout(); $mwh->standend(); my($max_y,$max_x); $mwh->getmaxyx($max_y, $max_x); my $lines=10; my $columns=$max_x-2; my $widgets1 = Curses::Widgets::ListBox->new({ Y => 0, X => 0, COLUMNS => $columns, LINES => $lines, LISTITEMS => \@list, MULTISEL => 1, VALUE => [0,1], SELECTEDCOL => 'white', CAPTION => $head, CAPTIONCOL => 'yellow', FOREGROUND => 'white', BACKGROUND => 'blue', }); $widgets1->draw($mwh); my $widgets2 = Curses::Widgets::ListBox->new({ Y => 12, X => 0, COLUMNS => $columns, LINES => $max_y-$lines-4, LISTITEMS => [], MULTISEL => 0, # VALUE => 0,
SELECTEDCOL => 'white', # CAPTION => $head,
CAPTIONCOL => 'yellow', FOREGROUND => 'white', BACKGROUND => 'blue', }); $widgets2->draw($mwh); my $yy=13; my $xx=2; while ($yy< $max_y){ my $pkg=shift @pkg; move($yy,$xx); if (defined $pkg) { printw("$pkg"); } else { printw(""); } $yy++; } # move(11,2);
#attron(COLOR_WHITE,COLOR_BLUE); #关闭字符修饰效果
# printw("info");
#attroff(COLOR_WHITE,COLOR_BLUE); #关闭字符修饰效果
#attroff(COLOR_PAIR(1)); #关闭字符修饰效果
refresh(); $lasttime=time; } } exit 1;
|