Hello and welcome to our community! Is this your first visit?
Register
Enjoy an ad free experience by logging in. Not a member yet? Register.
Results 1 to 6 of 6
  1. #1
    120
    120 is offline
    Regular Coder
    Join Date
    Nov 2009
    Location
    UK
    Posts
    105
    Thanks
    6
    Thanked 15 Times in 15 Posts

    Java Reverse DNS Lookup

    Hi - I've had a look around for places where I can get some help/advice on a Java issue I have? I've tried usenet but the groups look almost dead(?). Coding Forums has come highly recommended.

    I'm new to Java, but have some general programming and shell experience. I was pleasantly surprised to find how quick and easy it is to get working code out of Java - but I'm struggling with DNS lookups.

    Basically, I'm trying to mimic a reverse dns lookup (ip to full PTR) like I would get with:

    Code:
    dig -x 211.21.152.4
    or
    host 211.21.152.4
    This code works-ish:
    Code:
                    import java.net.*;
                    //.......
                    try {	
    		InetAddress thost = InetAddress.getByName("211.21.152.4");
       		//HostName = thost.getHostName();
       		HostName = thost.getCanonicalHostName(); 
       		System.out.println("HOST: "+HostName);
     		} catch (UnknownHostException e) {
       		System.out.println("NO HOST");	
    		}
    NOTE: tried thost.getCanonicalHostName & getHostName
    The issue I'm getting is the result is not consistent with DNS.
    This code returns: HOST: 211.21.152.4

    but, dig -x 211.21.152.4 returns
    211-21-152-4.HINET-IP.hinet.net
    AND
    host 211.21.152.4 returns:
    211-21-152-4.HINET-IP.hinet.net.

    At first I thought the methods getHostName/getCanonicalHostName were returning what it thought was the hostname from the string, and it was extremely intelligent in finding this name. I also noted the docs warned that if there was a security manager in place, 'a textual representation of the IP address would be returned'. That was fine until I tried the code again with 80.75.69.195 and the Java code returned the full PTR as dig -x or host would:

    HOST: web1.redut.net

    Basically it appears that if the DNS PTR contains something that looks like an IP address, the Java methods are returning it rather than the whole pointer.

    What I want is the whole pointer line from a reverse DNS lookup. I know there is an xbill dns library, but my concern is - assuming I can figure out how to install it - this will make what I am writing less portable(?) and require target JVM to have the library. I would really like to keep it to the core libraries at this stage.

    Does anyone know what I can do to get the full pointer, regardless of if parts of it *look* like an IP? Any help or pointers to other places to ask would be really appreciated.

    I know it must irritate regular posters here when someone new bursts in, asks a question, gets an answer and never contributes again. I promise not to do that now that I've found this forum.

    Mike

  • #2
    Senior Coder TheShaner's Avatar
    Join Date
    Sep 2005
    Location
    Orlando, FL
    Posts
    1,126
    Thanks
    2
    Thanked 40 Times in 40 Posts
    Try this instead:
    Code:
    byte[] ipAddr = new byte[] {211, 21, 152, 4};
    InetAddress addr = InetAddress.getByAddress(ipAddr);
    String hostname = addr.getCanonicalHostName();
    I know both the getByName and getByAddress methods return an InetAddress object, but I'm not sure if there is a difference regarding the information put into the returned object with those methods. It's at least worth a shot.

    Also, it looks as if both getHostName and getCanonicalHostName check to see whether they can establish a socket connection to the address. If it cannot, then it determines that it does not have permission to do a reverse lookup. The two commands, dig and host, do not attempt socket connections, as far as I know. So that may be the discrepancy. But again, I don't have any real knowledge in this area of Java.

    Honestly, the regulars here don't mind whether you post once or 100 times, or always receive help and never reciprocate (as long as problems are stated clearly with an honest attempt in solving them yourself, which you've clearly done). If we can help you, then we've done our job. Sticking around is your choice and we always appreciate new faces. Good luck

    -Shane

  • #3
    120
    120 is offline
    Regular Coder
    Join Date
    Nov 2009
    Location
    UK
    Posts
    105
    Thanks
    6
    Thanked 15 Times in 15 Posts
    Thanks Shane.

    Example tried but refused to compile:

    Code:
    rdns.java:101: possible loss of precision
    found   : int
    required: byte
    		byte[] ipAddr = new byte[] {211, 21, 152, 4};
    		                            ^
    rdns.java:101: possible loss of precision
    found   : int
    required: byte
    		byte[] ipAddr = new byte[] {211, 21, 152, 4};
    Java being knew to me, I figured 'well, it's found INT but wants byte, what happens if I change the array to an INT array....


    Code:
    rdns.java:103: cannot find symbol
    symbol  : method getByAddress(int[])
    location: class java.net.InetAddress
    		InetAddress addr = InetAddress.getByAddress(ipAddr);
    		                              ^
    1 error
    I can't quite figure why your array of bytes throws this error? To me all the values are under 255 -hence bytes- ?

  • #4
    Senior Coder TheShaner's Avatar
    Join Date
    Sep 2005
    Location
    Orlando, FL
    Posts
    1,126
    Thanks
    2
    Thanked 40 Times in 40 Posts
    Quote Originally Posted by 120 View Post
    Example tried but refused to compile:

    Code:
    rdns.java:101: possible loss of precision
    found   : int
    required: byte
    		byte[] ipAddr = new byte[] {211, 21, 152, 4};
    		                            ^
    rdns.java:101: possible loss of precision
    found   : int
    required: byte
    		byte[] ipAddr = new byte[] {211, 21, 152, 4};
    Sorry about that. Try:
    Code:
    byte[] ipAddr = new byte[] {(byte)211, (byte)21, (byte)152, (byte)4};
    You need to cast each number passed into the array as a byte. Without a specific typecasting, Java assumes that any whole number is an integer.

    Also, the getByAddress method only accepts byte arrays, so it throws an error if you pass anything in that is not a byte array.

    -Shane

  • Users who have thanked TheShaner for this post:

    120 (11-25-2009)

  • #5
    120
    120 is offline
    Regular Coder
    Join Date
    Nov 2009
    Location
    UK
    Posts
    105
    Thanks
    6
    Thanked 15 Times in 15 Posts
    Thanks Shane, but I've solved this using JNDI-v-DNS. Here is the solution in case anyone else is trying to do reverse DNS lookups with Java:


    THIS EXAMPLE {mostly stolen elsewhere from the Sun forum} WORKS FLAWLESSLY and makes use the default system DNS. The key (and like a knob I forgot this) is to reverse the octets of the IP and append the in-addr.arpa zone to them when looking for the PTR (this will *not* work InetAddress methods as far as I can tell, hence making use of JDNI)

    Code:
    /**
    
     * 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");
    
    		}
    
    	}
    
    }
    OUTPUT IS NOW AS EXPECTED:
    Code:
    PTR: 211-21-152-4.HINET-IP.hinet.net.
    Compiling may give these warnings re: generics
    Code:
    dns.java uses unchecked or unsafe operations.
    Recompile with -Xlint:unchecked for details
    These can be ignored (program will still compile) OR modify one line:
    Code:
    Hashtable<String,String> env = new Hashtable<String,String>()
    Hope that helps someone else who is looking to solve this. Thanks for the input. Another day of learning, time for a beer :-)

  • #6
    120
    120 is offline
    Regular Coder
    Join Date
    Nov 2009
    Location
    UK
    Posts
    105
    Thanks
    6
    Thanked 15 Times in 15 Posts
    Can a MOD change the subject of the post for the benefit of others/search engines?

    Something like 'REVERSE DNS LOOKUP WITH JAVA'? may be more helpful?


  •  

    Posting Permissions

    • You may not post new threads
    • You may not post replies
    • You may not post attachments
    • You may not edit your posts
    •