Net-Connection-Sniffer

 view release on metacpan or  search on metacpan

Sniffer.pm  view on Meta::CPAN

);
use Proc::PidUtil qw(
	if_run_exit
	is_running
	get_script_name
	make_pidfile
	zap_pidfile
);
use Net::DNS::Codes qw(  
	T_PTR
	T_SOA
	C_IN
	BITS_QUERY 
	RD
	NS_PACKETSZ
	HFIXEDSZ
	QUERY
	NOERROR
	NXDOMAIN
	SERVFAIL
);
use Net::DNS::ToolKit qw(
	get16
	getIPv4
	gethead
	newhead
	get_ns
);
use Net::DNS::ToolKit::RR;
#use Net::DNS::ToolKit::Debug qw(
#	print_head
#	print_buf
#);
use Sys::Sig qw(TERM KILL USR1);

bootstrap Net::Connection::Sniffer $VERSION;

# File GLOBAL variables

# define LIBNET_ETH_H	0x0e	/* Ethernet header:	14 bytes */
my $ETH_H = 14;
# define LIBNET_IPV4_H	0x14	/* IPv4 header:		20 bytes */
my $IPV4_H = 20;

#define LIBNET_IPV6_H	0x28	/* IPv6 header:		40 bytes */
#my $IPV6_H = 40;
## define LIBNET_TCP_H	0x14	/* TCP header:		20 bytes */
#my $TCP_H = 20;


#my $addr_off	= $ETH_H + 12;		# src address
#my $frag_off	= $ETH_H + 6;

my $minlen	= $ETH_H + $IPV4_H + 4;	# need port numbers at a minimum
my $snaplen 	= $minlen;

my $oneday	= 86400;			# WARNING, set in XS also
my $unique	= $$ -1;			# dns sequence number
my($match,$nomatch,$payoff);

my $af_inet6 = eval { AF_INET6() };
$af_inet6 = 0 if $@;

#################################################
##### global vars reset by HUP
my ($purge,$nxpurge);

##### global vars used in 'collect', 'dump_stats', elsewhere
#### WARNING, these are set in the XS portion also
my ($now, $start, $rate, $bw);

sub set_gvars {
  $now		= time;
  $start	= $now;
  $rate		= 0;				# global
  $bw		= 0;				# global
  p2xs_gvars($now, $start, $rate, $bw);		# reload xs vars from the module, clear 'hup', 'ra', 'ba'
}

##### global vars used in 'collect' or 'daemon'only
my ($dto);

sub set_globals() {
  set_gvars();
  $purge	= \&setpurge;			# starting purge routine
#  $ra		= 0E0;				# intermediate rate accumulator
#  $ba		= 0E0;				# intermediate bw accumulator
  $nxpurge	= 0;
  $dto		= $now + 15;
}

set_globals;

#my %subref;
#foreach(sort keys %Net::Connection::Sniffer::) {
#  my $subref = \&{"Net::Connection::Sniffer::$_"};
#  $Net::Connection::Sniffer::{$_} =~ /[^:]+$/;
#  $subref{$subref} = $&;
#}

my %dispatch = (
	&LISTEN_MSG	=> \&do_listen,
	&DNS_NEEDED	=> \&dns_send,
	&DUMP_REQUEST	=> \&dump_stats,
	&DNS_RECEIVE	=> \&dns_rcv,
	&PURGE		=> \&timer,
);

my $dnslookup = [];
my $stats = {
#       naddr	=> {
#		B	=> 5678,	# bytes accumulated
#		C	=> 1234,	# counts
#		E	=> 124444,	# count epoch
#		N	=> ['hostname',],	# hostname(s) for this IP
#		R	=> 2345,	# rate
#		S	=> 123456,	# count start time
#		T	=> 123455,	# TTL timeout of PTR record
#		W	=> 7890.	# bandWidth
#       },
};

Sniffer.pm  view on Meta::CPAN

