http://qs321.pair.com?node_id=149992
Category: Networking Code
Author/Contact Info rob_au
Description: This code watches for ARP requests on the ethernet address specified and sends an alert email to the network administrator in the event of a change in the hardware MAC address associated with an IP address. This was developed in part for a network traffic accountancy system in order to maintain record of machine hardware addresses and minimise the likelihood that network users could introduce foreign equipment onto the network.

It should be noted that this code was written as a proof of concept moreso than as a stand-alone piece of code. However, this code is interesting in its own right in that no external binaries are called upon for the capturing or interpretation of the ethernet ARP packets, instead relying upon the libpcap packet capturing library.

For previous nodes relating to this type of application, review (code) MAC n' IP cheese, How can I find a MAC address from aremote IP ? and MAC Address and NIC Device on Network.

#!/usr/bin/perl -Tw

use constant EMAIL  =>  'email@yourdomain.com';
use constant SERVER =>  'mail.yourdomain.com';

use Net::PcapUtils;
use Net::SMTP;
use NetPacket::ARP;
use NetPacket::Ethernet qw/:types/;
use strict;

my %ether;

my $mail = Net::SMTP->new(SERVER);

Net::PcapUtils::loop( 
    sub {
        my ($arg, $header, $packet) = @_;
        my $ethernet = NetPacket::Ethernet->decode($packet);
        if ($ethernet->{'type'} == ETH_TYPE_ARP) {
            my $arp = NetPacket::ARP->decode($ethernet->{'data'}, $eth
+ernet);
            my $ip = join '.', map { hex } ($arp->{'spa'} =~ /([[:xdig
+it:]]{2})/g);
            my $mac = join ':', ($arp->{'sha'} =~ /([[:xdigit:]]{2})/g
+);
            if ((exists $ether{$ip}) && ($ether{$ip} ne $mac)) {
                $mail->to(EMAIL);
                $mail->mail('root@yourdomain.com');
                $mail->data;
                $mail->datasend("There has been a change in the MAC ad
+dress associated with IP address ", $ip, "!\n\n");
                $mail->datasend("    Previous hardware MAC address -> 
+", $ether{$ip}, "\n");
                $mail->datasend("    Current hardware MAC address -> "
+, $mac, "\n");
                $mail->dataend;
                $mail->quit;
            }
            $ether{$ip} = $mac;
        }
    }, 
    'DEV'   =>  'eth0'
);
Replies are listed 'Best First'.
Re: ARP Watch
by zentara (Archbishop) on Mar 07, 2002 at 15:55 UTC
    There is a very good article on "sniffing switches" at http://www.linuxjournal.com/article.php?sid=5869&mode=thread&order=0
    which uses ARP hacking.