#!/usr/bin/perl -w
###########################################
# Mike Schilli, 2006 (m@perlmeister.com)
###########################################
use strict;
use Net::Pcap;
use NetPacket::IP;
use NetPacket::Ethernet;
use Socket;
use WatchLAN;

die "You need to be root to run this.\n"
  if $> != 0;

my ( $err, $netaddr, $netmask );
my $dev = Net::Pcap::lookupdev( \$err );

Net::Pcap::lookupnet($dev, \$netaddr, 
                     \$netmask, \$err) and
    die "lookupnet $dev failed ($!)";

my $object =
  Net::Pcap::open_live( $dev, 1024, 1, 
                        -1, \$err );

my $db = WatchLAN->new();

Net::Pcap::loop( $object, -1, \&callback,
  [ $netaddr, $netmask ] );

###########################################
sub callback {
###########################################
  my ($user_data, $hdr, $raw_packet) = @_;

  my ($netaddr, $netmask) = @$user_data;

  my $packet = NetPacket::Ethernet->
                      decode($raw_packet);

  my $src_mac = $packet->{src_mac};
    # Add separating colons
  $src_mac =~ s/(..)(?!$)/$1:/g;

  my $edata =
   NetPacket::Ethernet::strip($raw_packet);

  my $ip = NetPacket::IP->decode($edata);

    # Package coming from local network?
  if ((inet_aton( $ip->{src_ip} ) &
       pack( 'N', $netmask )
      ) eq pack( 'N', $netaddr )) {
    $db->event_add( $src_mac, 
                    $ip->{src_ip} );
  }
}
