added WhoIsClient and parsing for whois.ripe.net
This commit is contained in:
@ -74,5 +74,12 @@
|
|||||||
<type>jar</type>
|
<type>jar</type>
|
||||||
<scope>compile</scope>
|
<scope>compile</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>commons-net</groupId>
|
||||||
|
<artifactId>commons-net</artifactId>
|
||||||
|
<scope>compile</scope>
|
||||||
|
<version>3.2</version>
|
||||||
|
</dependency>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
</project>
|
</project>
|
||||||
|
|||||||
@ -0,0 +1,77 @@
|
|||||||
|
/*
|
||||||
|
* To change this template, choose Tools | Templates
|
||||||
|
* and open the template in the editor.
|
||||||
|
*/
|
||||||
|
package de.muehlencord.shared.network;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author jomu
|
||||||
|
*/
|
||||||
|
public class CidrTool {
|
||||||
|
|
||||||
|
public static List<String> rangeToCidrList(String startIp, String endIp) {
|
||||||
|
long start = ipToLong(startIp);
|
||||||
|
long end = ipToLong(endIp);
|
||||||
|
|
||||||
|
ArrayList<String> pairs = new ArrayList<>();
|
||||||
|
while (end >= start) {
|
||||||
|
byte maxsize = 32;
|
||||||
|
while (maxsize > 0) {
|
||||||
|
long mask = CIDR2MASK[ maxsize - 1];
|
||||||
|
long maskedBase = start & mask;
|
||||||
|
|
||||||
|
if (maskedBase != start) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
maxsize--;
|
||||||
|
}
|
||||||
|
double x = Math.log(end - start + 1) / Math.log(2);
|
||||||
|
byte maxdiff = (byte) (32 - Math.floor(x));
|
||||||
|
if (maxsize < maxdiff) {
|
||||||
|
maxsize = maxdiff;
|
||||||
|
}
|
||||||
|
String ip = longToIP(start);
|
||||||
|
pairs.add(ip + "/" + maxsize);
|
||||||
|
start += Math.pow(2, (32 - maxsize));
|
||||||
|
}
|
||||||
|
return pairs;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public static final int[] CIDR2MASK = new int[]{0x00000000, 0x80000000,
|
||||||
|
0xC0000000, 0xE0000000, 0xF0000000, 0xF8000000, 0xFC000000,
|
||||||
|
0xFE000000, 0xFF000000, 0xFF800000, 0xFFC00000, 0xFFE00000,
|
||||||
|
0xFFF00000, 0xFFF80000, 0xFFFC0000, 0xFFFE0000, 0xFFFF0000,
|
||||||
|
0xFFFF8000, 0xFFFFC000, 0xFFFFE000, 0xFFFFF000, 0xFFFFF800,
|
||||||
|
0xFFFFFC00, 0xFFFFFE00, 0xFFFFFF00, 0xFFFFFF80, 0xFFFFFFC0,
|
||||||
|
0xFFFFFFE0, 0xFFFFFFF0, 0xFFFFFFF8, 0xFFFFFFFC, 0xFFFFFFFE,
|
||||||
|
0xFFFFFFFF};
|
||||||
|
|
||||||
|
private static long ipToLong(String strIP) {
|
||||||
|
long[] ip = new long[4];
|
||||||
|
String[] ipSec = strIP.split("\\.");
|
||||||
|
for (int k = 0; k < 4; k++) {
|
||||||
|
ip[k] = Long.valueOf(ipSec[k]);
|
||||||
|
}
|
||||||
|
|
||||||
|
return (ip[0] << 24) + (ip[1] << 16) + (ip[2] << 8) + ip[3];
|
||||||
|
}
|
||||||
|
|
||||||
|
private static String longToIP(long longIP) {
|
||||||
|
StringBuilder sb = new StringBuilder("");
|
||||||
|
sb.append(String.valueOf(longIP >>> 24));
|
||||||
|
sb.append(".");
|
||||||
|
sb.append(String.valueOf((longIP & 0x00FFFFFF) >>> 16));
|
||||||
|
sb.append(".");
|
||||||
|
sb.append(String.valueOf((longIP & 0x0000FFFF) >>> 8));
|
||||||
|
sb.append(".");
|
||||||
|
sb.append(String.valueOf(longIP & 0x000000FF));
|
||||||
|
|
||||||
|
return sb.toString();
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,109 @@
|
|||||||
|
/*
|
||||||
|
* To change this template, choose Tools | Templates
|
||||||
|
* and open the template in the editor.
|
||||||
|
*/
|
||||||
|
package de.muehlencord.shared.network;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author jomu
|
||||||
|
*/
|
||||||
|
public class NetworkInformation {
|
||||||
|
|
||||||
|
// private String network;
|
||||||
|
private String netname;
|
||||||
|
private String description;
|
||||||
|
private String country;
|
||||||
|
private String adminC;
|
||||||
|
private String techC;
|
||||||
|
private String maintainedBy;
|
||||||
|
private String status;
|
||||||
|
|
||||||
|
NetworkInformation(String netname, String descr, String country) {
|
||||||
|
this.netname = netname;
|
||||||
|
this.description = descr;
|
||||||
|
this.country = country;
|
||||||
|
this.adminC = null;
|
||||||
|
this.techC = null;
|
||||||
|
this.status = null;
|
||||||
|
this.maintainedBy = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* *** getter / setter *** */
|
||||||
|
/**
|
||||||
|
* @return the netname
|
||||||
|
*/
|
||||||
|
public String getNetname() {
|
||||||
|
return netname;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the description
|
||||||
|
*/
|
||||||
|
public String getDescription() {
|
||||||
|
return description;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the country
|
||||||
|
*/
|
||||||
|
public String getCountry() {
|
||||||
|
return country;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the adminC
|
||||||
|
*/
|
||||||
|
public String getAdminC() {
|
||||||
|
return adminC;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param adminC the adminC to set
|
||||||
|
*/
|
||||||
|
public void setAdminC(String adminC) {
|
||||||
|
this.adminC = adminC;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the techC
|
||||||
|
*/
|
||||||
|
public String getTechC() {
|
||||||
|
return techC;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param techC the techC to set
|
||||||
|
*/
|
||||||
|
public void setTechC(String techC) {
|
||||||
|
this.techC = techC;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the maintainedBy
|
||||||
|
*/
|
||||||
|
public String getMaintainedBy() {
|
||||||
|
return maintainedBy;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param maintainedBy the maintainedBy to set
|
||||||
|
*/
|
||||||
|
public void setMaintainedBy(String maintainedBy) {
|
||||||
|
this.maintainedBy = maintainedBy;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the status
|
||||||
|
*/
|
||||||
|
public String getStatus() {
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param status the status to set
|
||||||
|
*/
|
||||||
|
public void setStatus(String status) {
|
||||||
|
this.status = status;
|
||||||
|
}
|
||||||
|
}
|
||||||
132
network/src/main/java/de/muehlencord/shared/network/Whois.java
Normal file
132
network/src/main/java/de/muehlencord/shared/network/Whois.java
Normal file
@ -0,0 +1,132 @@
|
|||||||
|
package de.muehlencord.shared.network;
|
||||||
|
|
||||||
|
import de.muehlencord.shared.util.StringUtil;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.net.SocketException;
|
||||||
|
import java.net.UnknownHostException;
|
||||||
|
import java.text.ParseException;
|
||||||
|
import java.util.LinkedList;
|
||||||
|
import java.util.List;
|
||||||
|
import org.apache.commons.net.whois.WhoisClient;
|
||||||
|
import org.apache.log4j.Logger;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author jomu
|
||||||
|
*/
|
||||||
|
public class Whois {
|
||||||
|
|
||||||
|
/** logger object */
|
||||||
|
private final static Logger logger = Logger.getLogger(Whois.class);
|
||||||
|
/** whois client from commons-net package to execute commands with */
|
||||||
|
WhoisClient whois;
|
||||||
|
/** the complete output */
|
||||||
|
String whoIsString = null;
|
||||||
|
/** network list in CIDR form the host belongs to */
|
||||||
|
private List<String> network;
|
||||||
|
/** network list in CIDDR form network belongs to */
|
||||||
|
private List<String> rootNetwork;
|
||||||
|
/** network information of host */
|
||||||
|
private NetworkInformation networkInformation;
|
||||||
|
|
||||||
|
public Whois() {
|
||||||
|
whois = new WhoisClient();
|
||||||
|
whois.setDefaultTimeout(60000);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public void execute(String whoIsServer, String ip) throws UnknownHostException, SocketException, IOException, ParseException {
|
||||||
|
whois.connect(whoIsServer);
|
||||||
|
whoIsString = whois.query(ip);
|
||||||
|
// split by blank lines to identify blocks
|
||||||
|
String[] blocks = whoIsString.split("\n\n");
|
||||||
|
for (String block : blocks) {
|
||||||
|
analyseBlock(block);
|
||||||
|
}
|
||||||
|
whois.disconnect();
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO introduce parer per RIR
|
||||||
|
private void analyseBlock(String block) throws ParseException {
|
||||||
|
logger.debug("Start analysing block");
|
||||||
|
logger.debug("\n---\n" + block + "\n---\n");
|
||||||
|
|
||||||
|
if ((block == null) || (block.equals("")) || (!block.contains(" "))) {
|
||||||
|
logger.debug("Skippig empty block");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
String startString = block.substring(0, block.indexOf(" "));
|
||||||
|
if (startString.equals("%")) {
|
||||||
|
startString = block.substring(0, block.indexOf(" ", 2));
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (startString) {
|
||||||
|
|
||||||
|
case "inetnum:":
|
||||||
|
// information on network server belongs to (upper level / level -1)
|
||||||
|
String inetnum = StringUtil.getValueBetweenKeywords(block, "inetnum:", "netname:");
|
||||||
|
logger.info("inetnum: = " + inetnum);
|
||||||
|
String netname = StringUtil.getValueBetweenKeywords(block, "netname:", "descr:");
|
||||||
|
logger.info("netname: = " + netname);
|
||||||
|
String descr = StringUtil.getValueBetweenKeywords(block, "descr:", "country:");
|
||||||
|
logger.info("descr: = " + descr);
|
||||||
|
String country = StringUtil.getValueBetweenKeywords(block, "country:", "admin-c:");
|
||||||
|
logger.info("country: = " + country);
|
||||||
|
String adminC = StringUtil.getValueBetweenKeywords(block, "admin-c:", "tech-c:");
|
||||||
|
logger.info("admin-c: = " + adminC);
|
||||||
|
String techC = StringUtil.getValueBetweenKeywords(block, "tech-c:", "status:");
|
||||||
|
logger.info("tech-c: = " + techC);
|
||||||
|
String status = StringUtil.getValueBetweenKeywords(block, "status:", "mnt-by:");
|
||||||
|
logger.info("status: = " + status);
|
||||||
|
String mntBy = StringUtil.getValueBetweenKeywords(block, "mnt-by:", "source:");
|
||||||
|
logger.info("mnt-by: = " + mntBy);
|
||||||
|
|
||||||
|
// convert inetnum to CDIR
|
||||||
|
String[] ipAddresses = inetnum.split(" "); // TODO - what happens if not 3 parts are found
|
||||||
|
// FIXME add CDIR notation support
|
||||||
|
String startIpAddress = ipAddresses[0];
|
||||||
|
String endIPAddress = ipAddresses[2];
|
||||||
|
network = CidrTool.rangeToCidrList(startIpAddress, endIPAddress);
|
||||||
|
logger.info("Network:" + network.toString());
|
||||||
|
|
||||||
|
this.networkInformation = new NetworkInformation(netname, descr, country);
|
||||||
|
|
||||||
|
break;
|
||||||
|
case "route:":
|
||||||
|
// get information on level-2 network
|
||||||
|
String route = StringUtil.getValueBetweenKeywords(block, "route:", "descr:");
|
||||||
|
this.rootNetwork = new LinkedList<>();
|
||||||
|
this.rootNetwork.add(route);
|
||||||
|
logger.info ("Root network "+this.rootNetwork.toString());
|
||||||
|
break;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
case "role:":
|
||||||
|
// admin company of network server belongs to
|
||||||
|
logger.info("Skipping role block");
|
||||||
|
break;
|
||||||
|
case "person:":
|
||||||
|
// admin person of network server belongs to
|
||||||
|
logger.info("Skipping person block");
|
||||||
|
break;
|
||||||
|
case "% Information":
|
||||||
|
case "% Note:":
|
||||||
|
case "% This":
|
||||||
|
case "%":
|
||||||
|
logger.info("Skipping comment block");
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
logger.info("Unknown block found");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<String> getNetwork() {
|
||||||
|
return this.network;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<String> getRootNetwork() {
|
||||||
|
return this.rootNetwork;
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,16 @@
|
|||||||
|
package de.muehlencord.shared.network;
|
||||||
|
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author jomu
|
||||||
|
*/
|
||||||
|
public class RangeToCidrTest extends BaseTest {
|
||||||
|
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testRangeToCidr() {
|
||||||
|
System.out.println (CidrTool.rangeToCidrList("212.204.60.0", "212.204.60.255"));
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,48 @@
|
|||||||
|
/*
|
||||||
|
* To change this template, choose Tools | Templates
|
||||||
|
* and open the template in the editor.
|
||||||
|
*/
|
||||||
|
package de.muehlencord.shared.network;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.net.SocketException;
|
||||||
|
import java.net.UnknownHostException;
|
||||||
|
import java.text.ParseException;
|
||||||
|
import org.junit.Ignore;
|
||||||
|
import org.junit.Test;
|
||||||
|
import static org.junit.Assert.*;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author jomu
|
||||||
|
*/
|
||||||
|
public class WhoisTest extends BaseTest {
|
||||||
|
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@Ignore
|
||||||
|
public void testDenicWhoIs() throws UnknownHostException, SocketException, IOException, ParseException {
|
||||||
|
Whois whoIsClient = new Whois();
|
||||||
|
// Denic answers "status: connect" only
|
||||||
|
whoIsClient.execute ("whois.denic.de", "-T dn,ace muehlencord.de");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@Ignore
|
||||||
|
public void testInternic() throws UnknownHostException, SocketException, IOException, ParseException {
|
||||||
|
Whois whoIsClient = new Whois();
|
||||||
|
// Denic answers "status: connect" only
|
||||||
|
whoIsClient.execute ("whois.1api.net", "egameladder.com");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testStepWise() throws UnknownHostException, SocketException, IOException, ParseException {
|
||||||
|
Whois whoIsClient = new Whois();
|
||||||
|
// whoIsClient.execute ("whois.ripe.net", "88.198.181.181");
|
||||||
|
whoIsClient.execute ("whois.ripe.net", "212.204.60.1");
|
||||||
|
assertTrue ("network", whoIsClient.getNetwork().contains("212.204.60.0/24"));
|
||||||
|
// whoIsClient.execute ("whois.ripe.net", "212.204.60.0");
|
||||||
|
// whoIsClient.execute ("whois.ripe.net", "212.0.0.0/8");
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -5,4 +5,4 @@ log4j.debug=false
|
|||||||
log4j.appender.ConsoleLogger=org.apache.log4j.ConsoleAppender
|
log4j.appender.ConsoleLogger=org.apache.log4j.ConsoleAppender
|
||||||
log4j.appender.ConsoleLogger.layout=org.apache.log4j.PatternLayout
|
log4j.appender.ConsoleLogger.layout=org.apache.log4j.PatternLayout
|
||||||
log4j.appender.ConsoleLogger.layout.ConversionPattern= %d - %m (%c)%n
|
log4j.appender.ConsoleLogger.layout.ConversionPattern= %d - %m (%c)%n
|
||||||
log4j.appender.ConsoleLogger.threshold=INFO
|
log4j.appender.ConsoleLogger.threshold=DEBUG
|
||||||
Reference in New Issue
Block a user