Commit 300b16f8 authored by juvancic's avatar juvancic
Browse files

TA use of jpcap lib from other projects

parent cd00c3a2
Loading
Loading
Loading
Loading
+261 −0
Original line number Diff line number Diff line
package jpcap;

import jpcap.loader.JpcapLibraryLoaderRegistry;
import jpcap.packet.Packet;

/**
 * This class is used to capture packets or read packets from a captured file.
 */
public class JpcapCaptor extends JpcapInstance {
	/**
	 * Number of received packets
	 * 
	 * @see #updateStat()
	 */
	public int received_packets;

	/**
	 * Number of dropped packets
	 * 
	 * @see #updateStat()
	 */
	public int dropped_packets;

	private native String nativeOpenLive(String device, int snaplen,
			int promisc, int to_ms);

	private native String nativeOpenOffline(String filename);

	private native void nativeClose();

	private JpcapCaptor() throws java.io.IOException {
		if (reserveID() < 0)
			throw new java.io.IOException("Unable to open a device: "
					+ MAX_NUMBER_OF_INSTANCE + " devices are already opened.");
	}

	/**
	 * Returns the interfaces that can be used for capturing.
	 * 
	 * @return List of Interface objects
	 */
	public static native NetworkInterface[] getDeviceList();

	/**
	 * Opens the specified network interface, and returns an instance of this class.
	 * 
	 * @return an instance of this class Jpcap.
	 * @param intrface
	 *            The network interface to capture packets
	 * @param snaplen
	 *            Max number of bytes captured at once
	 * @param promisc
	 *            If true, the inferface becomes promiscuous mode
	 * @param to_ms
	 *            Timeout of
	 *            {@link #processPacket(int,PacketReceiver) processPacket()}.
	 *            Not all platforms support a timeout; on platforms that don't,
	 *            the timeout is ignored.
	 *            On platforms that support a timeout, a zero value will cause Jpcap
	 *            to wait forever to allow enough packets to arrive, with no timeout.
	 * @exception java.io.IOException
	 *                Raised when the specified interface cannot be opened
	 */
	public static JpcapCaptor openDevice(NetworkInterface intrface,
			int snaplen, boolean promisc, int to_ms) throws java.io.IOException {
		JpcapCaptor jpcap = new JpcapCaptor();
		String ret = jpcap.nativeOpenLive(intrface.name, snaplen, (promisc ? 1
				: 0), to_ms);

		if (ret != null) // error
			throw new java.io.IOException(ret);

		return jpcap;
	}

	/**
	 * Opens a dump file created by tcpdump or Ethereal, and returns an instance
	 * of this class.
	 * 
	 * @param filename
	 *            File name of the dump file
	 * @exception java.io.IOException
	 *                If the file cannot be opened
	 * @return an instance of this class Jpcap
	 */
	public static JpcapCaptor openFile(String filename)
			throws java.io.IOException {
		JpcapCaptor jpcap = new JpcapCaptor();
		String ret = jpcap.nativeOpenOffline(filename);

		if (ret != null) // error
			throw new java.io.IOException(ret);

		return jpcap;
	}

	/** Closes the opened interface of dump file. */
	public void close() {
		nativeClose();
		unreserveID();
	}

	/**
	 * Captures a single packet.
	 * 
	 * @return a captured packet. <br>
	 * null if an error occured or timeout has elapsed. <br>
	 * Packet.EOF is EOF was reached when reading from a offline file.
	 */
	public native Packet getPacket();
	
	 /**
   * Captures a single ip packet.
   * 
   * @return a captured packet. <br>
   * null if an error occured or timeout has elapsed. <br>
   * Packet.EOF is EOF was reached when reading from a offline file.
   */
  public native Packet getIpPacket();

	/**
	 * Captures the specified number of packets consecutively.<br/>
	 * 
	 * Unlike loopPacket(), this method returns (althrough not guaranteed)
	 * when the timeout expires. Also, in "non-blocking" mode, this
	 * method returns immediately when there is no packet to capture.
	 * 
	 * @param count
	 *            Number of packets to be captured<BR>
	 *            You can specify -1 to capture packets parmanently until
	 *            timeour, EOF or an error occurs.
	 * @param handler
	 *            an instnace of JpcapHandler that analyzes the captured packets
	 * @return Number of captured packets
	 */
	public native int processPacket(int count, PacketReceiver handler);

	/**
	 * Captures the specified number of packets consecutively.
	 * <P>
	 * 
	 * Unlike processPacket(), this method ignores the timeout.
	 * This method also does not support "non-blocking" mode.
	 * 
	 * @param count
	 *            Number of packets to be captured<BR>
	 *            You can specify -1 to capture packets parmanently until EOF or
	 *            an error occurs.
	 * @param handler
	 *            an instnace of JpcapHandler that analyzes the captured packets
	 * @return Number of captured packets
	 */
	public native int loopPacket(int count, PacketReceiver handler);

