Groovy and DNS query to get your external IP address

I stumbled upon this Stackoverflow question:

and got interested into the way to get your external IP by using a DNS lookup, as presented in this answer:

It’s an interesting idea and implementation and I also agree with the poster:

  • DNS query is a bit faster
  • More importantly, I have a feeling it’s more reliable. I know that sites can be slow, DNS query is less likely to be so
  • Given the investment in hosting the DNS service on a large scale, they service is likely more robust and likely to stay there longer than sites

Anyway, if you are using Oracle Java, then you already have a JNDI DNS provider built-in. You can read more about it here:

This Stackoverflow question:

specifically this answer:

has an example code to query a generic DNS server, provided you know it’s IP address. Below is a Groovy script that combines the information from the above links:

  • Gives an example of how a default way to perform a DNS query would be – getIp method
  • Gives a way to perform DNS query on the specific DNS server – getIpUsingDnsServer method
  • Uses these to query myip.opendns.com to get your external IP

Read more about OpenDNS myip entry here:

Here’s the script itself:

import javax.naming.Context
import javax.naming.NamingEnumeration
import javax.naming.directory.Attribute
import javax.naming.directory.Attributes
import javax.naming.directory.DirContext
import javax.naming.directory.InitialDirContext

class DnsPrb {
   static main(String[] args) {
      new DnsPrb().run()
   }
   
   def run() {
      String dnsServer = 'resolver4.opendns.com'
      String dnsIp = getIp dnsServer
      println("$dnsServer -> $dnsIp")
      
      def myIps = getIpUsingDnsServer dnsServer, 'myip.opendns.com'
      println("myIps: $myIps")
   }

   String getIpUsingDnsServer(String dnsServer, String name) {
      Properties env = new Properties()
      env.put Context.INITIAL_CONTEXT_FACTORY, 'com.sun.jndi.dns.DnsContextFactory'
      env.put Context.PROVIDER_URL, "dns://$dnsServer".toString()

      DirContext ictx = new InitialDirContext(env)
      String[] types = ["A", "AAAA"]
      Attributes attrs = ictx.getAttributes name, types

      NamingEnumeration<? extends Attribute> e = attrs.all
      def ips = e.collect { it.get() }
      ips
   }

   String getIp(String name) {
      InetAddress dnsInetAddress = InetAddress.getByName name
      String ip = dnsInetAddress.hostAddress
      ip
   }
}