/usr/sbin/fai-new-mac is in fai-server 4.3.1+deb8u1.
This file is owned by root:root, with mode 0o755.
The actual contents of the file can be viewed below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 | #! /usr/bin/perl
# print only new MAC addresses, which are not yet known
# (c) Thomas Lange, 2007-2012
# fai-new-mac -tad
# tcpdump -pnlqte udp and src port bootpc and broadcast | fai-new-mac
# -a add arp entries to list of known MAC addresses
# -d add dhcpd entries to list of known MAC addresses
# -t read from tcpdump. If not given, read from stdin
# -p <pattern> only print MACs matching the pattern
use strict;
use Getopt::Std;
my $filename="/var/lib/fai/known-mac-addresses";
my $dhcpdconf="/etc/dhcp/dhcpd.conf";
my %mac;
$|=1;
our($opt_a,$opt_d,$opt_p,$opt_t,$opt_i);
sub read_known_macs {
-f $filename || return;
open (IN,"$filename") or die "Can't read file with known MAC addresses\n";
while (<IN>) {
chomp;
$mac{$_}=1;
}
close IN;
}
sub read_arp {
open (ARP,"arp -an|") || die "Can't read arp list. $!\n";
while (<ARP>) {
append_new_mac($1,"MAC found in ARP list") if /at (([0-9a-f]{1,2}:){5}[0-9a-f]{1,2}) \[ether\] on /i
}
close ARP;
}
sub read_dhcpd {
-f $dhcpdconf || return;
open(DHCP,"$dhcpdconf") || die "Can't read $dhcpdconf. $!\n";
while (<DHCP>) {
append_new_mac($1,"mac found in dhcpd.conf") if /hardware ethernet\s+(([0-9a-f]{1,2}:){5}[0-9a-f]{1,2})/i;
}
close DHCP;
}
sub append_new_mac {
my ($newmac,$msg) = @_;
return if defined $mac{$newmac};
$mac{$newmac}=1;
if ($opt_p) {
print "$msg $newmac\n" if $newmac =~ /$opt_p/i;
} else {
print "$msg $newmac\n";
}
open (OUT,">>$filename") or die "Can't append to file with old MAC addresses\n";
print OUT "$newmac\n";
close OUT;
}
sub read_from_tcpdump {
my $newmac;
if ($opt_t) {
open (TCPDUMP,"tcpdump $opt_i -pnlqte udp and src port bootpc and broadcast|") || die "Can't read from tcpdump. $!\n";
} else {
open (TCPDUMP,"-") || die "$!\n";
}
while (<TCPDUMP>) {
next if /^tcpdump:/;
next if /^listening /;
$newmac=(split)[0];
append_new_mac($newmac,"NEW");
}
close TCPDUMP;
}
sub usage {exit;}
getopts('atdp:i:') || usage();
$opt_i and $opt_i="-i $opt_i";
read_known_macs();
$opt_d && read_dhcpd();
$opt_a && read_arp();
read_from_tcpdump();
|