There are 2 types of headers you are dealing with. The terminology describes both and both are very related to each other. This is the source of the confusion.
First is the actual header data that resides within the packet buffer. This is the data that actually travels, as part of the packet, on the network. A network packet is captured as a buffer full of bytes, that contain data for many different protocols.
Second is the jNetPcap's JHeader based object that helps you read that data out of the raw packet buffer. This is the part that is reusable.
Another words, you do not have to allocate a new header object for each packet you want to read the header out of. Here are a few short pseudo examples that demonstrate where its recommended that header object's are instantiated for best performance.
Recommended - outside the main loop:
JHeader header = new Ethernet(); // Your header object
LOOP() {
JPacket packet = pcap.nextEx(); // read the next packet
if (packet.hasHeader(header)) {
}
}
Also recommended - as a class fields:
public class MyHeaderReader {
private JHeader header = new Ethernet(); // Your header object
public void readHeader(JPacket packet) {
if (packet.hasHeader(header)) {
}
}
}
Not recommended - inside the loop:
LOOP() {
JPacket packet = pcap.nextEx(); // read the next packet
JHeader header = new Ethernet(); // Your header object
if (packet.hasHeader(header)) {
}
}
The header java object can be associated with new header within a packet without having to allocate a new instance of it. This process is called "peering" in jNetPcap vocabulary. No data copies take place, only references to where the data resides change. This is a very efficient way of accessing lots and lots of headers.