package com.netifera.platform.net.internal.pcap; import java.io.BufferedReader; import java.io.File; import java.io.FileReader; import java.io.IOException; import java.net.NetworkInterface; import java.net.SocketException; import java.util.Collection; import java.util.Collections; import java.util.Enumeration; import java.util.HashSet; import java.util.Set; import org.osgi.service.component.ComponentContext; import com.netifera.platform.api.log.ILogManager; import com.netifera.platform.api.log.ILogger; import com.netifera.platform.api.system.ISystemService; import com.netifera.platform.net.internal.pcap.linux.LinuxPacketCapture; import com.netifera.platform.net.internal.pcap.osx.OsxPacketCapture; import com.netifera.platform.net.pcap.ICaptureInterface; import com.netifera.platform.net.pcap.IPacketCapture; import com.netifera.platform.net.pcap.IPacketCaptureFactoryService; import com.netifera.platform.net.pcap.IPacketHandler; public class PacketCaptureFactoryService implements IPacketCaptureFactoryService { private ISystemService system; private ILogger logger; private final Set<ICaptureInterface> interfaces = new HashSet<ICaptureInterface>(); public IPacketCapture create(ICaptureInterface iface, int snaplen, boolean promiscuous, int timeout, IPacketHandler packetHandler) { PacketCapture pcap = new PacketCapture(iface.getName(), snaplen, promiscuous, timeout, packetHandler); INativePacketCapture nativePcap = createNative(pcap); pcap.setNativeCapture(nativePcap); return pcap; } public Collection<ICaptureInterface> getInterfaces() { synchronized(interfaces) { return new HashSet<ICaptureInterface>(interfaces); } } public Collection<ICaptureInterface> getCurrentInterfaces() { try { initializeInterfaces(); } catch (SocketException e) { return Collections.emptySet(); } return getInterfaces(); } private INativePacketCapture createNative(IPacketCaptureInternal pcap) { switch(system.getOS()) { case OS_OSX: return new OsxPacketCapture(system, pcap, logger); case OS_LINUX: return new LinuxPacketCapture(system, pcap, logger); default: throw new IllegalStateException("No native pcap implementation for current OS"); } } protected void setSystemService(ISystemService system) { this.system = system; } protected void unsetSystemService(ISystemService system) { this.system = null; } protected void activate(ComponentContext ctx) { try { initializeInterfaces(); } catch (SocketException e) { throw new RuntimeException("SocketException initializing interfaces", e); } } protected void deactivate(ComponentContext ctx) { interfaces.clear(); } protected void setLogManager(ILogManager logManager) { logger = logManager.getLogger("PacketCapture"); } protected void unsetLogManager(ILogManager logManager) { logger = null; } private void initializeInterfaces() throws SocketException { Enumeration<NetworkInterface> networkInterfaces = null; try { networkInterfaces = NetworkInterface.getNetworkInterfaces(); } catch(Exception e) { networkInterfaces = null; } if(networkInterfaces == null) { initializeFromProc(); return; } synchronized(interfaces) { interfaces.clear(); while(networkInterfaces.hasMoreElements()) { NetworkInterface iface = networkInterfaces.nextElement(); PacketCapture pcap = new PacketCapture(iface.getDisplayName()); INativePacketCapture nativePcap = createNative(pcap); pcap.setNativeCapture(nativePcap); interfaces.add(new PhysicalInterface(this, iface, pcap.testOpen())); } } } /* * Kind of a hack to make the probe work on Linux */ private boolean initializeFromProc() { File f = new File("/peludo/osfs/proc/net/dev"); if(!(f.exists() && f.canRead())) { return false; } try { return readDevicesFromProc(f); } catch(IOException e) { return false; } } private boolean readDevicesFromProc(File f) throws IOException { BufferedReader in = new BufferedReader(new FileReader(f)); if(in.readLine() == null || in.readLine() == null) { in.close(); return false; } while(true) { final String line = in.readLine(); if(line == null) break; final String deviceName = line.split(":")[0].trim(); interfaces.add(new PseudoInterface(this, deviceName)); } in.close(); return true; } }