Java DNSLookup MX record list. Like MXToolBox
Asked Answered
J

2

5

I'm building a program to list all MX record of a domain. It seemed to work fine at first, but after comparing to a online tool http://mxtoolbox.com/. There are domain that the program can not get MX record while MXToolbox can.

I'm not sure what the reason is or any configuration that required.

Many thanks;

Here is my code.

import javax.naming.directory.Attribute;
import javax.naming.directory.Attributes;
import javax.naming.directory.InitialDirContext;
import javax.naming.Context;
import javax.naming.NamingEnumeration;
import javax.naming.NamingException;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.Hashtable;

public class DNSLookup
{
    private InitialDirContext iDirC;

    public DNSLookup ()
    {
         Hashtable<String, String> env = new Hashtable<String, String>();
         //env.put(Context.INITIAL_CONTEXT_FACTORY,"com.sun.jndi.ldap.LdapCtxFactory");
         //env.put(Context.PROVIDER_URL, "ldap://localhost:389/o=JNDITutorial");
         env.put(Context.INITIAL_CONTEXT_FACTORY,"com.sun.jndi.dns.DnsContextFactory");
         //env.put(Context.PROVIDER_URL, "dns://google.com");
         // get the default initial Directory Context
         try {
            iDirC = new InitialDirContext(env);
        } catch (NamingException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }

    private void lookup (String host, String record)
    {
        InetAddress inetAddress;
        try {
            inetAddress = InetAddress.getByName(host);
            // show the Internet Address as name/address
            System.out.println(inetAddress.getHostName() + " " + inetAddress.getHostAddress());

            // get the DNS records for inetAddress
            Attributes attributes = iDirC.getAttributes("dns:\\"+inetAddress.getHostName());
            // get an enumeration of the attributes and print them out
            //NamingEnumeration<?> attributeEnumeration = attributes.getAll();
/*          while (attributeEnumeration.hasMore())
            {
                System.out.println("" + attributeEnumeration.next());
            }
            attributeEnumeration.close();*/
            Attribute mxRecord = attributes.get(record);
            for (int i=0; i<mxRecord.size();i++)
                System.out.println(mxRecord.get(i));

        } catch (UnknownHostException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (NamingException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }

    public static void main(String[] args){
        DNSLookup looker = new DNSLookup();
        looker.lookup("truetech.com", "MX");
    }
}

The above domain will output NullPointer mean no MX record found. While the MXToolBox will output one.

Jewry answered 6/3, 2013 at 6:58 Comment(1)
You only need to change one line to dns:\\" + inetAddress.getHostName(),new String[] {record}Streptokinase
B
18

I know this is a late answer (but I hope this helps you or someone else).

Here's a working solution on how you can find MX Records. The solution hinges off IntialDirContext and goes on to use Attributes to define what type of attribute is required.

// Print out a sorted list of mail exchange servers for a network domain name
import javax.naming.directory.Attribute;
import javax.naming.directory.Attributes;
import javax.naming.directory.InitialDirContext;
import javax.naming.NamingException;
import java.util.Arrays;
import java.util.Comparator;

public class MailHostsLookup 
{
    public static void main(String args[]) 
    {
        // explain what program does and how to use it 
        if (args.length != 1)
        {
            System.err.println("Print out a sorted list of mail exchange servers ");
            System.err.println("    for a network domain name");
            System.err.println("USAGE: java MailHostsLookup domainName");
            System.exit(-1);
        } 
        try
        {   // print the sorted mail exhchange servers
            for (String mailHost: lookupMailHosts(args[0]))
            {
                System.out.println(mailHost);            
            }
        }
        catch (NamingException e)
        {
            System.err.println("ERROR: No DNS record for '" + args[0] + "'");
            System.exit(-2);
        }
     }

    // returns a String array of mail exchange servers (mail hosts) 
    //     sorted from most preferred to least preferred
    static String[] lookupMailHosts(String domainName) throws NamingException
    {
        // see: RFC 974 - Mail routing and the domain system
        // see: RFC 1034 - Domain names - concepts and facilities
        // see: http://java.sun.com/j2se/1.5.0/docs/guide/jndi/jndi-dns.html
        //    - DNS Service Provider for the Java Naming Directory Interface (JNDI)

        // get the default initial Directory Context
        InitialDirContext iDirC = new InitialDirContext();
        // get the MX records from the default DNS directory service provider
        //    NamingException thrown if no DNS record found for domainName
        Attributes attributes = iDirC.getAttributes("dns:/" + domainName, new String[] {"MX"});
        // attributeMX is an attribute ('list') of the Mail Exchange(MX) Resource Records(RR)
        Attribute attributeMX = attributes.get("MX");

        // if there are no MX RRs then default to domainName (see: RFC 974)
        if (attributeMX == null)
        {
            return (new String[] {domainName});
        }

        // split MX RRs into Preference Values(pvhn[0]) and Host Names(pvhn[1])
        String[][] pvhn = new String[attributeMX.size()][2];
        for (int i = 0; i < attributeMX.size(); i++)
        {
            pvhn[i] = ("" + attributeMX.get(i)).split("\\s+");
        }

        // sort the MX RRs by RR value (lower is preferred)
        Arrays.sort(pvhn, new Comparator<String[]>()
            {
                public int compare(String[] o1, String[] o2)
                {
                    return (Integer.parseInt(o1[0]) - Integer.parseInt(o2[0]));
                }
            });

        // put sorted host names in an array, get rid of any trailing '.' 
        String[] sortedHostNames = new String[pvhn.length];
        for (int i = 0; i < pvhn.length; i++)
        {
            sortedHostNames[i] = pvhn[i][1].endsWith(".") ? 
                pvhn[i][1].substring(0, pvhn[i][1].length() - 1) : pvhn[i][1];
        }
        return sortedHostNames;
    }
}
Beaver answered 8/5, 2013 at 18:57 Comment(0)
B
1

https://stackoverflow.com/a/14042816

kind of unfortunate to answer with a link to this Same site... maybe someone could organize the space more brilliantly...

use dnsjava.

Then again it may not be exactly what you're looking for...It doesn't give the exact same results as MxToolbox either.

Bessie answered 7/3, 2014 at 18:15 Comment(2)
It would be more useful if you could extract the relevant information from the answer you linked to (while keeping the link).Cataplasia
There is a specific provision for this: flag the question as a duplicate of the question you link to. Then this question can be closed as a duplicate (if enough higher-rep users agree). You should never answer a question by simply linking to another SO question.Hoffman

© 2022 - 2024 — McMap. All rights reserved.