+#!/usr/bin/perl -w
+# Send arp packets for ip takeover
+
+# Copyright (C) 2007-2011 Emmanuel Lacour <elacour@home-dn.net>
+#
+# This file is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License as published by the
+# Free Software Foundation; either version 2, or (at your option) any
+# later version.
+#
+# This file is distributed in the hope that it will be
+# useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+# of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this file; see the file COPYING. If not, write to the Free
+# Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+# 02110-1301, USA.
+
+
+use strict;
+use Getopt::Long;
+use Time::HiRes qw(usleep);
+use Socket;
+use Net::Interface;
+
+# Disable STDOUT buffering
+$| = 1;
+
+my $VERSION = '1.0';
+my $AUTHOR = 'Emmanuel Lacour, <elacour@home-dn.net>';
+
+
+# Defaults
+
+# Command line options
+my %opts;
+GetOptions (\%opts,
+ 'address=s',
+ 'iface=s',
+ 'dest=s',
+ 'count|c=i',
+ 'interval|i=i',
+ 'verbose|v',
+ 'help|h',
+ 'version|');
+
+$opts{'count'} = 5 if (!$opts{'count'});
+$opts{'interval'} = 100 if (!$opts{'interval'});
+
+if ($opts{'help'} || !$opts{'address'} || !$opts{'iface'} || !$opts{'dest'}) {
+ &usage;
+}
+
+if ($opts{'version'}) {
+ print "send_arpl.pl $VERSION\n";
+ print "Written by $AUTHOR\n";
+ exit;
+}
+
+sub usage() {
+ print "Usage: send_arp.pl [OPTION]...
+ --address=IP source IP address
+ --iface=IFACE network interface
+ --dest=IP destination IP address or broadcast
+-c, --count=NUMBER count of ARP to send (default: 5)
+-i, --interval=NUMBER interval between ARP requests (ms) (default: 100)
+-v, --verbose print debugging information
+-h, --help print this help, then exit
+ --version print this program version number
+";
+
+ exit;
+}
+
+sub sendARPReply($$$$$) {
+ my ($add,$iface,$ipdest,$count,$interval) = @_;
+ my $bmac = 'FF:FF:FF:FF:FF:FF';
+ my $netinfo = Net::Interface->new($iface);
+ my $hexmac = $netinfo->hwaddress();
+ my $mac = unpack("H*",$hexmac);
+
+ my $hexbmac = lc ($bmac);
+ $hexbmac =~ s/://g;
+ $hexbmac =~ s/([a-f0-9][a-f0-9])/chr(hex($1))/eg;
+
+ my $sock;
+
+ socket($sock, PF_INET, 10, 0x300);
+ select($sock); $|++;
+ select(STDOUT);
+
+ return if (! $sock);
+
+ my $arpreply =
+ $hexbmac. # MAC cible
+ $hexmac. # MAC source
+ "\x08\x06". # Format d'en-tete ARP
+ "\x00\x01". # Protocole (IP)
+ "\x08\x00". # Longueur de l'adresse physique
+ "\x06\x04". # Longueur de l'adresse reseau
+ "\x00\x02". # Operation (reply)
+ $hexmac. # MAC source
+ inet_aton($add). # IP source
+ $hexbmac. # MAC cible
+ inet_aton($ipdest) # IP cible
+ ;
+
+ my $dest = ("\x00" x 2).$iface.("\x00" x (14 - length($iface)));
+ # Send at least one time
+ my $i = 1;
+ print "Sending ARP to $ipdest, source $add (HW: $mac), on $iface:" if ($opts{'verbose'});
+ while ($i le $count) {
+ print " ." if ($opts{'verbose'});
+ send($sock, $arpreply, 0, $dest);
+ usleep ($interval * 1000);
+ $i++;
+ }
+ print " done.\n" if ($opts{'verbose'});
+}
+
+sendARPReply($opts{'address'},$opts{'iface'},$opts{'dest'},$opts{'count'},$opts{'interval'});
+