]> git.datanom.net - pve-dhcp-server.git/commitdiff
Implented config parser
authorMichael Rasmussen <mir@datanom.net>
Tue, 22 Jul 2014 02:00:45 +0000 (04:00 +0200)
committerMichael Rasmussen <mir@datanom.net>
Tue, 22 Jul 2014 02:00:45 +0000 (04:00 +0200)
DHCPServer.pm

index 5b6701fca41e84a585709837b17fc5bae21dc480..539093b34158728d8477cfdbe3d26f2eb591998a 100644 (file)
@@ -82,6 +82,7 @@ sub new {
     $self->{_sock_out_ip6}       = undef;
     $self->{_leases}             = undef;
     $self->{_reverse}            = undef;
+    $self->{_config}             = undef;
        $self->{_transaction_ip4} = 0;
        $self->{_transaction_ip6} = 0;
 
@@ -94,19 +95,28 @@ sub new {
     $self->{domain_name}       ||= undef;
     $self->{dns_servers}       ||= undef;
        $self->{ntp_servers}    ||= undef;
-       $self->{LOG_LEVEL}              ||= ERROR;
+       $self->{LOG_LEVEL}              = ERROR unless defined $self->{LOG_LEVEL};
        $self->{NODAEMON}               ||= 0;
        $self->{DEBUG}                  ||= 0;
        $self->{timeout}                ||= 10;
        $self->{lease_file}             ||= '/tmp/dhcpd.leases';
+       $self->{conf_file}              ||= '/tmp/dhcpd.cfg';
 
     return $self;
 }
 
 sub run {
        my ($self) = @_;
-       my ($sel, @ready, $socket);
+       my ($sel, @ready, $socket, $res);
 
+       eval {
+               $self->read_config();
+       };
+       if ($@) {
+               my $err = $@;
+               $self->logger($err, ERROR);
+               die $err;
+       }
        $self->logger("Starting dhcpd", INFO);
        if ($self->{NODAEMON} < 1) {
                $self->logger("Entering Daemon mode");
@@ -133,11 +143,8 @@ sub run {
                $self->logger("Now in Daemon mode", INFO);
        }
 
-       my $res = $self->read_lease_file();
-       do {
-               $self->logger("Couldn't read leases file '$self->{lease_file}'", ERROR);
-               die "Couldn't read leases file '$self->{lease_file}'";
-       } unless $res;
+       $res = $self->read_lease_file();
+       $self->logger("Starting with empty leases file '$self->{lease_file}'", INFO) unless $res;
 
        $self->logger("Initialization complete", INFO);
 
@@ -274,19 +281,19 @@ sub run_with_timeout {
 }
 
 sub lock {
-       my ($self, $shared) = @_;
+       my ($self, $file, $shared) = @_;
 
        my $mode = $shared ? LOCK_SH : LOCK_EX;
 
        my $lock_func = sub {
                if ($mode == LOCK_SH) {
-                       $self->{file_handle} = new IO::File ("<$self->{lease_file}") ||
-                die "can't open file for read - $!";
+                       $self->{file_handle} = new IO::File ("<$file") ||
+                die "can't open file '$file' for read - $!";
                } else {
-                       $self->{file_handle} = new IO::File (">$self->{lease_file}") ||
-                die "can't open file write - $!";
+                       $self->{file_handle} = new IO::File (">$file") ||
+                die "can't open file '$file' for write - $!";
                }
-        $self->logger("trying to aquire lock on '$self->{lease_file}'...");
+        $self->logger("trying to aquire lock on '$file'...");
         if (!flock ($self->{file_handle}, $mode|LOCK_NB)) {
                        my $success;
                        while(1) {
@@ -314,7 +321,7 @@ sub lock {
                $res = $self->run_with_timeout($lock_func);
        };
     if ($@) {
-               $self->logger("can't lock file '$self->{lease_file}' - $@", ERROR);
+               $self->logger("can't lock file '$file' - $@", ERROR);
                $self->{file_handle} = undef;
                return undef;
     }
@@ -323,11 +330,11 @@ sub lock {
 }
 
 sub unlock {
-       my ($self) = @_;
+       my ($self, $file) = @_;
 
        return '' unless($self->{file_handle});
        my $unlock_func = sub {
-        $self->logger("trying to unlock '$self->{lease_file}'...");
+        $self->logger("trying to unlock '$file'...");
         if (!flock($self->{file_handle}, LOCK_UN)) {
 
                        my $success;
@@ -353,7 +360,7 @@ sub unlock {
                $res = $self->run_with_timeout($unlock_func);
        };
     if ($@) {
-               $self->logger("can't lock file '$self->{lease_file}' - $@", ERROR);
+               $self->logger("can't lock file '$file' - $@", ERROR);
                $self->{file_handle} = undef;
                $res = undef;
     }
@@ -421,7 +428,7 @@ sub read_lease_file {
        my ($res, $key, $lease);
        my $error = 0;
 
-       $self->lock(1);
+       $self->lock($self->{lease_file}, 1);
        if ($self->{file_handle}) {
                my $fh = $self->{file_handle};
                my @lines = <$fh>;
@@ -453,7 +460,7 @@ sub read_lease_file {
                        $self->add_lease($key, $lease);
                }
                $self->logger("Leases data structure: \n" . Dumper($self->{_leases}));
-               $self->unlock();
+               $self->unlock($self->{lease_file});
                $res = 1;
        } else {
                $self->logger("Could not read leases file", ERROR);
@@ -467,7 +474,7 @@ sub write_lease_file {
        my ($self) = @_;
        my $res;
 
-       $res = $self->lock(0);
+       $res = $self->lock($self->{lease_file}, 0);
        if ($self->{file_handle}) {
                my $fh = $self->{file_handle};
                while ((my $lease, my $elems) = each $self->{_leases}) {
@@ -482,7 +489,7 @@ sub write_lease_file {
                        }
                        print $fh "}\n";
                }
-               $self->unlock();
+               $self->unlock($self->{lease_file});
                $res = 1;
        } else {
                $self->logger("Could not write leases file", ERROR);
@@ -492,6 +499,89 @@ sub write_lease_file {
        return $res;
 }
 
+#subnet 192.168.9.0 netmask 255.255.255.0 {
+#      range 192.168.9.2 192.168.9.100;
+#      ttl 7200;
+#      rttl 3600;
+#      router 192.168.9.254;
+#      dns-servers 192.168.2.201;
+#      ntp-servers 192.168.9.254;
+#      broadcast 192.168.9.255;
+#      domain-name "foo.bar";
+#      {
+#              allow 001cc0c33317,001cc0c33318,001cc0c33319,001cc0c33320;
+#              static 001cc0c33317 192.168.9.100,001cc0c33318 192.168.9.200;
+#      }
+#}
+sub read_config {
+       my ($self) = @_;
+       my ($res, $key, $netmask, $config, $subopt);
+
+       $self->lock($self->{conf_file}, 1);
+       if ($self->{file_handle}) {
+               my $fh = $self->{file_handle};
+               my @lines = <$fh>;
+               $subopt = 0;
+               foreach (@lines) {
+                       $self->logger("Read: $_");
+                       if ($_ =~ /^\s*subnet\s+([\d\.]+)\s+netmask\s+([\d\.]+)\s+{\s*/) {
+                               $self->{_config}->{$key} = $config if $config;
+                               $key = $1;
+                               $config = undef;
+                               $config->{netmask} = $2;
+                               $self->logger("Key: $key Netmask: $config->{netmask}");
+                       } else {
+                               next if (($_ =~ /^\s*}\s*/ && ! $subopt) || $_ =~ /^\s*$/ || $_ =~ /^\s*#.*/);
+                               if (! $subopt && $_ =~ /^\s*(range|ttl|rttl|router|dns-servers|ntp-servers|broadcast|domain-name)\s+(.+)\s*;/) {
+                                       $config->{$1} = $2;
+                                       $self->logger("Key: $1 Value: $2");
+                               } elsif ($subopt &&$_ =~ /^\s*}\s*/) {
+                                       $subopt = 0;
+                               } elsif ($subopt || $_ =~ /^\s*{\s*/) {
+                                       if ($subopt) {
+                                               if ($_ =~ /^\s*(allow|static)\s+(.+)\s*;/) {
+                                                       my (@vals, @tmp);
+                                                       @tmp = split(/,\s*/, $2);
+                                                       foreach (@tmp) {
+                                                               s/^\s+|\s+$//g;
+                                                               push @vals, $_;
+                                                       }
+                                                       $config->{$1} = [@vals];
+                                                       $self->logger("Key: $1 Value: $2");
+                                               } else {
+                                                       $key = 'UNDEF' unless $key;
+                                                       my $err = "$key: 'suboptions' Bad format";
+                                                       $self->logger($err, ERROR);
+                                                       $key = undef;
+                                                       $config = undef;
+                                                       die $err;
+                                               }
+                                       } else {
+                                               $subopt = 1;
+                                       }
+                               } else {
+                                       $key = 'UNDEF' unless $key;
+                                       my $err = "$key: Bad format";
+                                       $self->logger($err, ERROR);
+                                       $key = undef;
+                                       $config = undef;
+                                       die $err;
+                               }
+                       }
+               }
+               if ($config) {
+                       $self->{_config}->{$key} = $config;
+               }
+               $self->logger("Config data structure: \n" . Dumper($self->{_config}));
+               $self->unlock($self->{conf_file});
+               if (!$self->{_config}) {
+                       die "Empty config file";
+               }
+       } else {
+               die "Could not read config file";
+       }
+}
+
 sub logger {
        my ($self, $message, $level) = @_;
 
This page took 0.045461 seconds and 5 git commands to generate.