style="display:inline-block;width:728px;height:90px"
data-ad-client="ca-pub-7505528228218001"
data-ad-slot="1225241371">

5.6 - Registering a header

Once a header definition is complete you need to "register" your new header with jNetPcap's registry of protocol headers, to make the header active. The JRegistry class provides a JRegistry.register method for registering new headers. In this step, the JRegistry.register method will scan the header definition for any errors to make sure all the required components of a header definition are there.

Here is how you would register a new header definition defined in MyHeader class file.

try {
  int headerID = JRegistry.register(MyHeader.class);

  System.out.printf("Header registered successfully, its numeric ID is %d\n", headerID);

} catch (JRegistryHeaderErrors e) {
  e.printStackTrace();
  System.exit(1);
}

When to register

It is important to know when to register the header with JRegistry. The scanner that is assigned to process packets coming from libpcap, takes a snapshot of all the headers registered at the time, as it is assigned to its task. Therefore you have to register your new header before that happens.

It is recommended that you register your header before even pcap capture is opened. Although this is strictly not necessary, it is recommended that the registration takes place before hand.

Registering from static initializer in header definition itself

A common approach is to put registration code inside the header definition itself in a static initializer. This ensures that the header is always registered the first time the class file is loaded into java VM.

... // header definition class
static {
  try {
    JRegistry.register(MyHeader.class);
  } catch (RegistryHeaderErrors e) {
    e.printStackTrace();
  }
}
... // rest of header definition class

There is however a subtle gotcha with this type of registration which is not very obvious unless you think about it. Static initializer is executed only once when the class file is loaded. Therefore you must ensure that the class file is loaded before any pcap capture sessions are opened. Here is an example of correct way to utilize our new header with static registration:

MyHeader my = new MyHeader(); // Loads the class file and executes static initializer
StringBuilder errbuf = new StringBuilder(); // Error buffer

Pcap pcap = Pcap.openOffline("test.pcap", errbuf);

// Capture packets with handler or next, nextEx, etc..

Ip4 ip = new Ip4();
if (packet.hasHeader(ip) && packet.hasHeader(my)) {
  // We are ready to process IP and MyHeader
} 

An invalid approach:

StringBuilder errbuf = new StringBuilder(); // Error buffer

Pcap pcap = Pcap.openOffline("test.pcap", errbuf);

// Capture packets with handler or next, nextEx, etc..

Ip4 ip = new Ip4();
MyHeader my = new MyHeader(); // Header is registered too late!!!

if (packet.hasHeader(ip) && packet.hasHeader(my)) {
  // We are ready to process IP and MyHeader
} 

As you can see that once the capturing of packets has begun only then do we reference our new header definition which registers the header too late in the process. At this time if a packet scanner has already been assigned to the capture, the packets will not contain the new header. This is a common error with new header definitions, as its easy to forget where the header is being registered and also natural to put the new header definition instantiation where the rest of the headers are instantiated. That can still be done, as long as you ensure that the class file is loaded before hand.