会计考友 发表于 2012-8-4 12:13:19

Linux系统Perl精简版netstat

写作意图:
  Linux系统自带的netstat在很多时候抓信息会发现耗CPU很高,特别是在做一些监控系统的时候,发现如果使用了netstat,监控系统本身会造成系统负载比较高,因此试着用perl写下,time测试比自带的netstat更快更节省资源,青年人网提示欢迎批评,呵呵。
  #!/usr/bin/perl
  # Written by FinalBSD at 2008-11-20.
  # The netstat original written by C
  # is expensive to me, so this born.
  # As long as you retain this notice you
  # can do whatever you want with this stuff.
  # If we meet some day, and you think
  # this stuff is worth it, you can
  # buy me a beer in return.
  use strict;
  use warnings;
  use Getopt::Std;
  my $tcp = "/proc/net/tcp";
  my $tcp6 = "/proc/net/tcp6";
  my $route = "/proc/net/route";
  my @tcpState = (
  "NULL",
  "ESTABLISHED" ,
  "SYN_SENT",
  "SYN_RECV",
  "FIN_WAIT1",
  "FIN_WAIT2",
  "TIME_WAIT",
  "CLOSE",
  "CLOSE_WAIT",
  "LAST_ACK",
  "LISTEN",
  "CLOSING"
  );
  my @routeType = (
  "NULL",
  "U", # UP
  "G", # Gateway
  "UG" # UP & Gateway
  );

会计考友 发表于 2012-8-4 12:13:20

Linux系统Perl精简版netstat

  my %opts;
  getopts('nhatsrl', \%opts);
  if($opts{h}) {
  &usage();
  }
  if($opts{r}) {
  &route_info($route);
  exit;
  }
  &tcp_info($tcp);
  &tcp_info($tcp6);
  ######## FUNCTION DEFINITION ######
  #############################
  # Get statistics Information
  ############################
  sub tcp_info($) {
  my $file = shift;
  open(FH, $file) or die("$!");
  my $format = "%-30s %-30s %-10s\n";
  printf($format," Local Address"," Foreign Address","State");
  while() {
  next if /local_address/;
  my @data = split;
  my $state = $tcpState)];
  # Show listening Sockets.
  if($opts{l}){
  printf($format, &hextoint($data), &hextoint($data), $state) if $state =~ /LIST/;
  } else {
  printf($format, &hextoint($data), &hextoint($data), $state);
  }
  }
  close(FH);
  }
  #############################
  # Convert hex to int
  ############################
  sub hextoint($) {
  my $tmp = shift;
  my @data;
  my @ip;
  my $int;
  # if have ':', then it's addr:port,else just port.
  if( $tmp =~ /:/ ) {
  if( $tmp =~ /FFFF/ ) {
  @data = split /:/, $tmp;
  # break it and do convert later.
  @ip = $data =~ /\w{2}/g;
  foreach my $index (12..15){
  $ip[$index] = hex($ip[$index]);
  }
  $int = sprintf("%-5s %d.%d.%d.%d:%d", "tcp6",$ip, $ip, $ip, $ip, hex($data));
  } else {
  @data = split /:/, $tmp;
  @ip = $data =~ /\w{2}/g;
  foreach my $index (0..3){
  $ip[$index] = hex($ip[$index]);
  }
  $int = sprintf("%-s %d.%d.%d.%d:%d", " ",$ip, $ip, $ip, $ip, hex($data));
  }

会计考友 发表于 2012-8-4 12:13:21

Linux系统Perl精简版netstat

  } else {
  @ip = $tmp =~ /\w{2}/g;
  foreach my $index (0..3){
  $ip[$index] = hex($ip[$index]);
  }
  $int = sprintf("%d.%d.%d.%d", hex($ip), hex($ip), hex($ip), hex($ip));
  }
  return $int;
  }
  #############################
  # Show Kernel route table
  ############################
  sub route_info($) {
  my $routefile = shift;
  open(ROUTE, $routefile) or die ("Can't open route file!\n");
  my $header = "Iface Destination Gateway Flags Genmask\n";
  printf("%s", $header);
  my $format = "%-5s %-15s %-15s %-5s %-15s\n";
  while() {
  next if /Iface/;
  my @line = split;
  my ($iface, $dest, $gw, $flags, $mask ) = ($line, &hextoint($line), &hextoint($line), hex($line), &hextoint($line));
  printf($format, $iface, $dest, $gw, $routeType[$flags], $mask );
  }
  close(ROUTE);
  }
  #############################
  # Show help information
  ############################
  sub usage {
  printf("%s\n\n%-30s\n%-30s\n%-30s\n%-30s\n%-30s\n%-30s\n",
  "netstat written in Perl by FinalBSD.Copyright(c) 2008.",
  "-n Show numeric ip and port address.",
  "-r Display the kernel routing table.",
  "-a Show both listening and non-listening socktes.",
  "-t Show only TCP statistics.",
  "-l Show only listening sockets.",
  "-h Show help.",
  );
  exit;
  }
页: [1]
查看完整版本: Linux系统Perl精简版netstat