package com.netifera.platform.net.wifi.internal.sniffing; 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.wifi.pcap.IWifiPacketCapture; import com.netifera.platform.net.wifi.sniffing.IWifiSniffingEngine; public class WirelessRawManager extends AbstractPacketManager<IPacketHeader> implements IPacketSource { private IPacketDecoder decoder; private IWifiPacketCapture wirelessPcap; private Thread sniffingThread; private final Runnable sniffingLoop; private final IPacketHandler handler; private final ICaptureInterfaceEx iface; public WirelessRawManager(IWifiSniffingEngine engine, ICaptureInterfaceEx iface) { super(engine, iface); this.iface = iface; 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; final IPacketHeader packet = decoder.decode(packetData); deliverPacket(packet, header); } private void readPackets() { if(!wirelessPcap.read()) { getLogger().error("Wireless read failed on interface (" + getInterface().getName() + ") : " + wirelessPcap.getLastError()); getLogger().warning("Closing interface (" + getInterface().getName() + ") on error."); wirelessPcap.close(); wirelessPcap = null; Thread.currentThread().interrupt(); } } @Override protected boolean start() { if(isStarted()) return true; final ISniffingEngineService e = getSniffingEngine(); final IPacketCapture pcap = iface.pcapCreate(e.getSnaplen(), e.getPromiscuous(), e.getTimeout(), handler); if(!(pcap instanceof IWifiPacketCapture)) { getLogger().error("Unexpected capture instance type in Wireless Raw Manager"); return false; } if(!pcap.open()) { getLogger().error("Failed to open wireless interface '" + getInterface().getName() + "' for sniffing: " + pcap.getLastError()); pcap.close(); return false; } decoder = pcap.getDecoder(); if(decoder == null) { getLogger().error("No decoder available for link type " + pcap.getLinkType()); pcap.close(); return false; } wirelessPcap = (IWifiPacketCapture) pcap; sniffingThread = new Thread(sniffingLoop, "Wireless Sniffing Engine Thread on Interface (" + getInterface().getName() + ")"); sniffingThread.start(); return true; } @Override protected void stop() { sniffingThread.interrupt(); if(wirelessPcap != null) { wirelessPcap.close(); } try { sniffingThread.join(); } catch (InterruptedException e) { Thread.currentThread().interrupt(); } sniffingThread = null; wirelessPcap = null; } }