11

I need to get the DNS address, for example "http://stackoverflow.com/questions/ask". I used the following code and able to get in the form of 192.X.X.X.

  Hashtable env = new Hashtable();
  env.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.dns.DnsContextFactory");
  DirContext ictx = new InitialDirContext(env);
  String dnsServers = (String) ictx.getEnvironment().get("java.naming.provider.url");

  System.out.println("DNS Servers: " + dnsServers ); 
Kirk Woll
  • 76,112
  • 22
  • 180
  • 195
Manikandan
  • 1,479
  • 6
  • 48
  • 89

3 Answers3

18
InetAddress ia = InetAddress.getByAddress(new byte[] {74,125,127,106});
// or 
ia = InetAddress.getByName("74.125.127.106");
System.out.println(ia.getCanonicalHostName());
Clint
  • 8,988
  • 1
  • 26
  • 40
  • I give 216,239,51,99 in the byte[]. It asked me to type caste to byte for the first two(216 and 239). I type caste it. It prints 216.239.51.99 only not in words. – Manikandan Aug 18 '11 at 08:48
  • 1
    @Jack if you have linux/mac box and use dig -x 216.239.51.99 you will see that there is no answer for that number. That means there is no entry in DNS for it. That is why you get the number back in response. – Clint Aug 19 '11 at 16:48
9

I have taken the code linked to by @Sam DeHaan, cleaned it up a bit and tested it.

/**
 * Do a reverse DNS lookup to find the host name associated with an IP address. Gets results more often than
 * {@link java.net.InetAddress#getCanonicalHostName()}, but also tries the Inet implementation if reverse DNS does
 * not work.
 * 
 * Based on code found at http://www.codingforums.com/showpost.php?p=892349&postcount=5
 * 
 * @param ip The IP address to look up
 * @return   The host name, if one could be found, or the IP address
 */
private static String getHostName(final String ip)
 {
   String retVal = null;
   final String[] bytes = ip.split("\\.");
   if (bytes.length == 4)
   {
      try
      {
         final java.util.Hashtable<String, String> env = new java.util.Hashtable<String, String>();
         env.put("java.naming.factory.initial", "com.sun.jndi.dns.DnsContextFactory");
         final javax.naming.directory.DirContext ctx = new javax.naming.directory.InitialDirContext(env);
         final String reverseDnsDomain = bytes[3] + "." + bytes[2] + "." + bytes[1] + "." + bytes[0] + ".in-addr.arpa";
         final javax.naming.directory.Attributes attrs = ctx.getAttributes(reverseDnsDomain, new String[]
         {
            "PTR",
         });
         for (final javax.naming.NamingEnumeration<? extends javax.naming.directory.Attribute> ae = attrs.getAll(); ae.hasMoreElements();)
         {
            final javax.naming.directory.Attribute attr = ae.next();
            final String attrId = attr.getID();
            for (final java.util.Enumeration<?> vals = attr.getAll(); vals.hasMoreElements();)
            {
               String value = vals.nextElement().toString();
               // System.out.println(attrId + ": " + value);

               if ("PTR".equals(attrId))
               {
                  final int len = value.length();
                  if (value.charAt(len - 1) == '.')
                  {
                     // Strip out trailing period
                     value = value.substring(0, len - 1);
                  }
                  retVal = value;
               }
            }
         }
         ctx.close();
      }
      catch (final javax.naming.NamingException e)
      {
         // No reverse DNS that we could find, try with InetAddress
         System.out.print(""); // NO-OP
      }
   }

   if (null == retVal)
   {
      try
      {
         retVal = java.net.InetAddress.getByName(ip).getCanonicalHostName();
      }
      catch (final java.net.UnknownHostException e1)
      {
         retVal = ip;
      }
   }

   return retVal;
 }
  • 1
    It's important to note that it isn't always possible to do a reverse lookup because the data isn't always there in DNS. – KC Baltz Nov 16 '17 at 18:49
  • Why don't we try `getCanonicalHostName` first and use `DirContext` as fallback? Is it because `getCanonicalHostName` may return wrong result? – basin Aug 10 '18 at 10:04
  • I'm asking because `ctx.getAttributes` is usually slow – basin Aug 10 '18 at 10:08
  • @basin Two reasons: 1. On my machine, `getCanonicalHostName` was very unreliable, so trying it before `DirContext` was often a waste of time. 2. It fails silently. If it cannot resolve an IP address, it does not return an error but returns the IP as the hostname. Detecting a failure would involve running all returns through an IP address regex. – Konstantin Tarashchanskiy Aug 16 '18 at 19:50
  • can the first approach of JNDI be used to query ipv6? – Cpp crusaders Oct 29 '20 at 22:27
  • I figured how to ipv6 with JNDI also instead of using iterations I think this is better: `attrs.get("PTR").get()` example: comment 6 in [stack overflow link](https://stackoverflow.com/questions/34842698/inetaddress-getcanonicalhostname-returns-ip-instead-of-hostname) of course we need to hand exceptions accordingly ipv6 can be handled by following translation for reverseDnsDomain: `2001:4860:4802:36::a becomes a.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.6.3.0.0.2.0.8.4.0.6.8.4.1.0.0.2.ip6.arpa` and similar for `2001:4860:4802:36:0:0:0:a ` – Cpp crusaders Oct 30 '20 at 20:35
  • This code has some odd things in it. My main issue with this is that attrId == "PTR" is checkd inside the nested loop but is set in the outside loop. There is no need to interate over attr.getAll() if attrId is not PTR Also, once retVal is set, we dont break/return. So essentially this code returns the last value found in the nested loop in the last PTR attribute – OranShuster Oct 08 '21 at 08:51
8

CodingForums similar question -- see post #5 (DISCLAIMER: Code is not mine, not tested by me)


Code from linked source:

/**
 * 25 Nov 2009 REVERSE DNS LOOKUP USING JNDI
 * In this example the IP being looked up is 211.21.152.4
 * The octets are reversed (4.152.21.211)
 * and appended to the in-addr.arpa zone:
 * 4.152.21.211.in-addr.arpa
 */

import javax.naming.*;
import javax.naming.directory.*;
import java.util.*;

public class dns    { 
    public static void main(String[] args)  { 
        try {
            Hashtable env = new Hashtable();
            env.put("java.naming.factory.initial","com.sun.jndi.dns.DnsContextFactory");

            DirContext ctx = new InitialDirContext(env);
            Attributes attrs = ctx.getAttributes("4.152.21.211.in-addr.arpa",new String[] {"PTR"});

            for (NamingEnumeration ae = attrs.getAll();ae.hasMoreElements();) {
                Attribute attr = (Attribute)ae.next();
                String attrId = attr.getID();
                for (Enumeration vals = attr.getAll();vals.hasMoreElements();
                System.out.println(attrId + ": " + vals.nextElement()));
            }

            ctx.close();
        }   

        catch(Exception e) {
            System.out.println("NO REVERSE DNS");
        }
    }
}
Sam DeHaan
  • 10,246
  • 2
  • 40
  • 48