summaryrefslogtreecommitdiff
path: root/lib/VNDBUtil.pm
diff options
context:
space:
mode:
Diffstat (limited to 'lib/VNDBUtil.pm')
-rw-r--r--lib/VNDBUtil.pm19
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;