|
|||||||||
| PREV PACKAGE NEXT PACKAGE | FRAMES NO FRAMES | ||||||||
See:
Description
| Interface Summary | |
|---|---|
| JBinding | A bindinding between two protocol headers. |
| JCompoundHeader<B extends JHeader> | |
| JDependency | Lists binding's protocol dependencies. |
| JHeaderAccessor | Accessor to get a structured header from underlying buffer. |
| JHeaderType | |
| JPacketHandler<T> | A dispatchable packet hadler. |
| JPayloadAccessor | Interface which provides access to payload portion of the packet data. |
| PcapPacketHandler<T> | |
| Class Summary | |
|---|---|
| AbstractBinding<H extends JHeader> | |
| AbstractMessageHeader | |
| JBinding.DefaultJBinding | An abstract adaptor that provides a default implementation for a binding. |
| JFlow | |
| JFlowKey | A unique key that identifies a flow of related packets. |
| JFlowMap | |
| JHeader | A base class for all protocol header definitions. |
| JHeader.State | This class is peered state of a header a native state structure |
| JHeaderMap<B extends JHeader> | |
| JHeaderPool | A thread local pool of instances of headers. |
| JHeaderScanner | A header scanner, there is one per header, that is able to scan raw memory buffer and determine the length of the header and the next header ID after examining the current header's structure. |
| JMappedHeader | |
| JMemoryPacket | A heap based packet. |
| JMemoryPacket.JMemoryHeader | A capture header that stores information about the creation of the packet. |
| JPacket | A native packet buffer object. |
| JPacket.State | Class maintains the decoded packet state. |
| JRegistry | A registry of protocols, their classes, runtime IDs and bindings. |
| JScan | A inprogress working scan structure. |
| JScanner | JMemory with struct scanner_t, binding_t, packet_t and header_t structures. |
| JSubHeader<T extends JHeader> | |
| Payload | Builtin header type that is a catch all for all unmatch data within a packet buffer |
| PcapPacket | A pcap packet. |
| Enum Summary | |
|---|---|
| AbstractMessageHeader.MessageType | |
| Exception Summary | |
|---|---|
| PeeringException | |
| RegistryException | |
| RegistryHeaderErrors | |
| RegistryRuntimeException | |
| UnregisteredHeaderException | Thrown when a lookup on a header in JRegistry fails |
Packet decoding framework. Packet buffers are scanned and decoded.
loop
and
dispatch
methods that deliver decoded packets to the registered handler. The
class JPacket allows the programmer to check for existance of certain
protocol headers within the packet's data buffer. The programmer can use
a header to then access any of the fields and logic for that protocol.
Here is an example of what a JPacketHandler might look like:
JPacketHandlerThe example demonstates ahandler = new JPacketHandler () { private Ethernet eth = new Ethernet(); private Ip4 ip = new Ip4(); public void nextPacket(JPacket packet, String user) { if (packet.hasHeader(Ethernet.ID)) { eth = packet.getHeader(eth); byte[] dstMac = eth.destination(); byte[] srcMac = eth.source(); int type = eth.type(); // Do something } /* * For convenience there is a hasHeader method that takes a header instance * and combines hasHeader with getHeader methods if the header exists. */ if (packet.hasHeader(ip)) { int flags = ip.flags(); int offset = ip.offset(); byte[] srcIp = ip.source(); byte[] dstIp = ip.destination(); int protocol = ip.protocol(); } // Or can simply print out the contents of the packet System.out.println(packet.toString()); } }
JPacketHandler
implementation, which gets passed into
loop/dispatch
methods and receives packets. The handler's
nextPacket
method receives a fully decoded packet. The information about which
headers exist, where in the buffer and how long they are is recorded in
native structures which
JPacket, JPacket.State, JHeader, JHeader.State
classes access. The method
JPacket.hasHeader
is a simply bitwise operation on an unsigned integer that is very
efficient and fast.
The typical steps for working with the packet objects is first to check if the header the user is insterested in exists in the packet, has been found by the packet scanner, and then request that user supplied header instance is peered with the native structures that describe that header.(Peering means that the physical address of the native structure is recorded somewhere in the java class beeing peered and afterwards that class uses that pointer to access and retrieve data from the physical native structure or buffer.)
The framework provides additional Pcap.loop and
Pcap.dispatch methods which allow the user to supply a JPacketHandler,
as opposed to PcapHandler, which delivers a decoded JPacket
object to the user's callback method JPacketHandler.nextPacket(JPacket
packet, Object user)
JPacket class is the main interface to the decoded
packet information, specifically; which protocol headers exist in the
packet, found by scanning the raw byte buffer, and detailed information
on those headers. The user can query a JPacket using
methods JPacket.hasHeader(int id), JPacket.getHeader(T
header):<T extends JHeader> T and JPacket.getCaptureHeader()
which returns the capture information such as timestamp and wirele
(length of the packet as seen on the network wire.)
There are also numerous support and other implementation classes such as
The scanner implementation is almost completely in native code. The scanner when its initialized allocates a large native memory block to hold its state and state about every packet it decodes. A pointer into the buffer is maintained which points to memory space where packet state can be recorded. Pointer is advanced for each packet that is being scanned. When the buffer is exhausted and the end is reached, the buffer simply wraps around to the beginning and the buffer is reused. This is the same algorithm that native libpcap uses for its capture buffer. So both the raw packet buffer, maintained by libpcap, and the packet decoded state information, maintained by JScanner, are kept in temporary, roundrobin buffers. This is something that also applies to other Pcap.loop and Pcap.dispatch methods that only dispatch raw byte buffers.
As packets arrive and the scanner is asked to scan them, it increments a pointer to a packet_state_t structure, within its buffer. The packet_state_t structure is where information is recorded about each headers. First there is a compress bitmap which using header's numerical IDs, records information about the presence of a header by setting a bit in this bitmap (an unsigned integer). Calls to JPacket.hasHeader(int id) simply check if a bit is set for a specific header ID and return true or false. Therefore JPacket.hasHeader checks are very light and fast and can be made frequently without having to worry about performance. Secondly, the scanner also records header's position within the buffer and the header's length. That information is also recorded in packet_state_t which has a header_state_t array member. The last header is typically a payload header, a special header that is catch all and captures the remainder of the packet that was not matched with any protocol header.
Before we begin on native structures, lets look at the class inheritance tree.
jMemory
+-> JBuffer
| +-> JPacket - peered with libpcap packet data buffer
|
+-> JStruct
+-> JPacket.State - peered with JScanners packet_state_t structure
+-> JHeader.State - peered with JScanners header_state_t structure
Further more, JPacket maintains an internal reference to a JPacket.State
object as a private field. That is JPacket is peered with libpcap packet
buffer, while a separate JPacket.State object is peered with the
JScanner packet state structure. Notice that JPacket extends JBuffer,
therefore any JPacket can be used as a normal JBuffer providing full
access to all of the packets raw contents. The state information is
allocated and maintained by JScanner.
Packets are assigned a packet_state_t structure by peering a java class with this native memory structure. jNetPcap uses the concept of native peers by holding the physical memory address as a internal private field within the java object. Native functions when called upon, retrieve this address location, cast a local pointer to that physical memory location for the structure that the class is peered with and then access that information. So a JPacket.State object is peered with a packet_state_t structure (residing in native memory) by simply changing a single java field. Java objects that are peered, hold very little additional information about the structure. There are some additional fields that are maintained for security purposes such as the size of the memory block and who the java owner of that memory block is. This information is only maintained for security and deallocation of memory purposes when the java parent object is garbage collected. This peering mechanism allows previously allocated packets to be reused extrememly efficiently, by simply changing a single pointer to a packet_state_t structure within it and changing the state of the packet immediately. JHeaders also maintain their state in this way.
|
|||||||||
| PREV PACKAGE NEXT PACKAGE | FRAMES NO FRAMES | ||||||||