Archive

dhcp.confのhost情報を抜き出してCSV化するPerlスクリプト

を作成しました。

dhcp.conf内で

host hogehoge_001 {
  hardware ethernet 08:9F:3C:26:D0:A5;
  fixed-address 192.68.1.1
}
host hogehoge_002 {  hardware ethernet 08:9F:3D:26:D0:DD; }
    host hogehoge_003 {
  hardware ethernet 08:9F:3C:26:D0:A5;
  fixed-address 192.68.1.2
}

とかなっている場合に

hogehoge_001,08:9F:3C:26:D0:A5,192.68.1.001
hogehoge_002,08:9F:3D:26:D0:DD,
hogehoge_003,08:9F:3C:26:D0:A5,192.68.1.002

と一列目をhost、二列目をMACアドレス、三列目をIPアドレスとしたカンマ区 切りのCSVに整形して出力します。MACアドレスやIPアドレスの登録が無い場合にも対応しており、該当列が空白となります。単純に host{…}を正規表現で検索してsubnet内外関係無く抜き出しています。久しぶりにPerlに触れました。 以下、2310::AFREEです。自己責任で。

#!/usr/bin/perl
# -*- cperl -*-

# read dhcp.conf and ouput each host's defined mac and ip address(fixed)
# 2006/10/19

# ================================================================================
# header
# ================================================================================
use strict;
use File::Basename;


# ================================================================================
# prototype
# ================================================================================
sub read_file_contents;  # return string
sub get_result_string;   # return string

# ================================================================================
# global
# ================================================================================
# regexp
my $debug=0;  # if 1, print debug 
my $host_block_regexp = "host\\s*([\\w\\.\\-]+)\\s*{([^}]*)}";
my $fixed_address_regexp = "fixed-address\\s+(\\d+)\\.(\\d+)\\.(\\d+)\\.(\\d+)\\s*;";
my $mac_address_regexp = "hardware\\s+ethernet\\s+(\\w{2}:\\w{2}:\\w{2}:\\w{2}:\\w{2}:\\w{2})\\s*;";
# execute main stream
&mainsub();

# ================================================================================
# main
# ================================================================================

sub mainsub() {
  # check argment
  my $conf_file_name = $ARGV[0];
  my $file_contents;
  my $host;
  my $block_contents;

  # check file exists
  if (! -e $conf_file_name) {
    print "Error: Can't find $conf_file_name !\n";
    print "\tUsage ".basename($0)." <dhcp_conf_filename>\n";
    exit 1;
  }

  # read file contents
  $file_contents = read_file_contents($conf_file_name);
  if ($debug) {
    print $file_contents."\n\n\n";
  }

  while ($file_contents =~ /$host_block_regexp/g) {
    $host = $1;
    $block_contents = $2;
    if ($debug){
      print "======================================================================\n";
      print "Debug Report: host=$host \n";
      print "Debug Report: contents=$block_contents \n";
    }
    print get_result_string($host, $block_contents);
  }

}

sub read_file_contents() {
  my $file_name = @_[0];
  my @file_contents;
  my @file_contents_sub;
  my $file_contents_joined;

  open(FILE, "$file_name") or die "File $file_name Read Error";
  @file_contents = <FILE>;
  close(FILE);

  foreach (@file_contents) {
    unless ($_ =~ /^\s*#/) {
      push (@file_contents_sub,$_);
    }
  }



  $file_contents_joined = join("" ,@file_contents_sub);
  $file_contents_joined =~ s/\r?\n//g;
  $file_contents_joined =~ s/\t/ /g;
  return $file_contents_joined;
}


sub get_result_string() {
  my $host_name = @_[0];
  my $contents  = @_[1];
  my $ip_address;
  my $ip_address_1;
  my $ip_address_2;
  my $ip_address_3;
  my $ip_address_4;
  my $mac_address;


  if ($contents  =~ /$fixed_address_regexp/){
    $ip_address_1 = $1;
    $ip_address_2 = $2;
    $ip_address_3 = $3;
    $ip_address_4 = sprintf("%03d",$4);  # padding 0
    $ip_address = "$ip_address_1.$ip_address_2.$ip_address_3.$ip_address_4";
  }

  if ($contents  =~ /$mac_address_regexp/){
    $mac_address = $1;
  }

  return "$host_name,$mac_address,$ip_address\n";
}