Skip Menu |

Preferred bug tracker

Please visit the preferred bug tracker to report your issue.

This queue is for tickets about the Net-ISC-DHCPd CPAN distribution.

Report information
The Basics
Id: 81269
Status: resolved
Priority: 0/
Queue: Net-ISC-DHCPd

People
Owner: Nobody in particular
Requestors: RDRAKE [...] cpan.org
Cc:
AdminCc:

Bug Information
Severity: Important
Broken in: (no value)
Fixed in: (no value)



Subject: Patch for Class, Zone, Conditionals, and a few parsing bugs
I'm attaching a patch file that fixes Class, Zones, Conditionals, and some parsing errors I was getting on my dhcpd.conf file. I'd really like to give you a copy of my dhcpd.conf for testing because it's 400Kb and does some interesting things, but it has some customer data so I want to clean it up before giving it out. I'll give some examples though: Keys were failing because a newline wasn't an accepted possible termination for the regex. That should be fixed now. key dhcpserver { algorithm hmac-md5; secret "..."; }; Some of my "option space" don't have encapsulate. I'm not sure if they work properly without it, but that's how it was given to me by the vendor. I've changed OptionSpace to not require it now. option space ubnt; option ubnt.unifi-address code 1 = ip-address; Conditionals also work now: if option vendor-class-identifier = "ubnt" { vendor-option-space ubnt; } Classes work: class "SipuraATA" { match if (substring(option host-name,0,9) = "SipuraSPA"); } And finally, Zones are also allowed. These are used when you want to enable dynamic DNS updates through DHCP: zone staging.fake-domain-name-here.net { primary 1.2.3.4; key staging-key; } I get a test result passed for "make test" but I didn't add any new unit tests. If that is a problem let me know and I'll write some for the new things. Also let me know if it breaks or does something you don't want it to do. Thanks, Robert Drake
Subject: net-isc-dhcpd-class.patch
From 94a366a025d3430772be833924570219f9993eb6 Mon Sep 17 00:00:00 2001 From: Robert Drake <rdrake@direcpath.net> Date: Sun, 18 Nov 2012 23:57:11 -0500 Subject: [PATCH 1/4] Added Zone.pm to Config.pm Fixed Key.pm for keys with opening brackets on the next line Added last if (/\s*{/); to Role.pm to prevent parse errors on open bracket lines (this could be made safer by checking to see if the parser is at a point where it expects an open bracket. Added lib/Net/ISC/DHCPd/Config/Zone.pm for zone handling. --- lib/Net/ISC/DHCPd/Config.pm | 1 + lib/Net/ISC/DHCPd/Config/Key.pm | 2 +- lib/Net/ISC/DHCPd/Config/Role.pm | 3 + lib/Net/ISC/DHCPd/Config/Zone.pm | 107 ++++++++++++++++++++++++++++++++++++++ 4 files changed, 112 insertions(+), 1 deletions(-) create mode 100644 lib/Net/ISC/DHCPd/Config/Zone.pm diff --git a/lib/Net/ISC/DHCPd/Config.pm b/lib/Net/ISC/DHCPd/Config.pm index 55e8dd1..77ba543 100644 --- a/lib/Net/ISC/DHCPd/Config.pm +++ b/lib/Net/ISC/DHCPd/Config.pm @@ -116,6 +116,7 @@ __PACKAGE__->create_children(qw/ Net::ISC::DHCPd::Config::Group Net::ISC::DHCPd::Config::Block Net::ISC::DHCPd::Config::KeyValue + Net::ISC::DHCPd::Config::Zone /); sub _build_root { $_[0] } diff --git a/lib/Net/ISC/DHCPd/Config/Key.pm b/lib/Net/ISC/DHCPd/Config/Key.pm index 442bb2e..f274684 100644 --- a/lib/Net/ISC/DHCPd/Config/Key.pm +++ b/lib/Net/ISC/DHCPd/Config/Key.pm @@ -46,7 +46,7 @@ has [qw/ name algorithm secret /] => ( ); sub _build_children { [undef] } -sub _build_regex { qr{^\s* key \s (")?(\S+)\1 }x } +sub _build_regex { qr{^\s* key \s (")?(\S+)(\1|$) }x } =head1 METHODS diff --git a/lib/Net/ISC/DHCPd/Config/Role.pm b/lib/Net/ISC/DHCPd/Config/Role.pm index 2d65563..c8bd557 100644 --- a/lib/Net/ISC/DHCPd/Config/Role.pm +++ b/lib/Net/ISC/DHCPd/Config/Role.pm @@ -291,6 +291,9 @@ sub parse { last LINE; } } + elsif($line =~ /^\s*{/) { + next LINE; + } elsif($line =~ /^\s*$/o) { next LINE; } diff --git a/lib/Net/ISC/DHCPd/Config/Zone.pm b/lib/Net/ISC/DHCPd/Config/Zone.pm new file mode 100644 index 0000000..1df89fd --- /dev/null +++ b/lib/Net/ISC/DHCPd/Config/Zone.pm @@ -0,0 +1,107 @@ +package Net::ISC::DHCPd::Config::Zone; + +=head1 NAME + +Net::ISC::DHCPd::Config::Key - Server key + +=head1 DESCRIPTION + +See L<Net::ISC::DHCPd::Config::Role> for methods and attributes without +documentation. + +An instance from this class, comes from / will produce the block below: + + $name_attribute_value $value_attribute_value; + + key "$name" { + algorithm $algorithm; + secret "$secret"; + }; + +=head1 SYNOPSIS + +See L<Net::ISC::DHCPd::Config/SYNOPSIS>. + +=cut + +use Moose; + +with 'Net::ISC::DHCPd::Config::Role'; + +=head1 ATTRIBUTES + +=head2 name + +Name of the key - See L</DESCRIPTION> for details. + +=head2 algorithm + +=head2 secret + +=cut + +has [qw/ name key primary /] => ( + is => 'rw', # TODO: WILL PROBABLY CHANGE! + isa => 'Str', +); + +sub _build_children { [undef] } +# not sure if this can be quoted or not +sub _build_regex { qr{^\s* zone \s (")?(\S+)(\1|$) }x } + +=head1 METHODS + +=head2 slurp + +This method is used by L<Net::ISC::DHCPd::Config::Role/parse>, and will +slurp the content of the function, instead of trying to parse the +statements. + +=cut + +sub slurp { + my($self, $line) = @_; + + return 'last' if($line =~ /^\s*}/); + # not sure if these can really be quoted + $self->primary($1) if($line =~ /primary \s+ (\S+);/x); + $self->key($2) if($line =~ /key \s+ ("?)(\S+)\1;/x); + return 'next'; +} + +=head2 captured_to_args + +See L<Net::ISC::DHCPd::Config::Role/captured_to_args>. + +=cut + +sub captured_to_args { + return { name => $_[2] }; # $_[1] == quote or empty string +} + +=head2 generate + +See L<Net::ISC::DHCPd::Config::Role/generate>. + +=cut + +sub generate { + my $self = shift; + + return( + sprintf('zone %s {', $self->name), + $self->primary ? (sprintf ' primary %s;', $self->primary) : (), + $self->key ? (sprintf ' key %s;', $self->key) : (), + '}', # TODO: should this really be here? + ); +} + +=head1 COPYRIGHT & LICENSE + +=head1 AUTHOR + +See L<Net::ISC::DHCPd>. + +=cut + +1; -- 1.7.2.5 From baf89d56a498689f3557f58cdceadbcf5120bbd5 Mon Sep 17 00:00:00 2001 From: Robert Drake <rdrake@direcpath.net> Date: Mon, 19 Nov 2012 00:17:39 -0500 Subject: [PATCH 2/4] Fixed documentation in Zone.pm --- lib/Net/ISC/DHCPd/Config/Zone.pm | 14 +++++++------- 1 files changed, 7 insertions(+), 7 deletions(-) diff --git a/lib/Net/ISC/DHCPd/Config/Zone.pm b/lib/Net/ISC/DHCPd/Config/Zone.pm index 1df89fd..1375291 100644 --- a/lib/Net/ISC/DHCPd/Config/Zone.pm +++ b/lib/Net/ISC/DHCPd/Config/Zone.pm @@ -2,7 +2,7 @@ package Net::ISC::DHCPd::Config::Zone; =head1 NAME -Net::ISC::DHCPd::Config::Key - Server key +Net::ISC::DHCPd::Config::Zone - Server Zone =head1 DESCRIPTION @@ -13,9 +13,9 @@ An instance from this class, comes from / will produce the block below: $name_attribute_value $value_attribute_value; - key "$name" { - algorithm $algorithm; - secret "$secret"; + zone $name { + primary $primary; + key $key; }; =head1 SYNOPSIS @@ -32,11 +32,11 @@ with 'Net::ISC::DHCPd::Config::Role'; =head2 name -Name of the key - See L</DESCRIPTION> for details. +Name of the Zone - See L</DESCRIPTION> for details. -=head2 algorithm +=head2 primary -=head2 secret +=head2 key =cut -- 1.7.2.5 From c941f48b12bf0da94db0c915ffa441cc737a052a Mon Sep 17 00:00:00 2001 From: Robert Drake <rdrake@direcpath.net> Date: Mon, 19 Nov 2012 00:24:25 -0500 Subject: [PATCH 3/4] Added Class to tracked values --- lib/Net/ISC/DHCPd/Config.pm | 1 + lib/Net/ISC/DHCPd/Config/Class.pm | 79 +++++++++++++++++++++++++++++++++++++ 2 files changed, 80 insertions(+), 0 deletions(-) create mode 100644 lib/Net/ISC/DHCPd/Config/Class.pm diff --git a/lib/Net/ISC/DHCPd/Config.pm b/lib/Net/ISC/DHCPd/Config.pm index 77ba543..6f14dc0 100644 --- a/lib/Net/ISC/DHCPd/Config.pm +++ b/lib/Net/ISC/DHCPd/Config.pm @@ -106,6 +106,7 @@ with 'Net::ISC::DHCPd::Config::Root'; __PACKAGE__->create_children(qw/ Net::ISC::DHCPd::Config::Host + Net::ISC::DHCPd::Config::Class Net::ISC::DHCPd::Config::Subnet Net::ISC::DHCPd::Config::SharedNetwork Net::ISC::DHCPd::Config::Function diff --git a/lib/Net/ISC/DHCPd/Config/Class.pm b/lib/Net/ISC/DHCPd/Config/Class.pm new file mode 100644 index 0000000..0562da4 --- /dev/null +++ b/lib/Net/ISC/DHCPd/Config/Class.pm @@ -0,0 +1,79 @@ +package Net::ISC::DHCPd::Config::Class; + +=head1 NAME + +Net::ISC::DHCPd::Config::Class; + +=head1 DESCRIPTION + +See L<Net::ISC::DHCPd::Config::Role> for methods and attributes without +documentation. + +An instance from this class, comes from / will produce the block below: + + class "$name" { + ... + } + +=head1 SYNOPSIS + +See L<Net::ISC::DHCPd::Config/SYNOPSIS>. + +=cut + +use Moose; + +with 'Net::ISC::DHCPd::Config::Role'; + +=head1 ATTRIBUTES + +=head2 name + +Name of the key - See L</DESCRIPTION> for details. + +=head2 algorithm + +=head2 secret + +=cut + +# match will get treated as a KeyValue +__PACKAGE__->create_children(qw/ + Net::ISC::DHCPd::Config::Option + Net::ISC::DHCPd::Config::KeyValue +/); + +sub _build_regex { qr{^\s* class \s (")?(.*?)(\1|$) }x } + +=head1 METHODS + +=head2 captured_to_args + +See L<Net::ISC::DHCPd::Config::Role/captured_to_args>. + +=cut + +sub captured_to_args { + return { name => $_[2] }; # $_[1] == quote or empty string +} + +=head2 generate + +See L<Net::ISC::DHCPd::Config::Role/generate>. + +=cut + +sub generate { + my $self = shift; + return sprintf('class "%s" {', $self->name), $self->_generate_config_from_children, '}'; +} + +=head1 COPYRIGHT & LICENSE + +=head1 AUTHOR + +See L<Net::ISC::DHCPd>. + +=cut + +1; -- 1.7.2.5 From f39e61bb93768cbc447af396f9979d4d1ca5595e Mon Sep 17 00:00:00 2001 From: Robert Drake <rdrake@direcpath.net> Date: Mon, 19 Nov 2012 00:56:09 -0500 Subject: [PATCH 4/4] Small fixes to Class. Added Condtional to Config.pm. Fixed OptionSpace to not require encapsulate line. --- lib/Net/ISC/DHCPd/Config.pm | 1 + lib/Net/ISC/DHCPd/Config/Class.pm | 5 +++++ lib/Net/ISC/DHCPd/Config/OptionSpace.pm | 4 ++-- 3 files changed, 8 insertions(+), 2 deletions(-) diff --git a/lib/Net/ISC/DHCPd/Config.pm b/lib/Net/ISC/DHCPd/Config.pm index 6f14dc0..ef1790d 100644 --- a/lib/Net/ISC/DHCPd/Config.pm +++ b/lib/Net/ISC/DHCPd/Config.pm @@ -107,6 +107,7 @@ with 'Net::ISC::DHCPd::Config::Root'; __PACKAGE__->create_children(qw/ Net::ISC::DHCPd::Config::Host Net::ISC::DHCPd::Config::Class + Net::ISC::DHCPd::Config::Conditional Net::ISC::DHCPd::Config::Subnet Net::ISC::DHCPd::Config::SharedNetwork Net::ISC::DHCPd::Config::Function diff --git a/lib/Net/ISC/DHCPd/Config/Class.pm b/lib/Net/ISC/DHCPd/Config/Class.pm index 0562da4..8c895f5 100644 --- a/lib/Net/ISC/DHCPd/Config/Class.pm +++ b/lib/Net/ISC/DHCPd/Config/Class.pm @@ -37,6 +37,11 @@ Name of the key - See L</DESCRIPTION> for details. =cut +has [qw/ name /] => ( + is => 'rw', + isa => 'Str', +); + # match will get treated as a KeyValue __PACKAGE__->create_children(qw/ Net::ISC::DHCPd::Config::Option diff --git a/lib/Net/ISC/DHCPd/Config/OptionSpace.pm b/lib/Net/ISC/DHCPd/Config/OptionSpace.pm index ed9a713..254186f 100644 --- a/lib/Net/ISC/DHCPd/Config/OptionSpace.pm +++ b/lib/Net/ISC/DHCPd/Config/OptionSpace.pm @@ -129,11 +129,11 @@ sub generate { return( sprintf('option space %s;', $self->prefix), $self->generate_config_from_children, - sprintf('option %s code %i = encapsulate %s;', + $self->name ? (sprintf 'option %s code %i = encapsulate %s;', $self->name, $self->code, $self->prefix, - ), + ) : (), ); } -- 1.7.2.5
Closing this since it's mine. I'll reintroduce the patch once I get things working with perl-blead. On Mon Nov 19 01:22:15 2012, RDRAKE wrote: Show quoted text
> I'm attaching a patch file that fixes Class, Zones, Conditionals, and > some parsing errors I was getting on my dhcpd.conf file. > > I'd really like to give you a copy of my dhcpd.conf for testing because > it's 400Kb and does some interesting things, but it has some customer > data so I want to clean it up before giving it out. > > I'll give some examples though: > > Keys were failing because a newline wasn't an accepted possible > termination for the regex. That should be fixed now. > > key dhcpserver > { > algorithm hmac-md5; > secret "..."; > }; > > Some of my "option space" don't have encapsulate. I'm not sure if they > work properly without it, but that's how it was given to me by the > vendor. I've changed OptionSpace to not require it now. > > option space ubnt; > option ubnt.unifi-address code 1 = ip-address; > > Conditionals also work now: > > if option vendor-class-identifier = "ubnt" > { > vendor-option-space ubnt; > } > > > Classes work: > > class "SipuraATA" > { > match if (substring(option host-name,0,9) = "SipuraSPA"); > } > > And finally, Zones are also allowed. These are used when you want to > enable dynamic DNS updates through DHCP: > > zone staging.fake-domain-name-here.net > { > primary 1.2.3.4; > key staging-key; > } > > > I get a test result passed for "make test" but I didn't add any new unit > tests. If that is a problem let me know and I'll write some for the new > things. > > Also let me know if it breaks or does something you don't want it to do. > > Thanks, > Robert Drake