All pastes #1835159 Raw Edit

Mine

public text v1 · immutable
#1835159 ·published 2010-03-12 08:42 UTC
rendered paste body
#! /usr/bin/env perl

use Net::IP;
use IO::Socket::INET;
use IO::Socket::INET6;

# This script will remove:
#
# - A line with invalid IPv4 or IPv6 addresses.
# - A line with an IPv4 address or IPv6 address that has been seen before.
# - A line with an IPv4 or IPv6 address that we cannot connect to.
# - A line with a domain name that has been seen before.
#
# Input format: <domain name>,<ipv4 address>,<ipv6 address>


# These are used to avoid duplicate domains or addresses.
my %domain_names;
my %ipv4s;
my %ipv6s;

# Used for keeping statistics
my $reachable_ipv4s;
my $unreachable_ipv4s;
my $reachable_ipv6s; 
my $unreachable_ipv6s;
my %ipv4_types;
my %ipv6_types;

my $port = shift(@ARGV);

while (<>)
{
    chomp;

    if (/(.+),(.+),(.+)/)
    {
        my ($domain_name, $ipv4, $ipv6) = ($1, $2, $3);
        
        # First check for duplicates
        next if (exists $domain_names{$domain_name});
        $domain_names{$domain_name} = 1;

        next if (exists $ipv4s{$ipv4});
        $ipv4s{$ipv4} = 1;

        next if (exists $ipv6s{$ipv6});
        $ipv6s{$ipv6} = 1;
       

        # Skip non-globally-routable addresses
        my $ip = new Net::IP($ipv4) || next;
        $ipv4_types{$ip->iptype()}++;

        my $ip6 = new Net::IP($ipv6) || next;
        $ipv6_types{$ip6->iptype()}++;
        
        next if ($ip->iptype() ne  "PUBLIC");
        next if ($ip6->iptype() ne "GLOBAL-UNICAST");
        
        
        # Skip if we cannot connect to both addresses.
        my $unreachable_address = 0;
        my $ipv4_sock;
        my $ipv6_sock;

        # Try establishing a connection to the IPv4 address.
        if ($ipv4_sock = new IO::Socket::INET(PeerAddr => $ipv4, PeerPort => $port, Proto => 'tcp', Timeout => 5))
        {
            $reachable_ipv4s++;   
            close($ipv4_sock); # Graceful Shutdown 
        }
        else
        {
            $unreachable_ipv4s++;
            $unreachable_address = 1;
        }
        
        # Try establishing a connection to the IPv6 address.
        if ($ipv6_sock = new IO::Socket::INET6(PeerAddr => $ipv6, PeerPort => $port, Proto => 'tcp', Timeout => 5))
        {
            $reachable_ipv6s++;
            close($ipv4_sock); # Graceful Shutdown
        }
        else
        {
            $unreachable_ipv6s++;
            $unreachable_address = 1;
        }

        next if ($unreachable_address);
        
        print "$_\n";
    }
}

my $total = 0;
$total += $_ for (values %ipv4_types);

print "IPv4 Address Types:\n\n";
printf "%-30s%-15s%s\n", "Type", "Frequency", "Percentage";
for $key (sort { $ipv4_types{$b} <=> $ipv4_types{$a} } keys %ipv4_types)
{
    printf("%-30s%-15d%.2f\n", $key, $ipv4_types{$key}, $ipv4_types{$key} / $total * 100);
}
printf "%-30s%-15d%.2f\n", "Total", $total, 100;

print "\n";

print "IPv6 Address Types:\n\n";
printf "%-30s%-15s%s\n", "Type", "Frequency", "Percentage";
for $key (sort { $ipv6_types{$b} <=> $ipv6_types{$a} } keys %ipv6_types)
{
    printf("%-30s%-15d%.2f\n", $key, $ipv6_types{$key}, $ipv6_types{$key} / $total * 100);
}
printf "%-30s%-15d%.2f\n", "Total", $total, 100;

print "\n";

$total = $reachable_ipv4s + $unreachable_ipv4s;
printf "Reachable IPv4 Addresses: %d/%d (%.2f%%)\n", $reachable_ipv4s, $total, $reachable_ipv4s / $total * 100;
$total = $reachable_ipv6s + $unreachable_ipv6s;
printf "Reachable IPv6 Addresses: %d/%d (%.2f%%)\n", $reachable_ipv6s, $total, $reachable_ipv6s / $total * 100;