Explanation
We can use GNU Parallel to mix-and-match several commands and options that are at stake here.
We can determine the public IP address through DNS with dig
(the DNS lookup utility from BIND), this lets us try out both UDP (with the +notcp
option) and TCP (+tcp
option), leaving only ICMP behind. However, we can try sending all these queries to multiple independent destination IPv4 and IPv6 addresses, making it more likely that the load-balancing of the connection will take place, returning more unique responses, as expected.
As the results may contain many duplicates (i.e., if IPv6 is missing or if UDP, TCP and varying the dst-addr return identical results), we'll get rid of these with sort
and uniq
.
It would appear that the positioning of -4
and -6
with dig
might also be handled differently — if positioned right after dig
before the @
specifier, then it's enforced as a hard requirement; if positioned past the @
specifier and/or at the end of the command line, it's enforced as a soft requirement (IPv4 will be used if IPv6 is missing); the snippet below uses it as a soft requirement to avoid having to implement error-handling.
Solution
Here's the full solution:
parallel -k dig -t txt o-o.myaddr.l.google.com +short \
::: @ns{1,2,3,4}.google.com ::: -4 -6 ::: +notcp +tcp \
| sort -n | uniq \
| parallel -vk ::: "echo" "host" "whois" :::: /dev/stdin
Here's the same snippet as a single line:
parallel -k dig -t txt o-o.myaddr.l.google.com +short ::: @ns{1,2,3,4}.google.com ::: -4 -6 ::: +notcp +tcp | sort -n | uniq | parallel -vk ::: "echo" "host" "whois" :::: /dev/stdin
Here's the same snippet SO inline:
parallel -k dig -t txt o-o.myaddr.l.google.com +short ::: @ns{1,2,3,4}.google.com ::: -4 -6 ::: +notcp +tcp | sort -n | uniq | parallel -vk ::: "echo" "host" "whois" :::: /dev/stdin
Note that depending on whois
in your system, you might have to change "whois"
to something like "whois -a"
(for ARIN), whois -A
(for APNIC) or "whois -r"
(for RIPE) to make sure that the whois request for IPv6 addresses gets sent to the proper place; this is exactly why I'm using the quotation marks in the above snippet:
parallel -k dig -t txt o-o.myaddr.l.google.com +short ::: @ns{1,2,3,4}.google.com ::: -4 -6 ::: +notcp +tcp | sort -n | uniq | parallel -vk ::: "echo" "host" "whois -a" :::: /dev/stdin
Testing
Here's a demonstration of what the two parallel
invocations above work to accomplish:
% parallel -k echo dig -t txt o-o.myaddr.l.google.com +short \
? ::: @ns{1,2,3,4}.google.com ::: -4 -6 ::: +notcp +tcp
dig -t txt o-o.myaddr.l.google.com +short @ns1.google.com -4 +notcp
dig -t txt o-o.myaddr.l.google.com +short @ns1.google.com -4 +tcp
dig -t txt o-o.myaddr.l.google.com +short @ns1.google.com -6 +notcp
dig -t txt o-o.myaddr.l.google.com +short @ns1.google.com -6 +tcp
dig -t txt o-o.myaddr.l.google.com +short @ns2.google.com -4 +notcp
dig -t txt o-o.myaddr.l.google.com +short @ns2.google.com -4 +tcp
dig -t txt o-o.myaddr.l.google.com +short @ns2.google.com -6 +notcp
dig -t txt o-o.myaddr.l.google.com +short @ns2.google.com -6 +tcp
dig -t txt o-o.myaddr.l.google.com +short @ns3.google.com -4 +notcp
dig -t txt o-o.myaddr.l.google.com +short @ns3.google.com -4 +tcp
dig -t txt o-o.myaddr.l.google.com +short @ns3.google.com -6 +notcp
dig -t txt o-o.myaddr.l.google.com +short @ns3.google.com -6 +tcp
dig -t txt o-o.myaddr.l.google.com +short @ns4.google.com -4 +notcp
dig -t txt o-o.myaddr.l.google.com +short @ns4.google.com -4 +tcp
dig -t txt o-o.myaddr.l.google.com +short @ns4.google.com -6 +notcp
dig -t txt o-o.myaddr.l.google.com +short @ns4.google.com -6 +tcp
%
% printf '"%s"\n"%s"\n"%s"\n"%s"' "127.0.0.1" "127.0.0.1" "::1" "::1" \
? | sort -n | uniq \
? | parallel -k echo ::: "echo" "host" "whois -a" :::: /dev/stdin
echo "127.0.0.1"
echo "::1"
host "127.0.0.1"
host "::1"
whois -a "127.0.0.1"
whois -a "::1"
%