• R/O
  • HTTP
  • SSH
  • HTTPS

Commit

Tags
Keine Tags

Frequently used words (click to add to your profile)

javac++androidlinuxc#windowsobjective-ccocoa誰得qtpythonphprubygameguibathyscaphec計画中(planning stage)翻訳omegatframeworktwitterdomtestvb.netdirectxゲームエンジンbtronarduinopreviewer

恥ずかしい勘違いから生まれた、DHCP6の不要かつ部分的な実装


Commit MetaInfo

Revisiondca7e1d8f8b6c961e03d3274683c2b0d0ef6be79 (tree)
Zeit2021-08-11 23:35:27
Autordyknon <dyknon@user...>
Commiterdyknon

Log Message

add Net::DHCP6::Option::DnsServer

Ändern Zusammenfassung

Diff

--- a/Net/DHCP6/AbstractOption/DUID.pm
+++ b/Net/DHCP6/AbstractOption/DUID.pm
@@ -22,7 +22,7 @@ sub new {
2222 $self = \$opts{data};
2323 }elsif(@_ == 1){
2424 $self = shift;
25- $self = \$self if(!ref $self);
25+ $self = \$self if(!length ref $self);
2626 }elsif(lc($_[0]) eq "llt" && @_ == 4){
2727 shift; #llt
2828 $self = \(pack("S>S>L>", 1, shift, shift) . shift);
--- a/Net/DHCP6/AbstractOption/List.pm
+++ b/Net/DHCP6/AbstractOption/List.pm
@@ -35,6 +35,12 @@ sub serialize_elem { ... }
3535 # must overridden
3636 sub consume_elem { ... }
3737
38+# may overridden
39+sub coerce {
40+ my $class_or_self = shift;
41+ shift;
42+}
43+
3844 sub all_elems {
3945 my $self = shift;
4046 @$self;
--- a/Net/DHCP6/Message.pm
+++ b/Net/DHCP6/Message.pm
@@ -20,7 +20,7 @@ sub gen_xid {
2020 sub new {
2121 my $class = shift;
2222 my $type = shift;
23- my $id = ref $_[0] ? undef : shift;
23+ my $id = length ref $_[0] ? undef : shift;
2424 unless(defined $id){
2525 $id = $class->gen_xid;
2626 }
--- /dev/null
+++ b/Net/DHCP6/Option/DnsServer.pm
@@ -0,0 +1,33 @@
1+package Net::DHCP6::Option::DnsServer;
2+# RFC3646 3.
3+
4+use strict;
5+use warnings;
6+use Net::DHCP6::AbstractOption::Vector;
7+use Net::DHCP6::Parameters qw/DHCP6_OPT_DNS_SERVERS/;
8+use Net::DHCP6::Value::Ipv6Addr;
9+
10+our $VERSION = "0.0.1";
11+our @ISA = qw/Net::DHCP6::AbstractOption::Vector/;
12+
13+use constant code => DHCP6_OPT_DNS_SERVERS;
14+use constant name => "DnsServer";
15+use constant len_elem => 16;
16+
17+sub serialize_elem {
18+ my $class_or_self = shift;
19+ shift->raw;
20+}
21+
22+sub parse_elem {
23+ my $class_or_self = shift;
24+ Net::DHCP6::Value::Ipv6Addr->from_bytes(shift);
25+}
26+
27+sub coerce {
28+ my $class_or_self = shift;
29+ Net::DHCP6::Value::Ipv6Addr->new(shift);
30+}
31+
32+__PACKAGE__->register_option;
33+1;
--- a/Net/DHCP6/Option/OptionRequest.pm
+++ b/Net/DHCP6/Option/OptionRequest.pm
@@ -23,5 +23,12 @@ sub parse_elem {
2323 unpack("S>", shift);
2424 }
2525
26+sub coerce {
27+ my $class_or_self = shift;
28+ my $val = 0+shift;
29+ die "out of range" if($val < 0 || $val >= 2**16);
30+ $val;
31+}
32+
2633 __PACKAGE__->register_option;
2734 1;
--- /dev/null
+++ b/Net/DHCP6/Value/Ipv6Addr.pm
@@ -0,0 +1,169 @@
1+package Net::DHCP6::Value::Ipv6Addr;
2+
3+use strict;
4+use warnings;
5+
6+our $VERSION = "0.0.1";
7+
8+sub new {
9+ my $class = shift;
10+ if(@_ == 0){
11+ $class->from_array(0, 0, 0, 0, 0, 0, 0, 0);
12+ }elsif(@_ == 1){
13+ my $self = shift;
14+ if(ref $self eq ""){
15+ $class->from_str($self);
16+ }elsif(ref $self eq "ARRAY" && !eval{$self->isa("ARRAY")}){
17+ $class->from_array(@$self);
18+ }elsif(eval{$self->DOES(__PACKAGE__)}){
19+ $class->from_bytes($self->raw);
20+ }elsif(eval{$self->DOES("Math::BigInt")}){
21+ $class->from_bigint($self);
22+ }else{
23+ $class->from_str("$self");
24+ }
25+ }else{
26+ $class->from_array(@_);
27+ }
28+}
29+
30+# RFC4291 2.2.
31+sub from_str {
32+ my $class = shift;
33+ my $str = shift;
34+
35+# disallow multiple "::"
36+ die if($str =~ /:::|::.*::/);
37+
38+# disallow zero length pieces other than "::"
39+ die if($str =~ /^:(?!:)/);
40+ die if($str =~ /(?<!:):$/);
41+
42+# test other restrictions of ipv6 address syntax
43+ die if($str !~ /^([0-9a-fA-F:]+)((?<=:)[0-9]+(?:\.[0-9]+){3})?$/);
44+
45+# extract ipv4 part if it exists
46+ my $v4part;
47+ if($2){
48+ $str = $1 . "0:0"; # placeholder of ipv4 part
49+ $v4part = pack "C*", map{
50+ die if($_ >= 256);
51+ $_;
52+ }split(/\./, $2);
53+ }
54+
55+ my @parts = split(/:/, $str, -1);
56+ if($str =~ /^::/){
57+ shift @parts;
58+ }
59+ if($str =~ /::$/){
60+ pop @parts;
61+ }
62+ my $zeros = 8 - @parts + 1;
63+
64+ my $self = pack "S>*", map{
65+ if(length $_){
66+# decode hex
67+ die if(hex($_) >= 0x10000);
68+ hex($_);
69+ }else{
70+# replace :: with *one or more* zeros
71+ die if($zeros == 0);
72+ (0) x $zeros;
73+ }
74+ } @parts;
75+ die "invalid length" if(length $self != 16);
76+
77+# concatenate ipv4 part
78+ if(defined $v4part){
79+ $self = substr($self, 0, 12) . $v4part;
80+ }
81+
82+ $class->from_bytes($self);
83+}
84+
85+sub from_bytes {
86+ my $class = shift;
87+ my $value = shift;
88+ die "invalid length" if(length $value != 16);
89+ my $self = \$value;
90+ bless $self, $class;
91+}
92+
93+sub from_bigint {
94+ my $class = shift;
95+ my $raw = "\0"x16 . shift->to_bytes; # big endian = network byte order
96+ my $sould_zeros = substr($raw, 0, length($raw) - 16);
97+ die "out of range" if($sould_zeros ne "\0" x length($sould_zeros));
98+ $class->from_bytes(substr($raw, length($raw) - 16));
99+}
100+
101+sub from_array {
102+ my $class = shift;
103+ my $self;
104+ if(@_ == 16){
105+ $self = pack "C*", @_;
106+ }elsif(@_ == 8){
107+ $self = pack "S>*", @_;
108+ }else{
109+ die "invalid length";
110+ }
111+ $class->from_bytes($self);
112+}
113+
114+# RFC4291 2.2.
115+# RFC5952 4.
116+sub str {
117+ my $self = shift;
118+ my @parts = unpack "S>*", $$self;
119+
120+ my $start_mzeros;
121+ my $length_mzeros = 0;
122+ {
123+ my $start_zeros;
124+ my $length_zeros = 0;
125+ while(my ($i, $v) = each(@parts)){
126+ if($v){
127+ if($length_zeros > $length_mzeros){
128+ $start_mzeros = $start_zeros;
129+ $length_mzeros = $length_zeros;
130+ }
131+ $length_zeros = 0;
132+ }else{
133+ if($length_zeros++ == 0){
134+ $start_zeros = $i;
135+ }
136+ }
137+ }
138+ if($length_zeros > $length_mzeros){
139+ $start_mzeros = $start_zeros;
140+ $length_mzeros = $length_zeros;
141+ }
142+ }
143+
144+ @parts = map{sprintf "%x", $_} @parts;
145+ if($length_mzeros > 1){
146+ my $i1 = $start_mzeros - 1;
147+ my $i2 = $start_mzeros + $length_mzeros;
148+ @parts = (@parts[0..$i1], "", @parts[$i2..$#parts]);
149+ }
150+ if($parts[0] eq ""){
151+ unshift @parts, "";
152+ }
153+ if($parts[$#parts] eq ""){
154+ push @parts, "";
155+ }
156+ join(":", @parts);
157+}
158+
159+sub raw {
160+ my $self = shift;
161+ $$self;
162+}
163+
164+use overload (
165+ '""' => sub {
166+ my $self = shift;
167+ $self->str;
168+ }
169+);