#!/usr/bin/perl -w
# Steven Shiau <steven _at_ nchc org tw>
# License: GPL
# Description: To parse the dhcpd.conf as a HOSTNAME IP MAC table.
# The reference is like: 
#$VAR1 = {
#          'mdk101-201' => {
#                            'IP' => '192.168.219.1',
#                            'MAC' => '00:50:56:00:01:01'
#                          },
#          'mdk101-102' => {
#                            'IP' => '192.168.199.2',
#                            'MAC' => '00:50:56:00:00:02'
#                          },
#          'mdk101-101' => {
#                            'IP' => '192.168.199.1',
#                            'MAC' => '00:50:56:00:00:01'
#                          }
#        };

use strict;
use Data::Dumper;

if ($#ARGV != 0) {
  print "You must specify the output file! Program terminated!!!\n";
  exit(1);
}

my $IP_MAC_FILE=shift(@ARGV);
my ($HOSTS, $ihost);
my $dhcpd_conf="";

unlink $IP_MAC_FILE if -f $IP_MAC_FILE;
open(OUT, ">$IP_MAC_FILE") || die "Can't open file: $IP_MAC_FILE\n";
if ((-f "/etc/debian_version")) {
  # Debian
  if ((-f "/etc/dhcp3/dhcpd.conf")) {
    $dhcpd_conf = "/etc/dhcp3/dhcpd.conf";
  }
}else{
  # RH-like or SUSE
  if ((-f "/etc/dhcp/dhcpd.conf")) {
    $dhcpd_conf = "/etc/dhcp/dhcpd.conf";
  }elsif((-f "/etc/dhcpd.conf")) {
    $dhcpd_conf = "/etc/dhcpd.conf";
  }
}

if ("$dhcpd_conf" eq "") {
  print "dhcpd.conf not found! Program terminated!!!\n";
  exit(1);
}

sub parse_dhcpd_conf {
  my (%host_list, $host);
  open(IN, $dhcpd_conf) || die "Can't open file: $!";
  while (<IN>) {
  	next unless (/^[[:space:]]*host .*{/i || /^[[:space:]]*hardware ethernet/i || /^[[:space:]]*fixed-address/i);
  	my $line = $_;
  	chomp $line;
  	if ($line =~ /^[[:space:]]*host .*{/i) {
  		$host = (split(' ', $line))[1];
  		next;
  	}
  	if ($line =~ /^[[:space:]]*hardware ethernet .*$/i) {
  		my $mac = (split(' ', $line))[2];
		$mac =~ s/;$//;
		# We convert all the MAC to lowercase, which is used in pxelinux config filename.
		$mac = lc($mac);
  		$host_list{$host}{"MAC"} = $mac;
  		next;
  	}
  	if ($line =~ /^[[:space:]]*fixed-address .*$/i) {
  		my $ip = (split(' ', $line))[1];
		$ip =~ s/;$//;
  		$host_list{$host}{"IP"} = $ip;
  		next;
  	}
  }
  close(IN);
  #print Dumper(\%host_list);
  return (\%host_list);
}

# make the reference.
$HOSTS = parse_dhcpd_conf();

# output the results
print OUT "# Generated by DRBL script parse_dhcpd_conf\n";
print OUT "# HOSTNAME IP MAC_ADDRESS\n";
foreach my $ihost ( sort keys(%{$HOSTS}) ) {
  print OUT "$ihost $HOSTS->{$ihost}->{IP} $HOSTS->{$ihost}->{MAC}\n";
}