	/**
	 * Same as <a href="#processPacket(int, jpcap.PacketReceiver)">processPacket()</a>
	 */
	@Deprecated
	public int dispatchPacket(int count, PacketReceiver handler){
		return processPacket(count,handler);
	}

	/**
	 * Sets/unsets "non-blocking" mode
	 * 
	 * @param nonblocking
	 *            TRUE to set "non-blocking" mode. FALSE to set "blocking" mode
	 */
	public native void setNonBlockingMode(boolean nonblocking);

	/**
	 * Checks if the current setting is in "non-blocking" mode or not.
	 * 
	 * @return TRUE if it is in "non-blocking" mode. FALSE otherwise.
	 */
	public native boolean isNonBlockinMode();

	/**
	 * Set a flag that will force processPacket() and loopPacket() to return
	 * rather than looping.
	 * 
	 * <P>
	 * 
	 * Note that processPacket() and loopPacket() will not return after this
	 * flag is set UNTIL a packet is received or a read timeout occurs. By
	 * default, there is no read timeout. See comments in
	 * setPacketReadTimeout().
	 */
	public native void breakLoop();

	/**
	 * Sets the socket read timeout (SO_RCVTIMEO) for the socket used to read
	 * packets from the kernel. Setting this timeout is useful if using
	 * processPacket() or loopPacket() in blocking mode and you expect
	 * breakLoop() to work. breakLoop() will only have an effect if (a) you are
	 * actually getting packets or (b) if the read on the socket times out
	 * occasionally.
	 * <P>
	 * 
	 * This is currently only supported on UNIX.
	 * 
	 * @param millis
	 *            Timeout in milliseconds; 0 for no timeout.
	 * @return true upon success; false upon failure or if unsupported.
	 */
	public native boolean setPacketReadTimeout(int millis);

	/**
	 * Returns the socket read timeout (SO_RCVTIMEO) for the socket used to read
	 * packets from the kernel.
	 * <P>
	 * 
	 * This is currently only supported on UNIX.
	 * 
	 * @return Read timeout in milliseconds; 0 for no timeout; -1 if an error
	 *         occurred or this feature is unsupported.
	 */
	public native int getPacketReadTimeout();

	/**
	 * Sets a filter. This filter is same as tcpdump.
	 * 
	 * @param condition
	 *            a string representation of the filter
	 * @param optimize
	 *            If true, the filter is optimized
	 * @exception java.io.IOException
	 *                Raised if the filter condition cannot be compiled or
	 *                installed
	 */
	public native void setFilter(String condition, boolean optimize)
			throws java.io.IOException;

	/**
	 * Updates {@link #received_packets received_packets} and
	 * {@link #dropped_packets dropped_packets}.
	 */
	public native void updateStat();

	/**
	 * Returns an error message
	 * 
	 * @return error message
	 */
	public native String getErrorMessage();

	/**
	 * Obtains an instance of JpcapSender that uses the same interface to send
	 * packets. You can use this method only if you opened an interface with
	 * openDevice() method.
	 * 
	 * @return returns an instance of JpcapSender
	 */
	public JpcapSender getJpcapSenderInstance() {
		return new JpcapSender(ID);
	}

	static {
		JpcapLibraryLoaderRegistry.getInstance().loadLibrary();
	}
}
+24 −0
Original line number Diff line number Diff line
package jpcap;

abstract class JpcapInstance {
	protected static final int MAX_NUMBER_OF_INSTANCE = 255;

	protected static boolean[] instanciatedFlag = new boolean[MAX_NUMBER_OF_INSTANCE];

	protected int ID;

	protected int reserveID(){
		ID = -1;
		for (int i = 0; i < MAX_NUMBER_OF_INSTANCE; i++)
			if (!instanciatedFlag[i]) {
				ID = i;
				instanciatedFlag[i] = true;
				break;
			}
		return ID;
	}
	
	protected void unreserveID(){
		instanciatedFlag[ID]=false;
	}
}
+103 −0
Original line number Diff line number Diff line
package jpcap;

import jpcap.packet.Packet;

/** This class is used to send a packet. */
public class JpcapSender extends JpcapInstance {
	private native String nativeOpenDevice(String device);
	private native void nativeSendPacket(Packet packet);
	private native void nativeCloseDevice();
	private native void nativeOpenRawSocket();
	private native void nativeSendPacketViaRawSocket(Packet packet);
	private native void nativeCloseRawSocket();
	
	private static final int RAW_SOCKET_ID=99999;

	private String f_device = null;
	
	private JpcapSender() throws java.io.IOException {
		if (reserveID() < 0)
			throw new java.io.IOException("Unable to open a device: "
					+ MAX_NUMBER_OF_INSTANCE + " devices are already opened.");
	}
	
	JpcapSender(int ID){
		this.ID=ID;
	}

