Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

About the getNextPacketEx problem under linux #303

Open
gitlei0507 opened this issue Jan 6, 2023 · 0 comments
Open

About the getNextPacketEx problem under linux #303

gitlei0507 opened this issue Jan 6, 2023 · 0 comments

Comments

@gitlei0507
Copy link

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;
        }
    }
}

}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant