0

In UNIX shell, I'd like to script getting all public IPv4 and IPv6 addresses of my gateway, print it back, and then run both whois and host on all found addresses.

Additionally, because my connection is load-balanced, there might be more than one public IP-address, depending on whether ICMP, UDP or TCP is used (for example, traceroute -P UDP and traceroute -P ICMP always return different results), and/or depending on the source and the destination IP address.

What's the shortest UNIX shell snippet with which I can accomplish something like this?

cnst
  • 25,870
  • 6
  • 90
  • 122

1 Answers1

1

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"
%
cnst
  • 25,870
  • 6
  • 90
  • 122