# UDP dump port
  if ($port = $c->{port}) {
    bad_config("invalid port number '$c->{port}'")
	unless $port =~ /\d/ && $port !~ /\D/;
    if ($iaddr = $c->{host}) {
      if ($iaddr eq 'INADDR_LOOPBACK') {
	$iaddr = '127.0.0.1';
      }
      elsif ($iaddr eq 'INADDR_ANY') {
	$iaddr = '0.0.0.0';
      }
    } else {
      $c->{host} = $iaddr = '127.0.0.1';
    }
    bad_config("bad dump host '$c->{host}'")
	unless defined ($iaddr = inet_aton($iaddr));
    if ($c->{allowed} && @{$c->{allowed}}) {
      foreach (0..$#{$c->{allowed}}) {
	my $con = inet_aton($c->{allowed}->[$_]);
	bad_config("invalid 'allowed' host or IP '". $c->{allowed}->[$_] ."'")
		unless $con;
	push @allowed, $con;
      }
    } else {
      push @allowed, inet_aton('127.0.0.1');
    }
  }
}

sub clean_child() {
  my $pid = fork;
  if ($pid) {
    waitpid($pid,0);
    exit 0;
  }

  chdir '/';			# allow root dismount
  open STDIN, '/dev/null' or die "Can't dup STDIN to /dev/null: $!";
  open STDOUT, '>/dev/null' or die "Can't dup STDOUT to /dev/null: $!";
#open(STDOUT,">&STDERR");
#select STDERR;
#$| = 1;
#select STDOUT;
#$| = 1;
  exit 0 if $pid = fork;	# double fork to release instantiating terminal
}

#
# input:	ipv4 or ipv6 network address
# returns:	interface,
#		need promiscious [t/f]

sub get_if($) {
  my $naddr = ipanyto6(shift);
  my %net;
  my @ifs = interfaces Net::Interface ();
IF:
  foreach my $if (@ifs) {
    my @addrs = $if->address(AF_INET());
    my @netms = $if->netmask(AF_INET());
    if ($af_inet6) {
      push @addrs, $if->address($af_inet6);
      push @netms, $if->netmask($af_inet6);
    }
    foreach (0..$#addrs) {
      my $iddr = ipanyto6($addrs[$_]);
      my $name = $if->name();
      if ($naddr eq $iddr) {
	$match = $name;
	last IF;
      }
      my $mask = maskanyto6($netms[$_]);
      my $net = $iddr & $mask;
      my $bcst = $iddr | ~$mask;
      $name = $1 if $name =~ /(.+)\:/;			# for linux, fix aliases
      $net{$name} = $iddr
	if sub128($naddr,$net) && sub128($bcst,$naddr);	# within CIDR
    }
  }
  @_ = sort keys %net;
  my $pmsc = @_;
  if (!$match && $pmsc) {
    $match = shift @_;
  }
  return (wantarray)
	? ($match,$pmsc)
	: $match;
}

#			  ETHERNET HEADER
# +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
# |       Ethernet destination address (first 32 bits)            |
# +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
# | Ethernet dest (last 16 bits)  |Ethernet source (first 16 bits)|
# +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
# |       Ethernet source address (last 32 bits)                  |
# +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
# |        Type code              |                               |
# +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
# |  IP header, then TCP header, then your data                   |
# |                                                               |
#     ...
# |                                                               |
# |   end of your data                                            |
# +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
# |                       Ethernet Checksum                       |
# +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

#			      IPV4 HEADER
# +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
# |Version|  IHL  |Type of Service|          Total Length         |
# +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
# |         Identification        |Flags|      Fragment Offset    |
# +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
# |  Time to Live |    Protocol   |         Header Checksum       |
# +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
# |                       Source Address                          |
# +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
# |                    Destination Address                        |
# +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

#			     TCP HEADER
# +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+



( run in 0.592 second using v1.01-cache-2.11-cpan-39bf76dae61 )