恥ずかしい勘違いから生まれた、DHCP6の不要かつ部分的な実装
Revision | f2c9736b4ee41d8287f4961fae6d87f53fb2f63f (tree) |
---|---|
Time | 2021-08-12 21:47:29 |
Author | dyknon <dyknon@user...> |
Commiter | dyknon |
Domain Search List Option
@@ -0,0 +1,27 @@ | ||
1 | +package Net::DHCP6::AbstractOption::DomainNameList; | |
2 | +# base class for DHCP option containing a domain name list | |
3 | +# RFC8415 10. | |
4 | + | |
5 | +use strict; | |
6 | +use warnings; | |
7 | +use Net::DHCP6::AbstractOption::List; | |
8 | +use Net::DHCP6::Value::DomainName; | |
9 | + | |
10 | +our $VERSION = "0.001"; | |
11 | +our @ISA = qw/Net::DHCP6::AbstractOption::List/; | |
12 | + | |
13 | +# must overridden | |
14 | +#sub code { ... } | |
15 | + | |
16 | +sub serialize_elem { | |
17 | + my $class_or_self = shift; | |
18 | + shift->serialize; | |
19 | +} | |
20 | + | |
21 | +sub consume_elem { | |
22 | + my $class_or_self = shift; | |
23 | + my $buf = shift; | |
24 | + Net::DHCP6::Value::DomainName->consume_buf($buf); | |
25 | +} | |
26 | + | |
27 | +1; |
@@ -0,0 +1,16 @@ | ||
1 | +package Net::DHCP6::Option::DomainList; | |
2 | +# RFC3646 4. | |
3 | + | |
4 | +use strict; | |
5 | +use warnings; | |
6 | +use Net::DHCP6::AbstractOption::DomainNameList; | |
7 | +use Net::DHCP6::Parameters qw/DHCP6_OPT_DOMAIN_LIST/; | |
8 | + | |
9 | +our $VERSION = "0.001"; | |
10 | +our @ISA = qw/Net::DHCP6::AbstractOption::DomainNameList/; | |
11 | + | |
12 | +use constant code => DHCP6_OPT_DOMAIN_LIST; | |
13 | +use constant name => "DomainList"; | |
14 | + | |
15 | +__PACKAGE__->register_option; | |
16 | +1; |
@@ -0,0 +1,105 @@ | ||
1 | +package Net::DHCP6::Value::DomainName; | |
2 | +# RFC8415 10. | |
3 | +# RFC1035 2.3.1. | |
4 | +# RFC1035 2.3.4. | |
5 | +# RFC1035 3.1. | |
6 | + | |
7 | +use strict; | |
8 | +use warnings; | |
9 | + | |
10 | +our $VERSION = "0.001"; | |
11 | + | |
12 | +sub root { | |
13 | + my $class = shift; | |
14 | + my $self = [""]; | |
15 | + bless $self, $class; | |
16 | +} | |
17 | + | |
18 | +sub new { | |
19 | + my $class = shift; | |
20 | + if(@_ == 1){ | |
21 | + if($_[0] eq "." || $_[0] eq ""){ | |
22 | + return $class->root; | |
23 | + } | |
24 | + my @label = split(/\./, $_[0], -1); | |
25 | + if(@label == 1){ | |
26 | + push @label, ""; | |
27 | + } | |
28 | + $class->new(@label); | |
29 | + }else{ | |
30 | + push @label, "" if($_[$#_] ne ""); | |
31 | + if(join "", map{length $_ > 63} @_){ | |
32 | + die "length of domain label > 63"; | |
33 | + } | |
34 | + if(length join(".", @_) > 254){ | |
35 | + die "length of domain name > 255"; | |
36 | + } | |
37 | + if(join "", | |
38 | + map{$_ !~ /^[A-Za-z](?:[A-Za-z0-9-]*[A-Za-z0-9])?$/} | |
39 | + @_[0 .. ($#_-1)] | |
40 | + ){ | |
41 | + die "invalid domain name"; | |
42 | + } | |
43 | + my $self = [@_]; | |
44 | + bless $self, $class; | |
45 | + } | |
46 | +} | |
47 | + | |
48 | +sub new_relaxed { | |
49 | + my $class = shift; | |
50 | + if(@_ == 1 && ref $_[0] ne ""){ | |
51 | + $class->new_relaxed(@{$_[0]}); | |
52 | + }else{ | |
53 | + my $self = [@_]; | |
54 | + bless $self, $class; | |
55 | + } | |
56 | +} | |
57 | + | |
58 | +sub consume_buf { | |
59 | + my $class = shift; | |
60 | + my $buf = shift; | |
61 | + my @label; | |
62 | + while(1){ | |
63 | + die "null-label not found" if(length $$buf < 1); | |
64 | + my $len = unpack("C", substr $$buf, 0, 1); | |
65 | + if($len == 0){ | |
66 | + push @label, ""; | |
67 | + last; | |
68 | + } | |
69 | + die "imcomplete label" if(length $$buf < 1 + $len); | |
70 | + push @label, substr($$buf, 1, $len); | |
71 | + $$buf = substr($$buf, 1 + $len); | |
72 | + } | |
73 | + $class->new_relaxed(@label); | |
74 | +} | |
75 | + | |
76 | +sub labels { | |
77 | + my $self = shift; | |
78 | + @$self; | |
79 | +} | |
80 | + | |
81 | +sub str { | |
82 | + my $self = shift; | |
83 | + my @label = $self->labels; | |
84 | + @label = map{s/([^0-9A-Za-z-])/"\x".sprintf("%02x", ord($_))/ge} @label; | |
85 | + join(".", @label); | |
86 | +} | |
87 | + | |
88 | +sub serialize { | |
89 | + my $self = shift; | |
90 | + my @label = $self->labels; | |
91 | + die "not a FQDN" if($label[$#label] ne ""); | |
92 | + join "", map{ | |
93 | + die "length of label > 255" if(length $_ > 255); | |
94 | + pack("C", length $_) . $_; | |
95 | + } @label; | |
96 | +} | |
97 | + | |
98 | +use overload ( | |
99 | + '""' => sub { | |
100 | + my $self = shift; | |
101 | + $self->str; | |
102 | + } | |
103 | +); | |
104 | + | |
105 | +1; |