5.1.1 - What is a network packet and a header

What is a header?

From the network theory point of view, a protocol header contains information that is specific for that protocol. A header is a concise, structured information that is transmitted between one or more applications on the same or different host computers or other devices. While a protocol as a whole, may be comprised of more than one header type that it uses for communication purposes to exchange information such as state and transmit application specific data. This is the reason why sometimes a protocol is described as a protocol suite. A collection of related headers that facilitate exchange of data for that protocol.

What's inside those headers is usually integers, strings and some times incomprehensible mubo jumbo that only the application the header is intended for can understand. Its a collection of variable's values all stored as raw bytes in that portion of the data buffer, our packet. The header helps to break down those raw bytes into meaningful, structured data set. We call those variables in the header fields.

What is a packet?

A packet is a buffer of certain size, full of data, that is transmitted from one machine to another. This data buffer is transmitted differently depending on which "data-link" network you are using, such as ethernet, FDDI, token-ring, WAN point to point links, etc. The end result is the same, the entire bundle we call a buffer, is transmitted from one machine to another and arrives at the destination intact (hopefully). The receiving machine if this packet sees the packet as a data buffer of certain length. This data buffer starts at certain memory location and ends at certain memory location. Offset 0 into this data buffer represents the first byte of the packet. And the last byte in the buffer is exactly at offset + length of packet.

jNetPcap's header definitions take care of the mundane details of how to reconstruct data out of this raw soup of bytes we found in the packet, into integers, int based flags, strings, Ip addresses, Mac addresses and dozen other details you would have to do by hand yourself. The header definition that you use has accessor methods for each and every field you will find in the header's data buffer. You use normal java methods, that are named after the name of the field to read and write values to or from that field. The name of the fields are usually defined in documents that describe the header structure such as RFCs. The names are usually fairely consistent with the standards that define those headers.

There is more. A packet buffer, the data buffer that contains the entire packet, consists of many headers, usually one right after the other starting at byte offset 0 into the buffer. Each one of those headers is different from the previous one. The previous header usually has a field that determines exactly what header follows right after it. Another words, the header within a packet are like a daisy chain of protocol headers:

| Ethernet | Ip4 | Tcp | Http | Html | 

This is a diagram of a typical packet you will find. This particular packet transmitted our ultimate HTML text document that our browsers can read and display, but there was a lot more going on behind the scene. Just look at all those other types of headers found in the packet. They were all needed to transmit that packet across the network between web browser machine and the web server.

Note that this is a daisy-chain of headers. Ethernet has a field at toward the end of the header called type. This is a 2 byte unsigned short integer that holds a numerical value. That value is the id of the next protocol header right after Ethernet. The Ip4 header has a reserved id value of 0x800 for it. So anyone reading that packet has to look into that type field in order to determine the next protocol. When he does, 0x800 in that field tells him the next header is Ip4. Then Ip4 header also has a type field, in a different location of course, that tells you what the next header is, this type its 6 for Tcp. Tcp reserved with the Ip4 controlling body numer 6 for itself (this was done ages ago). No one else can use 6 for Ip4.type field. Tcp has source and destination port numbers, but same concept, those fields tell what the next header is. 80 is usually reserved for HTTP, but that is actually web server and client configurable. Lastly the Http header contains a field, which is actually text based, a string, that tells what the next header is. In our case that would be html.

This is another major and difficult part of interpreting the data within a packet. In order to know what is stored at the end of the packet, the payload, or the last header and its data, you have to decode or go through the daisy chain of headers, one after the other until you reach the end, in order to figure out what is the last header. Then if you saw that last header was Html you could sent that raw data to your own web browser to see the web page transmitted. Going through this daisy chain, also means that you have to understand everyone of those headers, so you can figure out what the next header is. Also if any of the previous headers threw any quircks into this whole complex mess. Ip4 can fragment everything after it, so you may only be at one Ip4 packet fragment out of several. This means your next header is probably not complete. (For those that are going to jump on me for this, Tcp protocol always sets the DF flag so for Tcp traffic Ip4 will never fragment - there happy Smile

That is where jNetPcap header definitions come in. What the API does is it scans that packet, going through this daisy chain of headers and discovering all the headers that are present in the packet. It learns exactly what type of header it is and where each header begins and ends within the packet. All that information is stored inside a java JPacket object. You can use JPacket to skip over headers and simply ask, is there a Html header in this packet, if yes I'm interested, otherwise lets not do anything with this packet and look at the next packet. Then you can go a step further. You can create an empty Html header, this is a plain old java file, and tell the packet to position the header in the right place so you can read data using that header. Any field methods you invoke, read their values directly out of the packet at the right place, and return that data to you as ints, strings, byte[] whatever that data type is and what ever the header's accessor method for that field signature looks like.