org.jnetpcap.packet
Class JScanner

java.lang.Object
  extended by org.jnetpcap.nio.JMemory
      extended by org.jnetpcap.nio.JStruct
          extended by org.jnetpcap.packet.JScanner

public class JScanner
extends JStruct

JMemory with struct scanner_t, binding_t, packet_t and header_t structures. JScanner utilizes unique numerical IDs assigned to each header to optimize access and recording of information about the presence of each header in various lookup array and bit masks. It also allocates a large memory block natively and sub-allocates structures per packet and for each header. When the end of the buffer is reached the buffer pointer is repositioned at the beginning of the buffer and the memory block is reused, another words round-robin algorithm is used over a single large buffer.

JScanner keeps a global jRegistry of header to ID mappings, bindings between various headers and depedencies which are used to efficiently apply the registered bindings. Further more, each JScanner instance can be customized with a custom set of bindings and dependencies on a per instance basis. The default is to use the global jRegistry. Therefore it is possible to override certain bindings on a scanner basis such as overriding default binding for an application level protocol to TCP port numbers for example.

The main scanner method is called scan(). This is a native method that scans the contents of the supplied JBuffer which also contains its data in native memory block typically allocated by libpcap, and records the output of the scan into series of native structures and bitmaps. This information is referenced by JPacket object. The JPacket memory pointer is the only thing changed and thus a single JPacket object can very quickly be repositioned to a new packet state.

 typedef struct header_t {
  int32_t hdr_id; // header ID
  int32_t hdr_offset; // offset into the packet_t->data buffer
  int32_t hdr_length; // length of the header in packet_t->data buffer
 } header_t;
 
 typedef struct packet_t {
  uint64_t pkt_header_map; // bit map of presence of headers
 
  // Keep track of how many instances of each header we have
  uint8_t pkt_instance_counts[MAX_ID_COUNT];
  char *pkt_data; // packet data buffer
 
  int32_t pkt_header_count; // total number of headers found
  header_t pkt_headers[]; // One per header + 1 more for payload
  } packet_t;
 
  typedef struct binding_t {
  int32_t bnd_id; // ID of the header that this binding is for
  // Map of required headers that must already processed in this packet
  uint64_t bnd_dependency_map;
  jobject bnd_jbinding; // JBinding object
 } java_binding_t;
 
 typedef struct scanner_t {
  int32_t sc_len; // bytes allocated for sc_packets buffer
  int32_t sc_offset; // offset into sc_packets for next packet
 
  // Cumulative map of dependencies that must already exist in the packet
  uint64_t sc_dependency_map[MAX_ID_COUNT];
 
  // Array of binding structures; The second array is NULL terminated 
  binding_t sc_bindings[MAX_ID_COUNT][MAX_BINDING_COUNT];
 
  uint64_t sc_binding_map; // bit mapping of java bindings 
 
  // Overrides CORE protocol bindings
  uint64_t sc_override_map[MAX_ID_COUNT];
  packet_t *sc_packet; // ptr into scanner_t where the first packet begins
 } scanner_t;
 
 

Note that a packet scanner (JScanner) is not a lightweight object but actually fairely heavy to initialize and run. The scanner typically allocates on the order of 100Kb of internal native memory for its state structures and buffer. It is advisable to use its thread local getter methods which maintain a pool of scanners on a per thread basis. Of course a new instance of a scanner can be instantiated and configured differently from the default case which uses the information in the global registry.

Author:
Mark Bednarczyk, Sly Technologies, Inc.

Nested Class Summary
 
Nested classes/interfaces inherited from class org.jnetpcap.nio.JMemory
JMemory.Type
 
Field Summary
static int DEFAULT_BLOCKSIZE
          Default allocation for memory block/buffer
static int MAX_ENTRY_COUNT
          Maximum number of header entries allowed per packet buffer by the scanner
static int MAX_ID_COUNT
          Maximum number of ID entries allowed by the scanner
static java.lang.String STRUCT_NAME
          Name of the peered native structure
 
Fields inherited from class org.jnetpcap.nio.JMemory
JNETPCAP_LIBRARY_NAME
 
Constructor Summary
JScanner()
          Allocates a default scanner using #DEFAULT_BLOCKSIZE buffer size
JScanner(int blocksize)
          Allocates the requested blocksize of memory + the sizeof(scanner_t)
 
Method Summary
protected  void finalize()
          Default finalizer which checks if there is any memory to free up.
static JScanner getThreadLocal()
          Maintains and allocates a pool of packet scanners.
 void reloadAll()
          Reloads the scanner and bindings table from JRegistry down to native scanner structures.
 int scan(JPacket packet, int id)
          Performs a scan on a packet that has been peered with a packet data buffer.
 
Methods inherited from class org.jnetpcap.nio.JStruct
getStructName, toString
 
Methods inherited from class org.jnetpcap.nio.JMemory
check, cleanup, isInitialized, isJMemoryBasedOwner, isOwner, peer, peer, peer, setSize, size, toDebugString, toHexdump, toHexdump, totalActiveAllocated, totalAllocateCalls, totalAllocated, totalAllocatedSegments0To255Bytes, totalAllocatedSegments256OrAbove, totalDeAllocateCalls, totalDeAllocated, transferFrom, transferFrom, transferFrom, transferFrom, transferFromDirect, transferOwnership, transferTo, transferTo, transferTo, transferTo, transferTo, transferTo, transferTo
 
Methods inherited from class java.lang.Object
clone, equals, getClass, hashCode, notify, notifyAll, wait, wait, wait
 

Field Detail

DEFAULT_BLOCKSIZE

public static final int DEFAULT_BLOCKSIZE
Default allocation for memory block/buffer

See Also:
Constant Field Values

MAX_ENTRY_COUNT

public static final int MAX_ENTRY_COUNT
Maximum number of header entries allowed per packet buffer by the scanner

See Also:
Constant Field Values

MAX_ID_COUNT

public static final int MAX_ID_COUNT
Maximum number of ID entries allowed by the scanner

See Also:
Constant Field Values

STRUCT_NAME

public static final java.lang.String STRUCT_NAME
Name of the peered native structure

See Also:
Constant Field Values
Constructor Detail

JScanner

public JScanner()
Allocates a default scanner using #DEFAULT_BLOCKSIZE buffer size


JScanner

public JScanner(int blocksize)
Allocates the requested blocksize of memory + the sizeof(scanner_t)

Parameters:
blocksize -
Method Detail

getThreadLocal

public static JScanner getThreadLocal()
Maintains and allocates a pool of packet scanners.

Returns:
a thread local global scanner

finalize

protected void finalize()
Description copied from class: JMemory
Default finalizer which checks if there is any memory to free up.

Overrides:
finalize in class JMemory

reloadAll

public void reloadAll()
Reloads the scanner and bindings table from JRegistry down to native scanner structures.


scan

public int scan(JPacket packet,
                int id)
Performs a scan on a packet that has been peered with a packet data buffer. The state structure o the packet is filled in and peered at the time of the packet scan.

Parameters:
packet - packet to process
id - numerical ID of the data link protocol, or first header within the data buffer
Returns:
number of bytes processed