About the getNextPacketEx problem under linux
gitlei0507 opened this issue · comments
I installed suse linux 15 sp1 in a virtual machine, pcap4j version is 1.8.2, when using getNextPacketEx, it will cause the thread to be stuck and not catch any exception, after testing, I found that assuming detecting 5 IP addresses, it will be stuck when looping to the sixth time, assuming detecting 1 IP address, it will be stuck when looping to the second time. After testing, we found that if we probe 5 IP addresses, the thread will get stuck when the loop reaches the sixth time, and if we probe 1 IP address, it will get stuck when the loop reaches the second time. The code is as follows.
import com.itss.spring.domain.ipc.IpcProbeserverNif;
import com.itss.spring.web.SpringContextUtil;
import com.itss.spring.web.component.pcap.PcapHelper;
import com.itss.spring.web.component.pcap.entity.HostScanInfo;
import com.itss.spring.web.component.pcap.entity.UltraScanInfo;
import com.ursa.acf.util.StringUtils;
import org.pcap4j.core.*;
import org.pcap4j.packet.IpV4Packet;
import org.pcap4j.packet.Packet;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.EOFException;
import java.net.Inet4Address;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.*;
public class PcapPacketListener {
private static final Logger logger = LoggerFactory.getLogger(PcapPacketListener.class);
private Object lock;
public PcapPacketListener(Object lock) {
this.lock = lock;
}
public Map<HostScanInfo, Packet> lisenerForIpScan(UltraScanInfo ultraScanInfo, PcapNetworkInterface nif) throws Exception {
PcapHelper pcapHelper = (PcapHelper) (SpringContextUtil.getBean(PcapHelper.class));
LinkedHashMap<String, HostScanInfo> incompleteHosts = ultraScanInfo.getIncompleteHosts();
Map<HostScanInfo, Packet> packetTempMap = new HashMap<>();
String receiveMac = "";
List<IpcProbeserverNif> receiveNifs = ultraScanInfo.getReceiveNifs();
for (IpcProbeserverNif receiveNif : receiveNifs) {
if (receiveNif.getName().equals(nif.getName())) {
receiveMac = receiveNif.getLinklayeraddress();
break;
}
}
PcapHandle.Builder handleBuilder = new PcapHandle.Builder(nif.getName())
.snaplen(65536)
.promiscuousMode(PcapNetworkInterface.PromiscuousMode.PROMISCUOUS)
.timeoutMillis(30)
.bufferSize(1024 * 1024 * 10);
PcapHandle handler = handleBuilder.build();
String filter = pcapHelper.createPcapFilter(ultraScanInfo);
if (!StringUtils.trim(filter).equals("")) {
handler.setFilter(filter, BpfProgram.BpfCompileMode.OPTIMIZE);
}
ExecutorService pool = Executors.newSingleThreadExecutor();
CloserTask t = new CloserTask(lock);
Future<Boolean> f = pool.submit(t);
try {
int count = 0;
while (!f.isDone()) {
count++;
logger.error("count:"+count);
Packet packet =null;
try {
packet = handler.getNextPacketEx();
}catch (PcapNativeException pcapNativeException){
logger.error("pcapNativeException",pcapNativeException);
}catch (EOFException eofException){
logger.error("eofException",eofException);
}catch (TimeoutException timeoutException){
logger.error("timeoutException",timeoutException);
}catch (NotOpenException notOpenException){
logger.error("notOpenException",notOpenException);
}
logger.error("packet is null:"+(packet == null));
if (packet == null) {
continue;
}
IpV4Packet ipPacket = packet.get(IpV4Packet.class);
logger.error("ipPacket is null:"+(ipPacket == null));
if (ipPacket == null) {
continue;
}
Inet4Address srcAddr = ipPacket.getHeader().getSrcAddr();
String srcAddrIp = srcAddr.getHostAddress();
logger.error("srcAddrIp:"+srcAddrIp);
logger.error("incompleteHosts.containsKey(srcAddrIp)"+(incompleteHosts.containsKey(srcAddrIp)));
if (incompleteHosts.containsKey(srcAddrIp)) {
HostScanInfo hostScanInfo = new HostScanInfo();
hostScanInfo.setIp(srcAddrIp);
hostScanInfo.setReceiveTime(handler.getTimestamp());
hostScanInfo.setReceiveNifMac(receiveMac);
packetTempMap.put(hostScanInfo, packet);
}
Thread.sleep(10);
}
} catch (Exception e) {
logger.error("循环监听回包出错!", e);
throw e;
} finally {
logger.error("finally start............");
pool.shutdownNow();
handler.close();
}
// 处理收包
// if (!packetTempMap.isEmpty()) {
// pcapHelper.dealReceivePacket(packetTempMap, ultraScanInfo, handler);
// }
// ultraScanInfo.setScanEndTime(new Date());
return packetTempMap;
}
/**
* 计时器
*/
private class CloserTask implements Callable<Boolean> {
private Object lock;
public CloserTask(Object lock) {
this.lock = lock;
}
@Override
public Boolean call() throws Exception {
synchronized (lock) {
lock.wait();
return true;
}
}
}
}