	/**
	 * Initializes a network interface for sending a packet, and returns an
	 * instance of this class.
	 * 
	 * @param device
	 *            Interface for sending a packet
	 * @throws IOException
	 *             Raised when initialization of the interface failed
	 * @return intstance of this class (JpcapSender)
	 */
	public static JpcapSender openDevice(NetworkInterface device) throws java.io.IOException {
		JpcapSender sender = new JpcapSender();
		String ret=sender.nativeOpenDevice(device.name);

		sender.f_device = device.name;

		if(ret==null)
			return sender;
		else
			throw new java.io.IOException(ret);
	}

	/**
	 * Open a raw IP socket to send a packet.<BR>
	 * When sending a packet via a raw socket, the datalink header of the packet is ignored
	 * (= automatically generated by OS).<P>
	 * Note: the implementation and behavior of a raw socket may vary in different OS.
	 * Also, you can only open one raw socket at a time.
	 * 
	 * @throws IOException
	 *             Raised when initialization of the interface failed
	 * @return intstance of this class (JpcapSender)
	 */
	@Deprecated
	public static JpcapSender openRawSocket() throws java.io.IOException {
		JpcapSender sender = new JpcapSender();
		sender.nativeOpenRawSocket();
		sender.ID=RAW_SOCKET_ID;
		
		return sender;
	}

	/** Closes the interface. */
	public void close() {
		if(ID==RAW_SOCKET_ID)
			nativeCloseRawSocket();
		else
			nativeCloseDevice();
		unreserveID();
	}

	/**
	 * Sends a packet.
	 * <P>
	 * If this JpcapSender instance was created by openDevice(), you need to set
	 * the Datalink layer's header (e.g., Ethernet header) of the packet. <P>
	 * 
	 * If this JpcapSender instance was created by openRawSocket(), you can only
	 * send IP packets, but you may not need to set the Datalink layer's header
	 * of the IP packets you want to send.<BR>
	 * Note: the implementation and behavior of a raw socket may vary in different OS.
	 * For example, in Windows 2000/XP, you need to manually set the datalink/IP headers
	 * of a packet. 
	 * @param packet Packet to be sent
	 */
	public void sendPacket(Packet packet){
		if(ID==RAW_SOCKET_ID)
			nativeSendPacketViaRawSocket(packet);
		else
			nativeSendPacket(packet);
	}

	public String getDeviceId() {
		return f_device;
	}
}
+55 −0
Original line number Diff line number Diff line
package jpcap;

import jpcap.loader.JpcapLibraryLoaderRegistry;
import jpcap.packet.Packet;

/** This class is used to save the captured packets into a file. */
public class JpcapWriter extends JpcapWriterInstance
{	
  private JpcapWriter(JpcapCaptor jpcapCaptor, String filename)
      throws java.io.IOException {
    if (reserveID() < 0) {
      throw new java.io.IOException("Unable to open a writer: "
          + MAX_NUMBER_OF_INSTANCE + " writers are already opened.");
    }
    
    String ret = nativeOpenDumpFile(filename, jpcapCaptor.ID, ID);

    if (ret != null) { // error
      unreserveID();
      throw new java.io.IOException(ret);
    }
  }
	
	/** Opens a file to save the captured packets.
     * @param jpcap instance of JpcapCaptor that was used to capture (load) packets
     * @param filename filename
     * @throws IOException If the file cannot be opened
     */
	public static JpcapWriter openDumpFile(JpcapCaptor jpcap,String filename) throws java.io.IOException{
		return new JpcapWriter(jpcap,filename);
	}
	
	public void close() {
	  nativeClose(ID);
	  unreserveID();
	}
	
	public void writePacket(Packet packet) {
	  nativeWritePacket(packet, ID);
	}
	
	private native String nativeOpenDumpFile(String filename, int captorId, int writerId);
	
	/** Closes the opened file. */
	private native void nativeClose(int id);
	
	/** Saves a packet into the file.
         * @param packet Packet to be saved
         */
	private native void nativeWritePacket(Packet packet, int writerId);

  static {
    JpcapLibraryLoaderRegistry.getInstance().loadLibrary();
  }
}
+24 −0
Original line number Diff line number Diff line
package jpcap;

abstract class JpcapWriterInstance {
	protected static final int MAX_NUMBER_OF_INSTANCE = 255;

	protected static boolean[] instanciatedFlag = new boolean[MAX_NUMBER_OF_INSTANCE];

	protected int ID;

	protected int reserveID(){
		ID = -1;
		for (int i = 0; i < MAX_NUMBER_OF_INSTANCE; i++)
			if (!instanciatedFlag[i]) {
				ID = i;
				instanciatedFlag[i] = true;
				break;
			}
		return ID;
	}
	
	protected void unreserveID(){
		instanciatedFlag[ID]=false;
	}
}
Loading