package com.netifera.platform.net.internal.sniffing.managers; import java.nio.ByteBuffer; import com.netifera.platform.net.packets.IPacketDecoder; import com.netifera.platform.net.packets.IPacketHeader; import com.netifera.platform.net.pcap.ICaptureHeader; import com.netifera.platform.net.pcap.IPacketCapture; import com.netifera.platform.net.pcap.IPacketHandler; import com.netifera.platform.net.pcap.ex.ICaptureInterfaceEx; import com.netifera.platform.net.sniffing.ISniffingEngineService; import com.netifera.platform.net.sniffing.util.AbstractPacketManager; import com.netifera.platform.net.sniffing.util.IPacketSource; import com.netifera.platform.net.sniffing.util.ISniffingEngineEx; public class RawManager extends AbstractPacketManager<IPacketHeader> implements IPacketSource { private IPacketDecoder decoder; private IPacketCapture pcap; // private final IPReassembler ipReassembler = new IPReassembler(); private Thread sniffingThread; private final Runnable sniffingLoop; private final IPacketHandler handler; private final ICaptureInterfaceEx iface; public RawManager(ISniffingEngineEx engine, ICaptureInterfaceEx captureInterface) { super(engine, captureInterface); iface = captureInterface; sniffingLoop = new Runnable() { public void run() { while(!Thread.interrupted()) { readPackets(); } } }; handler = new IPacketHandler() { public void handlePacket(ByteBuffer packetData, ICaptureHeader header) { processPacket(packetData, header); } }; } private void processPacket(ByteBuffer packetData, ICaptureHeader header) { if(!hasClients()) { return; } IPacketHeader packet = decoder.decode(packetData); deliverPacket(packet, header); } private void readPackets() { if(!pcap.read()) { getLogger().error("Read failed on interface (" + getInterface().getName() + ") : " + pcap.getLastError()); getLogger().warning("Closing interface (" + getInterface().getName() + ") on error."); pcap.close(); pcap = null; Thread.currentThread().interrupt(); } } @Override protected boolean start() { if(isStarted()) { return true; } final ISniffingEngineService e = getSniffingEngine(); pcap = iface.pcapCreate(e.getSnaplen(), e.getPromiscuous(), e.getTimeout(), handler); if(!pcap.open()) { getLogger().error("failed to open interface '" + getInterface().getName() + "' for sniffing: " + pcap.getLastError()); pcap.close(); pcap = null; return false; } decoder = pcap.getDecoder(); if(decoder == null) { getLogger().error("No decoder available for link type " + pcap.getLinkType() + " on interface " + getInterface().getName()); pcap.close(); pcap = null; return false; } sniffingThread = new Thread(sniffingLoop, "Sniffing Engine Thread on Interface (" + getInterface().getName() + ")"); sniffingThread.start(); return true; } @Override protected void stop() { sniffingThread.interrupt(); if(pcap != null) { pcap.close(); } try { sniffingThread.join(); } catch (InterruptedException e) { Thread.currentThread().interrupt(); } sniffingThread = null; pcap = null; } }