恥ずかしい勘違いから生まれた、DHCP6の不要かつ部分的な実装
Revisão | ceb17ba29fac5bb4d448816dfdf252b1b9faf664 (tree) |
---|---|
Hora | 2021-08-18 22:02:59 |
Autor | dyknon <dyknon@user...> |
Commiter | dyknon |
Rewrite ipv6 address parser
@@ -28,58 +28,37 @@ sub new { | ||
28 | 28 | } |
29 | 29 | |
30 | 30 | # RFC4291 2.2. |
31 | +sub from_str_helper { | |
32 | + length $_[0] ? pack("S>*", map{hex $_}split(/:/, $_[0])) : ""; | |
33 | +} | |
31 | 34 | sub from_str { |
32 | 35 | my $class = shift; |
33 | 36 | my $str = shift; |
34 | 37 | |
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; | |
38 | + if($str !~ /^ | |
39 | + ( | |
40 | + [0-9a-fA-F]{1,4} | |
41 | + (?: : [0-9a-fA-F]{1,4})* | |
42 | + )? | |
43 | + ( :: ( | |
44 | + [0-9a-fA-F]{1,4} | |
45 | + (?: : [0-9a-fA-F]{1,4})* | |
46 | + )? )? | |
47 | + (?: | |
48 | + (?: (?<! : ) : )? | |
49 | + (?<= : ) | |
50 | + ( [0-9]+ (?: \. [0-9]+ ){3} ) | |
51 | + )? | |
52 | + $/x){ | |
53 | + die "invalid address format"; | |
80 | 54 | } |
81 | - | |
82 | - $class->from_bytes($self); | |
55 | + my $left = from_str_helper($1); | |
56 | + my $zeros = !!$2; | |
57 | + my $right = from_str_helper($3) . ($4 ? pack("C*", split(/\./, $4)) : ""); | |
58 | + die "too long address" if(length($left . $right) + $zeros*2 > 16); | |
59 | + my $nez = 16 - length($left . $right); | |
60 | + die "not engough address length" if($nez && !$zeros); | |
61 | + $class->from_bytes($left . "\0"x$nez . $right); | |
83 | 62 | } |
84 | 63 | |
85 | 64 | sub from_bytes { |