- 前言
- 写这个程序的初衷是为了做一个小练习并将此作为提升java技术的开端,记录和整理是为了养成良好的思考习惯。
- 写这个程序用了蛮久的时间,期间也查询了很多资料,但碍于自己能力有限,程序没有调试成功。
- 最大的困难在于用到了网络方面的知识,例如发送ARP欺骗包以及转发接收到的数据包。参考了网上的示例和教程,但没用成功。
- 希望大家能有兴趣和我交流并找出问题所在。
- 搭建JPCAP环境
- 下载WinPcap并安装:http://www.winpcap.org/install/default.htm
- 下载Jpcap:
将JPcap.dll拷贝到D:\Program Files\Java\jdk1.7.0_80\jre\bin
将jpcap.jar拷贝到D:\Program Files\Java\jdk1.7.0_80\jre\lib\ext - 配置eclipse
下面介绍一些类和方法:
- 定时加载局域网中设备的信息
- 包括hostname、IP address、MAC address
ExecIntercept.java
/**
* Description: Get target device information at interval time.<br>
*
* @see
*/
public static void scheduleLoadDeviceInfo()
{
ScheduledExecutorService scheduleThread = Executors.newSingleThreadScheduledExecutor();
GetTargetDeviceInfoRunnable runnable = new GetTargetDeviceInfoRunnable(device);
scheduleThread.scheduleAtFixedRate(runnable, 0, 10, TimeUnit.MINUTES);
try
{
TimeUnit.SECONDS.sleep(DEVICEINFO_THREADSLEEPSECONDS);
}
catch (InterruptedException e)
{
/* Ignore this exception. */}
}
GetTargetDeviceInfoRunnable.java
/*
* 文件名:GetTargetDeviceInfoRunnable.java 修改人:Jagger 修改时间:2016年9月15日
*/
package com.traffic.intercept;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import org.apache.log4j.LogManager;
import org.apache.log4j.Logger;
import com.traffic.entity.DeviceInfo;
import com.traffic.exception.LTMException;
import com.traffic.util.DebugUtil;
import com.traffic.util.DeviceInfoUtil;
/**
* Get target device information at interval time.
*
* @author Jagger
* @version 2016年9月15日
* @see GetTargetDeviceInfoRunnable
* @since
*/
public class GetTargetDeviceInfoRunnable implements Runnable
{
private static Logger logger = LogManager.getLogger(GetTargetDeviceInfoRunnable.class);
private DeviceInfo device;
private static final String IP_ADDRESS = "ip_address";
private static final String MAC_ADDRESS = "mac_address";
private static final String HOSTNAME = "hostname";
private static final String GATEWAY_DEVICE = "gateway";
private static final String OWN_DEVICE = "own";
public GetTargetDeviceInfoRunnable(DeviceInfo device)
{
this.device = device;
}
@Override
public void run()
{
Map<String, Map<String, String>> deviceInfos = null;
if (DebugUtil.isDebug())
{
/* debug test start */
deviceInfos = new HashMap<String, Map<String, String>>();
Map<String, String> device1 = new HashMap<String, String>();
device1.put(MAC_ADDRESS, "78-EB-14-9C-89-3E");
device1.put(IP_ADDRESS, "192.168.1.1");
device1.put(HOSTNAME, "192.168.1.1");
deviceInfos.put(GATEWAY_DEVICE, device1);
Map<String, String> device2 = new HashMap<String, String>();
device2.put(MAC_ADDRESS, "BC-30-7D-7C-F2-AF");
device2.put(IP_ADDRESS, "192.168.1.105");
device2.put(HOSTNAME, "DESKTOP-4LOKC4J");
deviceInfos.put(OWN_DEVICE, device2);
Map<String, String> device3 = new HashMap<String, String>();
device3.put(MAC_ADDRESS, "38-BC-1A-13-25-D7");
device3.put(IP_ADDRESS, "192.168.1.106");
device3.put(HOSTNAME, "192.168.1.106");
deviceInfos.put("192.168.1.106", device3);
/* debug test end */
}
else
{
try
{
deviceInfos = DeviceInfoUtil.getAllDeviceInfo();
}
catch (LTMException e)
{
logger.error(e.getErrorCode() + " | " + e.getErrorDescription());
}
}
String networkSegment = null;
try
{
networkSegment = DeviceInfoUtil.getNetworkSegment();
}
catch (LTMException e)
{
logger.error(e.getErrorCode() + " | " + e.getErrorDescription());
}
String defaultGateway = DeviceInfoUtil.getDefaultGatewayAddress();
// Save all IP and MAC address mapping.
Map<String, String> IPToMAC = new HashMap<String, String>();
// Save all IP address at LAN.
Set<String> ipAddresses = new HashSet<String>();
for (String key : deviceInfos.keySet())
{
Map<String, String> deviceInfo = deviceInfos.get(key);
ipAddresses.add(deviceInfo.get(IP_ADDRESS));
IPToMAC.put(deviceInfo.get(IP_ADDRESS), deviceInfo.get(MAC_ADDRESS));
}
device.setSegment(networkSegment);
device.setDefaultGateway(defaultGateway);
device.setTargetInfo(deviceInfos);
// Except gateway and own IP address.
ipAddresses.remove(deviceInfos.get(GATEWAY_DEVICE).get(IP_ADDRESS));
ipAddresses.remove(deviceInfos.get(OWN_DEVICE).get(IP_ADDRESS));
device.setIpAddresses(ipAddresses);
device.setIPToMAC(IPToMAC);
}
}
DeviceInfoUtil.java
/**
* Description: Get local IP address.<br>
*
* @return local IP address
* @throws LTMException
* Can't get local IP address.
* @see
*/
private static String getLocalIPAddress()
throws LTMException
{
String localIPAddress = null;
try
{
localIPAddress = InetAddress.getLocalHost().getHostAddress();
}
catch (UnknownHostException e)
{
logger.error("Get local IP address error.");
throw new LTMException(ErrorCode.GETLOCALIPADDRESSERROR.getCode(),
ErrorCode.GETLOCALIPADDRESSERROR.getDescription(), e);
}
return localIPAddress;
}
/**
* Description: Get network segment.<br>
*
* @return network segment
* @throws LTMException
* @see
*/
public static String getNetworkSegment()
throws LTMException
{
String localIPAddress = null;
localIPAddress = getLocalIPAddress();
int index = localIPAddress.lastIndexOf(IPSEPARATOR);
String networkSegment = localIPAddress.substring(0, index);
return networkSegment;
}
/**
* Description: Get all IP address at LAN.<br>
*
* @return all IP address at LAN
* @throws LTMException
* @see
*/
private static List<String> getAllIPAddress()
throws LTMException
{
String networkSegment = null;
try
{
networkSegment = getNetworkSegment();
}
catch (LTMException e)
{
throw e;
}
List<Future<String>> ipAddressFutures = new ArrayList<Future<String>>();
// except 0 and 255
for (int i = 1; i < 255; i++ )
{
String ip = networkSegment + IPSEPARATOR + i;
ipAddressFutures.add(DeviceInfoUtil.threadPool.submit(new GetActiveIPCallable(ip)));
}
String ipAddress = null;
List<String> ipAddresses = new ArrayList<String>();
for (Future<String> ipAddressFuture : ipAddressFutures)
{
boolean isDone = ipAddressFuture.isDone();// Judge sub thread whether completed.
while (!isDone)
{
isDone = ipAddressFuture.isDone();// wait
}
try
{
ipAddress = ipAddressFuture.get();
}
catch (InterruptedException e)
{
/* Ignore this exception. */}
catch (ExecutionException e)
{
/* Ignore this exception. */}
finally
{
/* Needn't close thread pool. */}