#!/usr/bin/env perl # # ipnum2name - translate IP addresses in the input to DNS names # # $Id$ # when a lookup fails, returns the IP address itself # caches all results use warnings; use strict; use Socket qw( getaddrinfo getnameinfo ); my %ipnum2name; $| = 1; # force output line flushing my $ip4_rx = qr/([0-9]{1,3}(?:\.[0-9]{1,3}){3})/i; my $ip6_rx = qr/([0-9a-f]*:[0-9a-f:]+)/i; # not entirely accurate for IPv6, see https://stackoverflow.com/questions/53497/regular-expression-that-matches-valid-ipv6-addresses sub ipnum2name # thank you, https://www.perlmonks.org/?node_id=938198 { my ($num) = @_; my ( $err, @addrs ) = getaddrinfo( $num, 0 ); if ($err) { $num; } elsif ( my ( $err, $hostname ) = getnameinfo( $addrs[0]->{addr} ) ) { $err ? $num : $hostname; } } sub lookup { my ($num) = @_; if (!defined $ipnum2name{$num}) { $ipnum2name{$_} = ipnum2name($_) } $ipnum2name{$_} } while (<>) { chomp; my @line = split( /$ip4_rx/, $_ ); $_ = join('', map { /$ip4_rx/ ? lookup($_) : $_ } @line); @line = split( /$ip6_rx/, $_ ); print join('', map { /$ip6_rx/ ? lookup($_) : $_ } @line), "\n"; }