/**
* @author Derek Hardison
* File: WhoisProc.java
* Purpose: Performs WHOIS lookup on a domain name and collects
* registrar, name server 1, and name server 2.
*
* This work is licensed under the Creative Commons Attribution-Share
* Alike 3.0 License. To view a copy of this license, visit
* http://creativecommons.org/licenses/by-sa/3.0/ or send a letter to
* Creative Commons, 171 Second Street, Suite 300, San Francisco,
* California, 94105, USA.
*/
import java.io.InputStream;
import java.io.OutputStream;
import java.net.Socket;
public class WhoisProc {
// ASSERT: WHOISSERVER is a list of WHOIS servers and ports to connect to;
// if server returns no results the next server will be tried.
final String WHOISSERVER[][] = { { "internic.net", "43" },
{ "whois.pir.org", "43" } };
// ASSERT: WHOISPORT is the whois server port to query on.
final int WHOISTIMEOUT = 20000;
// ASSERT: WHOISTIMEOUT is the timeout till considered a failed
// connection to the whois server.
final String REGISTRARSTRING = "registrar:"; // ALL LOWERCASE
final String NAMESERVER1STRING = "name server:";
final String NAMESERVER2STRING = "name server:";
// ------------- END OF CONFIGURATION ----------------//
private String hostname;
// ASSERT: hostname is not set.
private String registrar;
// ASSERT: registrar is not set.
private String ns1;
// ASSERT: ns1 is not set.
private String ns2;
// ASSERT: ns2 is not set.
protected Socket s;
// ASSERT: s is not set.
/**
* Constructs the object and performs initial domain WHOIS lookup.
*
* @param h
* Domain name to perform WHOIS lookup on.
* @throws Exception
* If unable to collect WHOIS information on the domain name (ie
* WHOIS information is private or domain does not exist).
*/
public WhoisProc(String h) throws Exception {
collectDomainInformation(h);
}
/**
* Peforms WHOIS lookup on domain name using specified WHOIS servers in
* source file.
*
* @param h
* Domain name to perform WHOIS search for.
* @throws Exception
* Throws exception if unable to resolve domain name, or response
* from WHOIS server is not valid (No valid information returned on
* the domain).
*/
private void collectDomainInformation(String h) throws Exception {
hostname = h;
// ASSERT: hostname is set.
boolean runServer = true;
// ASSERT: runServer is true.
for (int i = 0; i < WHOISSERVER.length && runServer; i++) {
try {
System.out.println("Trying " + WHOISSERVER[i][0]);
executeLookup(h, WHOISSERVER[i][0], Integer
.parseInt(WHOISSERVER[i][1]));
runServer = false;
// ASSERT: runServer is false.
} catch (Exception e) {}
}
if (runServer) throw new java.net.UnknownHostException();
// ASSERT: If runServer is still true, it means we never obtained
// information about the domain.
}
/**
* Performs WHOIS lookup and updates registrar, ns1, and ns2 for given
* domain.
*
* @param h
* Domain name to perform WHOIS lookup for.
* @param serv
* WHOIS server to make request to.
* @param port
* WHOIS port to make request on.
* @throws Exception
* Throws UnknownHostException if WHOIS server contains no name
* server for domain (Assumed that the domain does not exist).
*/
private void executeLookup(String h, String serv, int port)
throws Exception {
s = new Socket(serv, port);
// ASSERT: s has been constucted to connect to the
// whois server.
s.setSoTimeout(WHOISTIMEOUT);
// ASSERT: s socket timeout has been set.
InputStream in = s.getInputStream();
// ASSERT: in is set.
OutputStream out = s.getOutputStream();
// ASSERT: out is set.
out.write((h + "\n").getBytes());
// ASSERT: We have sent a whois request for hostname
int tmp;
// ASSERT: tmp is not set.
String tmpString = "";
// ASSERT: tmpString is not set.
while ((tmp = in.read()) != -1)
tmpString += (char) tmp;
// ASSERT: tmpString is filled with the whois return.
in.close();
out.close();
s.close();
// ASSERT: socket, in & out buffers closed.
// System.out.println (tmpString);
tmpString = tmpString.toLowerCase();
// ASSERT: tmpString is now all lowercase.
if (tmpString.indexOf(NAMESERVER1STRING) >= 0) {
setRegistrar(tmpString);
// ASSERT: registrar is now set.
setNameServers(tmpString);
// ASSERT: ns1 & ns2 are now set.
} else {
throw new java.net.UnknownHostException();
}
}
/**
* Pulls registrar out of response from WHOIS server for domain lookup and
* sets registrar to domain registrar or "" if none exist.
*
* @param query
* WHOIS server response containing all the information about the
* domain.
*/
private void setRegistrar(String query) {
registrar = "";
// ASSERT: registrar = "".
int startIndex = query.indexOf(REGISTRARSTRING);
// ASSERT: startIndex is now set to the index of where we can find
// the REGISTRARSTRING.
int indexOfLastSpace = -1;
// ASSERT: indexOfLastSpace is -1.
boolean foundChar = false;
// ASSERT: foundChar is false.
for (int i = startIndex + REGISTRARSTRING.length(); i < query.length()
&& i > 0 && query.charAt(i) != '\n'; i++) {
if (!foundChar && query.charAt(i) != ' ') {
registrar += query.charAt(i);
foundChar = true;
// ASSERT: foundChar is true.
} else if (foundChar && query.charAt(i) == ' '
&& indexOfLastSpace == -1) {
indexOfLastSpace = i;
registrar += query.charAt(i);
} else if (foundChar && query.charAt(i) != ' ') {
indexOfLastSpace = -1;
registrar += query.charAt(i);
}
}
if (indexOfLastSpace > -1) registrar = registrar.substring(0,
indexOfLastSpace);
// ASSERT: registrar is now set.
}
/**
* Pulls name servers out of response from WHOIS server for domain lookup
* and sets ns1 and ns2 to the domain name servers or "" if none exist.
*
* @param query
* WHOIS server response containing all the information about the
* domain.
*/
private void setNameServers(String query) {
ns1 = "";
// ASSERT: ns1 = "".
ns2 = "";
// ASSERT: ns2 = "".
int startIndex = query.indexOf(NAMESERVER1STRING);
// ASSERT: startIndex is now set to the index of where we can find
// the NAMESERVER1STRING.
for (int i = startIndex + NAMESERVER1STRING.length(); i < query
.length()
&& i >= 0 && query.charAt(i) != '\n'; i++)
ns1 += query.charAt(i);
ns1 = ns1.replaceAll(" ", "");
// ASSERT: ns1 is now set.
// Find the second nameserver index
if (NAMESERVER1STRING.equals(NAMESERVER2STRING)) startIndex = query
.indexOf(NAMESERVER2STRING, startIndex
+ NAMESERVER1STRING.length());
else startIndex = query.indexOf(NAMESERVER2STRING);
// ASSERT: startIndex is set to the beginning of the second nameserver
// location.
for (int i = startIndex + NAMESERVER2STRING.length(); i < query
.length()
&& i >= 0 && query.charAt(i) != '\n'; i++)
ns2 += query.charAt(i);
ns2 = ns2.replaceAll(" ", "");
// ASSERT: ns2 is now set.
}
/**
* @return Hostname for current domain lookup.
*/
public String getDomainname() {
return hostname;
}
/**
* @return Name server 1 for domain lookup, "" if domain does not exist.
*/
public String getNS1() {
return ns1;
}
/**
* @return Name server 2 for domain lookup, "" if domain does not exist.
*/
public String getNS2() {
return ns2;
}
/**
* @return Registrar for domain lookup, "" if domain does not exist.
*/
public String getRegistrar() {
return registrar;
}
}