731 lines
16 KiB
Plaintext
731 lines
16 KiB
Plaintext
#!/usr/bin/perl5
|
|
|
|
# Manipulate ndbm database for DHCP
|
|
|
|
use Getopt::Std;
|
|
use Fcntl;
|
|
use NDBM_File;
|
|
use Socket;
|
|
use POSIX;
|
|
|
|
# globals
|
|
$dhcpDBFilename = "/var/dhcp/etherToIP";
|
|
|
|
sub lockDHCPdb {
|
|
if (flock LOCKDB, $LOCK_EX != 0) {
|
|
print "Can't lock file\n";
|
|
}
|
|
}
|
|
|
|
sub unlockDHCPdb {
|
|
if (flock LOCKDB, $LOCK_UN != 0) {
|
|
print "Can't unlock file\n";
|
|
}
|
|
}
|
|
|
|
|
|
sub usage {
|
|
print "Entry mode usage: $0 -a | -d | -u | -p [-r] [-X]\n";
|
|
print "\t-C cid -M mac_address -I ip_address -H qualified_hostname \n";
|
|
print "\t-T lease_secs|INF|STATIC [-f dbm_database]\n";
|
|
print "File mode usage: $0 -D | -L [-f dbm database]\n";
|
|
print "Use in entry mode with the following options:-\n";
|
|
print "\t-a add an entry - specify the -C -M -I -H and -T options\n";
|
|
print "\t-d delete an entry - specify -C|-M|-I|-H\n";
|
|
print "\t-u update lease time - specify -C|-M|-I|-H\n";
|
|
print "\t-p print entry - specify -C|-M|-I|-H\n";
|
|
print "\t-r replace mode for add (replace existing entry or create new)\n";
|
|
print "\t-X print and accept client identifiers as hex_string\n";
|
|
print "\t-T lease time can be specified with print option to print\n";
|
|
print "\t\t leases expiring in less than (<value) or greater than(>value)\n";
|
|
print "\t\t seconds. For example, dhcpdb -p -T <1000\n";
|
|
print "\t All fields should be provided to add entries. To update or delete\n";
|
|
print "\t a single key (cid, mac address, ip address, or hostname) is required.\n";
|
|
print "\nUse in file mode with the following options:-\n";
|
|
print "\t-D dump to text file (stdout is output)\n";
|
|
print "\t-L load from text file to database (stdin is input)\n";
|
|
exit();
|
|
}
|
|
|
|
# get a cid external form from a string
|
|
sub cid_stoa {
|
|
my $val = $_[0];
|
|
my $optX = $_[1];
|
|
my ($len, $cid, $cidout, @cid);
|
|
$len = length($val);
|
|
@cid = unpack("C$len", $val);
|
|
$cidout = "";
|
|
if ($optX eq "") {
|
|
$cidout = pack("C$len", @cid);
|
|
}
|
|
else {
|
|
foreach $cid (@cid) {
|
|
$cidout .= sprintf "%x:", $cid;
|
|
}
|
|
}
|
|
$cidout =~ s/:$//;
|
|
$cidout;
|
|
}
|
|
|
|
# convert cid to internally stored form (opaque string)
|
|
sub cid_atos {
|
|
my (@cid, $len, $cid);
|
|
my $optX = $_[1];
|
|
if ($optX eq "") {
|
|
return $_[0];
|
|
}
|
|
else {
|
|
@cid = split(/[;:]/, $_[0]);
|
|
$len = $#cid + 1;
|
|
for ($i = 0; $i < $len; $i++) {
|
|
$cids[$i] = hex($cid[$i]);
|
|
}
|
|
$cid = pack("C$len", @cids);
|
|
return $cid;
|
|
}
|
|
}
|
|
|
|
# prints an ethernet address as a string of hex bytes
|
|
|
|
sub ether_ntoa {
|
|
my $ether, $byte;
|
|
foreach $byte (@_) {
|
|
$ether .= sprintf "%x:", $byte;
|
|
}
|
|
$ether =~ s/:$//;
|
|
$ether;
|
|
}
|
|
|
|
sub ether_aton {
|
|
my @ether, $ether, @eth;
|
|
@ether = split(":", $_[0]);
|
|
for ($i = 0; $i <= $#ether; $i++) {
|
|
$eth[$i] = hex($ether[$i]);
|
|
}
|
|
@eth;
|
|
}
|
|
|
|
# create Keys
|
|
|
|
sub crEtherKey {
|
|
my $opt = $_[0];
|
|
my @ether, $len, $keyM;
|
|
@ether = ether_aton($opt);
|
|
$len = $#ether + 1;
|
|
$keyM = pack("a C$len", 0, @ether);
|
|
}
|
|
|
|
sub crHostNameKey {
|
|
my $opt = $_[0];
|
|
my $len, $keyH;
|
|
$len = length($opt);
|
|
$keyH = pack("a A$len", (1, $opt));
|
|
}
|
|
|
|
sub crIpaddrKey {
|
|
my $opt = $_[0];
|
|
my $ipaddr, $len, @ipaddr, $keyI;
|
|
$ipaddr = inet_aton("$opt");
|
|
$len = length($ipaddr);
|
|
@ipaddr = unpack("C4", $ipaddr);
|
|
$keyI = pack("a C4", (2, @ipaddr));
|
|
}
|
|
|
|
# always takes input in internal form
|
|
|
|
sub crCidKey {
|
|
my $opt = $_[0];
|
|
my $len, $keyC;
|
|
$len = length($opt);
|
|
$keyC = pack("a A$len", (3, $opt));
|
|
}
|
|
|
|
sub getKeyCfromM {
|
|
my $opt = $_[0];
|
|
my $keyM, $cid, $keyC;
|
|
$keyM = crEtherKey($opt);
|
|
if ($DHCPDB{$keyM} eq undef) {
|
|
print "Entry with key $opt_M not found.\n";
|
|
return undef;
|
|
}
|
|
else {
|
|
$cid = $DHCPDB{$keyM};
|
|
$keyC = crCidKey($cid);
|
|
}
|
|
return $keyC;
|
|
}
|
|
|
|
sub getKeyCfromH {
|
|
my $opt = $_[0];
|
|
my $keyH, $cid, $keyC;
|
|
$keyH = crHostNameKey($opt);
|
|
if ($DHCPDB{$keyH} eq undef) {
|
|
print "Entry with key $opt_H not found.\n";
|
|
return undef;
|
|
}
|
|
else {
|
|
$cid = $DHCPDB{$keyH};
|
|
$keyC = crCidKey($cid);
|
|
}
|
|
return $keyC;
|
|
}
|
|
|
|
sub getKeyCfromI {
|
|
my $opt = $_[0];
|
|
my $keyI, $cid, $keyC;
|
|
$keyI = crIpaddrKey($opt);
|
|
if ($DHCPDB{$keyI} eq undef) {
|
|
print "Entry with key $opt_I not found.\n";
|
|
return undef;
|
|
}
|
|
else {
|
|
$cid = $DHCPDB{$keyI};
|
|
$keyC = crCidKey($cid);
|
|
}
|
|
return $keyC;
|
|
}
|
|
|
|
# add an entry to the DHCP database
|
|
sub addDHCPdb {
|
|
my $dh_obj;
|
|
my $keyM, $keyH, $keyI, $keyC, $data, $err, $valC, @optT, $optT;
|
|
if ( ($opt_M eq "") || ($opt_C eq "") || ($opt_I eq "") ||
|
|
($opt_H eq "") || ($opt_T eq "") ) {
|
|
print "Must specify the -C, -M, -I, -H, and -T options to add\n";
|
|
usage();
|
|
}
|
|
|
|
@optT = split / /, $opt_T;
|
|
if (@optT > 1) {
|
|
$optT = mktime(@optT);
|
|
if ($optT ne undef) {
|
|
$opt_T = $optT;
|
|
}
|
|
else {
|
|
print "Time should be entered in time() or mktime() format\n";
|
|
usage();
|
|
}
|
|
}
|
|
|
|
if ($opt_T eq "INF") {
|
|
$opt_T = -1;
|
|
}
|
|
if ($opt_T eq "STATIC") {
|
|
$opt_T = -3;
|
|
}
|
|
if (($opt_T == 0) || ($opt_T < -3)) {
|
|
print "Lease time should be positive.\n";
|
|
untie %DHCPDB;
|
|
return -1;
|
|
}
|
|
|
|
$keyM = crEtherKey($opt_M);
|
|
|
|
$keyH = crHostNameKey($opt_H);
|
|
|
|
$keyI = crIpaddrKey($opt_I);
|
|
|
|
$valC = cid_atos($opt_C, $opt_X);
|
|
$keyC = crCidKey($valC);
|
|
|
|
$data = sprintf "%s\t%s\t%s\t%s\0", $opt_M, $opt_I, $opt_H, $opt_T;
|
|
|
|
$db_obj = tie(%DHCPDB, "NDBM_File", $dhcpDBFilename,
|
|
O_RDWR|O_CREAT, 0604);
|
|
|
|
if ($db_obj eq undef) {
|
|
die "Could not open $dhcpDBFilename.\n";
|
|
exit();
|
|
}
|
|
|
|
# before adding this record make sure that its not already
|
|
# in there.
|
|
$err = 0;
|
|
if ($opt_r == 0) {
|
|
if ($DHCPDB{$keyM} ne undef) {
|
|
$keyC = getKeyCfromM($opt_M);
|
|
print "Duplicate for Mac $opt_M: $DHCPDB{$keyC} exists.\n";
|
|
$err = 1;
|
|
}
|
|
if ($DHCPDB{$keyH} ne undef) {
|
|
$keyC = getKeyCfromH($opt_H);
|
|
print "Duplicate for Hostname $opt_H: $DHCPDB{$keyC} exists.\n";
|
|
$err = 1;
|
|
}
|
|
if ($DHCPDB{$keyI} ne undef) {
|
|
$keyC = getKeyCfromI($opt_I);
|
|
print "Duplicate for IP address $opt_I: $DHCPDB{$keyC} exists.\n";
|
|
$err = 1;
|
|
}
|
|
if ($DHCPDB{$keyC} ne undef) {
|
|
print "Duplicate for Cid $opt_C: $DHCPDB{$keyC} exists.\n";
|
|
$err = 1;
|
|
}
|
|
if ($err == 1) {
|
|
untie %DHCPDB;
|
|
return -1;
|
|
}
|
|
}
|
|
|
|
|
|
lockDHCPdb();
|
|
$DHCPDB{$keyM} = $valC;
|
|
$DHCPDB{$keyH} = $valC;
|
|
$DHCPDB{$keyI} = $valC;
|
|
$DHCPDB{$keyC} = $data;
|
|
unlockDHCPdb();
|
|
|
|
untie %DHCPDB;
|
|
return 0;
|
|
}
|
|
|
|
# delete an entry from the DHCP database
|
|
sub deleteDHCPdb {
|
|
my $dh_obj, $selections, $delete, $keyC, $keyI, $data, $keyH, $keyM;
|
|
my $M, $I, $H, $lease, $cid;
|
|
|
|
if ( ($opt_M eq "") && ($opt_C eq "") && ($opt_I eq "") && ($opt_H eq "") ) {
|
|
print "Must specify the -C, -M, -I, or -H options to delete\n";
|
|
usage();
|
|
}
|
|
|
|
$selections = ($opt_M ne undef) + ($opt_C ne undef) +
|
|
($opt_I ne undef) + ($opt_H ne undef);
|
|
if ($selections > 1) {
|
|
print "Deletion can be done on one key only.\n";
|
|
return -1;
|
|
}
|
|
|
|
$delete = 0;
|
|
$db_obj = tie(%DHCPDB, "NDBM_File", $dhcpDBFilename,
|
|
O_RDWR|O_CREAT, 0604);
|
|
|
|
if ($db_obj eq undef) {
|
|
die "Could not open $dhcpDBFilename.\n";
|
|
exit();
|
|
}
|
|
|
|
if ($opt_C ne "") {
|
|
$cid = cid_atos($opt_C, $opt_X);
|
|
$keyC = crCidKey($cid);
|
|
if ($DHCPDB{$keyC} eq undef) {
|
|
print "Entry with key $opt_C not found.\n";
|
|
}
|
|
else {
|
|
$data = $DHCPDB{$keyC};
|
|
($M, $I, $H, $lease) = split(/[\t ]/, $data);
|
|
$keyH = crHostNameKey($H);
|
|
$keyI = crIpaddrKey($I);
|
|
$keyM = crEtherKey($M);
|
|
$delete = 1;
|
|
}
|
|
}
|
|
elsif ($opt_M ne "") {
|
|
$opt_M =~ tr/A-Z/a-z/;
|
|
$keyC = getKeyCfromM($opt_M);
|
|
if ($keyC) {
|
|
$data = $DHCPDB{$keyC};
|
|
($M, $I, $H, $lease) = split(/[\t ]/, $data);
|
|
$M =~ tr/A-Z/a-z/;
|
|
if ($opt_M ne $M) {
|
|
print "Inconsistent data $opt_M != $M .\n";
|
|
untie %DHCPDB;
|
|
return -1;
|
|
}
|
|
$keyH = crHostNameKey($H);
|
|
$keyI = crIpaddrKey($I);
|
|
$delete = 1;
|
|
}
|
|
}
|
|
elsif ($opt_H ne "") {
|
|
$keyC = getKeyCfromH($opt_H);
|
|
if ($keyC) {
|
|
$data = $DHCPDB{$keyC};
|
|
($M, $I, $H, $lease) = split(/[\t ]/, $data);
|
|
if ($opt_H ne $H) {
|
|
print "Inconsistent data $opt_H != $H .\n";
|
|
untie %DHCPDB;
|
|
return -1;
|
|
}
|
|
$keyI = crIpaddrKey($I);
|
|
$keyM = crEtherKey($M);
|
|
$delete = 1;
|
|
}
|
|
}
|
|
elsif ($opt_I ne "") {
|
|
$keyC = getKeyCfromI($opt_I);
|
|
if ($keyC ne undef) {
|
|
$data = $DHCPDB{$keyC};
|
|
($M, $I, $H, $lease) = split(/[\t ]/, $data);
|
|
if ($opt_I ne $I) {
|
|
print "Inconsistent data $opt_I != $I .\n";
|
|
untie %DHCPDB;
|
|
return -1;
|
|
}
|
|
$keyM = crEtherKey($M);
|
|
$keyH = crHostNameKey($H);
|
|
$delete = 1;
|
|
}
|
|
}
|
|
else {
|
|
print "What option is this ?\n";
|
|
untie %DHCPDB;
|
|
return -1;
|
|
}
|
|
|
|
if ($delete == 1) {
|
|
lockDHCPdb();
|
|
|
|
delete $DHCPDB{$keyC};
|
|
delete $DHCPDB{$keyM};
|
|
delete $DHCPDB{$keyH};
|
|
delete $DHCPDB{$keyI};
|
|
|
|
unlockDHCPdb();
|
|
}
|
|
untie %DHCPDB;
|
|
}
|
|
|
|
# update a lease
|
|
|
|
sub updateDHCPdb {
|
|
my $dh_obj, $selections, $update, $keyC, $keyI, $data, $keyH, $keyM;
|
|
my $M, $I, $H, $lease, $cid, @optT, $optT;
|
|
|
|
if ( ($opt_M eq "") && ($opt_C eq "") && ($opt_I eq "") && ($opt_H eq "") ) {
|
|
print "Must specify the -C, -M, -I, or -H options to update\n";
|
|
usage();
|
|
}
|
|
elsif ($opt_T eq "") {
|
|
print "Must specify the lease value to update\n";
|
|
usage();
|
|
}
|
|
|
|
if ($opt_T eq "INF") {
|
|
$opt_T = -1;
|
|
}
|
|
if ($opt_T eq "STATIC") {
|
|
$opt_T = -3;
|
|
}
|
|
if (($opt_T == 0) || ($opt_T < -3)) {
|
|
print "Lease must be positive or -1(static allocation).\n";
|
|
return -1;
|
|
}
|
|
|
|
@optT = split / /, $opt_T;
|
|
if (@optT > 1) {
|
|
$optT = mktime(@optT);
|
|
if ($optT ne undef) {
|
|
$opt_T = $optT;
|
|
}
|
|
else {
|
|
print "Time should be entered in time() or mktime() format\n";
|
|
usage();
|
|
}
|
|
}
|
|
|
|
$selections = ($opt_M ne undef) + ($opt_C ne undef) +
|
|
($opt_I ne undef) + ($opt_H ne undef);
|
|
if ($selections > 1) {
|
|
print "Update can be done on one key only.\n";
|
|
return -1;
|
|
}
|
|
|
|
$update = 0;
|
|
|
|
$db_obj = tie(%DHCPDB, "NDBM_File", $dhcpDBFilename,
|
|
O_RDWR|O_CREAT, 0604);
|
|
if ($db_obj eq undef) {
|
|
die "Could not open $dhcpDBFilename.\n";
|
|
exit();
|
|
}
|
|
if ($opt_M ne "") {
|
|
$opt_M =~ tr/A-Z/a-z/;
|
|
$keyC = getKeyCfromM($opt_M);
|
|
if ($keyC) {
|
|
$data = $DHCPDB{$keyC};
|
|
($M, $I, $H, $lease) = split(/[\t ]/, $data);
|
|
$M =~ tr/A-Z/a-z/;
|
|
if ($opt_M ne $M) {
|
|
print "Inconsistent data $opt_M != $M .\n";
|
|
untie %DHCPDB;
|
|
return -1;
|
|
}
|
|
$update = 1;
|
|
}
|
|
}
|
|
elsif ($opt_C ne "") {
|
|
$cid = cid_atos($opt_C, $opt_X);
|
|
$keyC = crCidKey($opt_C);
|
|
if ($DHCPDB{$keyC} eq undef) {
|
|
print "Entry with key $opt_C not found.\n";
|
|
}
|
|
else {
|
|
$data = $DHCPDB{$keyC};
|
|
($M, $I, $H, $lease) = split(/[\t ]/, $data);
|
|
$update = 1;
|
|
}
|
|
}
|
|
elsif ($opt_H ne "") {
|
|
$keyC = getKeyCfromH($opt_H);
|
|
if ($keyC ne undef) {
|
|
$data = $DHCPDB{$keyC};
|
|
($M, $I, $H, $lease) = split(/[\t ]/, $data);
|
|
if ($opt_H ne $H) {
|
|
print "Inconsistent data $opt_H != $H .\n";
|
|
untie %DHCPDB;
|
|
return -1;
|
|
}
|
|
$update = 1;
|
|
}
|
|
}
|
|
elsif ($opt_I ne "") {
|
|
$keyI = getKeyCfromI($opt_I);
|
|
if ($keyC ne undef) {
|
|
$data = $DHCPDB{$keyC};
|
|
($M, $I, $H, $lease) = split(/[\t ]/, $data);
|
|
if ($opt_I ne $I) {
|
|
print "Inconsistent data $opt_I != $I .\n";
|
|
untie %DHCPDB;
|
|
return -1;
|
|
}
|
|
$update = 1;
|
|
}
|
|
}
|
|
else {
|
|
print "What option is this ?\n";
|
|
untie %DHCPDB;
|
|
return -1;
|
|
}
|
|
|
|
if ($update == 1) {
|
|
lockDHCPdb();
|
|
|
|
$data = sprintf "%s\t%s\t%s\t%s\0", $M, $I, $H, $opt_T;
|
|
$DHCPDB{$keyC} = $data;
|
|
|
|
unlockDHCPdb();
|
|
}
|
|
untie %DHCPDB;
|
|
|
|
}
|
|
|
|
|
|
# print database entries
|
|
|
|
sub printDHCPdb {
|
|
|
|
my $val, $print, $keyC, $keyM, $keyH, $keyI, $M, $H, $I, $lease;
|
|
my $op, $secs, $time, $key, $val, $type, @keybuf, $cid, $please;
|
|
if ( ($opt_M eq "") && ($opt_C eq "") && ($opt_I eq "") &&
|
|
($opt_H eq "") && ($opt_T eq "") ) {
|
|
print "Must specify the -C, -M, -I, -H, or -T options to print\n";
|
|
usage();
|
|
}
|
|
|
|
dbmopen %DHCPDB, $dhcpDBFilename, undef
|
|
or die "Can't open $dhcpDBFilename: $!\n";
|
|
|
|
$print = 0;
|
|
if ($opt_M ne "") {
|
|
$opt_M =~ tr/A-Z/a-z/;
|
|
$keyC = getKeyCfromM($opt_M);
|
|
if ($keyC ne undef) {
|
|
$data = $DHCPDB{$keyC};
|
|
($M, $I, $H, $lease) = split(/[\t ]/, $data);
|
|
$M =~ tr/A-Z/a-z/;
|
|
if ($opt_M ne $M) {
|
|
print "Inconsistent data $opt_M != $M .\n";
|
|
dbmclose %DHCPDB;
|
|
return -1;
|
|
}
|
|
$print = 1;
|
|
}
|
|
}
|
|
elsif ($opt_C ne "") {
|
|
$cid = cid_atos($opt_C, $opt_X);
|
|
$keyC = crCidKey($cid);
|
|
if ($DHCPDB{$keyC} eq undef) {
|
|
print "Entry with key $opt_C not found.\n";
|
|
}
|
|
else {
|
|
$data = $DHCPDB{$keyC};
|
|
($M, $I, $H, $lease) = split(/[\t ]/, $data);
|
|
$print = 1;
|
|
}
|
|
}
|
|
elsif ($opt_H ne "") {
|
|
$keyC = getKeyCfromH($opt_H);
|
|
if ($keyC ne undef) {
|
|
$data = $DHCPDB{$keyC};
|
|
($M, $I, $H, $lease) = split(/[\t ]/, $data);
|
|
if ($opt_H ne $H) {
|
|
print "Inconsistent data $opt_H != $H .\n";
|
|
dbmclose %DHCPDB;
|
|
return -1;
|
|
}
|
|
$print = 1;
|
|
}
|
|
}
|
|
elsif ($opt_I ne "") {
|
|
$keyC = getKeyCfromI($opt_I);
|
|
if ($keyC ne undef) {
|
|
$data = $DHCPDB{$keyC};
|
|
($M, $I, $H, $lease) = split(/[\t ]/, $data);
|
|
if ($opt_I ne $I) {
|
|
print "Inconsistent data $opt_I != $I .\n";
|
|
dbmclose %DHCPDB;
|
|
return -1;
|
|
}
|
|
$print = 1;
|
|
}
|
|
}
|
|
elsif ($opt_T ne "") {
|
|
$op = substr($opt_T, 0, 1);
|
|
if (($op eq "<") || ($op eq ">")) {
|
|
$secs = substr($opt_T, 1);
|
|
}
|
|
else {
|
|
$op = ">";
|
|
$secs = $opt_T;
|
|
}
|
|
$time = time();
|
|
while (($key,$val) = each %DHCPDB) {
|
|
($type, @keybuf) = unpack("a C*", $key);
|
|
if ($type == 3) { # cid is the key
|
|
($M, $I, $H, $lease) = split(/[\t ]/, $val);
|
|
if ($lease <= 0) {
|
|
$please = $lease . "\n";
|
|
} else {
|
|
$please = ctime($lease);
|
|
}
|
|
if ($op eq ">") {
|
|
if ( ($lease - $time) >= $secs ) {
|
|
$cid = pack("C*", @keybuf);
|
|
printf "%s :- %s\t%s\t%s\t%s", cid_stoa($cid, $opt_X), $M, $I, $H,
|
|
$please;
|
|
}
|
|
}
|
|
else {
|
|
if ( ($lease - $time) < $secs ) {
|
|
$cid = pack("C*", @keybuf);
|
|
|
|
printf "%s :- %s\t%s\t%s\t%s", cid_stoa($cid, $opt_X), $M, $I, $H,
|
|
$please;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
else {
|
|
print "What option is this ?\n";
|
|
dbmclose %DHCPDB;
|
|
return -1;
|
|
}
|
|
|
|
if ($print == 1) {
|
|
printf "%s :- %s\n", cid_stoa($cid, $opt_X), $data;
|
|
}
|
|
dbmclose %DHCPDB;
|
|
}
|
|
|
|
|
|
# dump the database entries
|
|
|
|
sub dumpDHCPdb {
|
|
my $key, $val, $type, @keybuf, $cid;
|
|
|
|
dbmopen %DHCPDB, $dhcpDBFilename, undef
|
|
or die "Can't open $dhcpDBFilename: $!\n";
|
|
|
|
while (($key,$val) = each %DHCPDB) {
|
|
($type, @keybuf) = unpack("a C*", $key);
|
|
|
|
if ($type == 3) { # cid is the key
|
|
$cid = pack("C*", @keybuf);
|
|
chop $val if ($val =~ /\0$/);
|
|
printf "%s\t%s\n", cid_stoa($cid, $opt_X), $val;
|
|
}
|
|
}
|
|
dbmclose %DHCPDB;
|
|
}
|
|
|
|
#load entries into the database
|
|
|
|
sub loadDHCPdb {
|
|
my $dh_obj;
|
|
my $key, $M, $H, $I, $lease, $keyM, $keyC, $keyH, $keyI, $data, $valC;
|
|
|
|
$db_obj = tie(%DHCPDB, "NDBM_File", $dhcpDBFilename,
|
|
O_RDWR|O_CREAT, 0604);
|
|
|
|
while (<>) {
|
|
chop $_ if ($_ =~ /\n$/);
|
|
($key, $M, $I, $H, $lease) = split(/[ \t]/, $_);
|
|
$valC = cid_atos($key,$opt_X);
|
|
$keyC = crCidKey($valC);
|
|
if ($DHCPDB{$keyC} ne "") {
|
|
print "Updating entry for $_\n";
|
|
}
|
|
$keyM = crEtherKey($M);
|
|
|
|
$keyH = crHostNameKey($H);
|
|
|
|
$keyI = crIpaddrKey($I);
|
|
$data = sprintf "%s\t%s\t%s\t%s\0", $M, $I, $H, $lease;
|
|
|
|
lockDHCPdb();
|
|
$DHCPDB{$keyM} = $valC;
|
|
$DHCPDB{$keyH} = $valC;
|
|
$DHCPDB{$keyI} = $valC;
|
|
$DHCPDB{$keyC} = $data;
|
|
unlockDHCPdb();
|
|
}
|
|
untie %DHCPDB;
|
|
}
|
|
|
|
sub main {
|
|
if (getopts('haduprXLDC:M:H:I:T:f:') == 0) {
|
|
usage();
|
|
}
|
|
if ($opt_h) {
|
|
usage();
|
|
}
|
|
if ($opt_f) {
|
|
$dhcpDBFilename = $opt_f;
|
|
}
|
|
|
|
sysopen(LOCKDB, "$dhcpDBFilename" . ".lock", O_RDONLY|O_CREAT, 0604)
|
|
or die "Can't open lock file: $!";
|
|
|
|
if (($opt_a == 1) || ($opt_r == 1)) {
|
|
$opt_a = 1;
|
|
addDHCPdb();
|
|
}
|
|
elsif ($opt_d == 1) {
|
|
deleteDHCPdb();
|
|
}
|
|
elsif ($opt_u == 1) {
|
|
updateDHCPdb();
|
|
}
|
|
elsif ($opt_p == 1) {
|
|
printDHCPdb();
|
|
}
|
|
elsif ($opt_D == 1) {
|
|
dumpDHCPdb();
|
|
}
|
|
elsif ($opt_L == 1) {
|
|
loadDHCPdb();
|
|
}
|
|
else {
|
|
print "Must specify add/delete/update/print/replace\n\n";
|
|
usage();
|
|
}
|
|
close(LOCKDB);
|
|
}
|
|
|
|
|
|
main();
|
|
|
|
|