diff options
Diffstat (limited to 'lib/VNDBUtil.pm')
-rw-r--r-- | lib/VNDBUtil.pm | 19 |
1 files changed, 12 insertions, 7 deletions
diff --git a/lib/VNDBUtil.pm b/lib/VNDBUtil.pm index 5e7135cf..c864fda9 100644 --- a/lib/VNDBUtil.pm +++ b/lib/VNDBUtil.pm @@ -7,7 +7,7 @@ use warnings; use Exporter 'import'; use Encode 'encode_utf8'; use Unicode::Normalize 'NFKD'; -use Socket 'inet_pton', 'inet_ntop', 'AF_INET6'; +use Socket 'inet_pton', 'inet_ntop', 'AF_INET', 'AF_INET6'; our @EXPORT = qw|shorten bb2html gtintype normalize normalize_titles normalize_query imgsize norm_ip|; @@ -246,17 +246,22 @@ sub imgsize { # Normalized IP address to use for duplicate detection/throttling. For IPv4 -# this is just the normal address, but for IPv6 this is the /48 subnet, with -# the rest of the address zero'd. +# this is the /23 subnet (is this enough?), for IPv6 the /48 subnet, with the +# least significant bits of the address zero'd. sub norm_ip { my $ip = shift; - return $ip if $ip !~ /:/; - # There's a whole bunch of IPv6 manipulation modules on CPAN, but many seem + # There's a whole bunch of IP manipulation modules on CPAN, but many seem # quite bloated and still don't offer the functionality to return an IP # with its mask applied (admittedly not a common operation). The libc - # socket functions will do fine in parsing and formatting IPv6 addresses, - # and the actual masking is quite trivial in binary form. + # socket functions will do fine in parsing and formatting addresses, and + # the actual masking is quite trivial in binary form. + my $v4 = inet_pton AF_INET, $ip; + if($v4) { + $v4 =~ s/(..)(.)./$1 . chr(ord($2) & 254) . "\0"/se; + return inet_ntop AF_INET, $v4; + } + $ip = inet_pton AF_INET6, $ip; return '::' if !$ip; $ip =~ s/^(.{6}).+$/$1 . "\0"x10/se; |