Network Engineering Stack Exchange is a question and answer site for network engineers. It's 100% free, no registration required.

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

Note this is not a duplicate of Why is the IP layer aware of higher layers in the network stack?

The need for a protocol identifier (eg. the IP header's Protocol field) in packet-based communication is clear: It's either this or some sort of computationally-intensive inference algorithm. The question is: why must it exist as part of the IP header rather than in the encapsulated protocols' headers?

It seems to me that this one of those cases where theoretical clarity meets practical considerations (AKA "Haskell meets Go"...): On the one hand placing a "protocol" field in the IP header breaks the conceptual separation of interests that eg. the OSI model aimed for; on the other hand forcing protocols higher up the stack to state their type in a consistent manner is much harder, and would eventually lead to a similar situation anyway (eg. if every protocol higher up the stack used its first header byte to state its type, it would look as if IP used its last header byte to do the same).

So my question is - what was the reasoning behind placing the "protocol" field inside the IP's packet header rather than anywhere else?

Edit: When writing this question I pondered whether to add the word "original" before "reasoning", ie the reasoning of the team that devised IP, but reckoned it was redundant as the question was phrased in the past tense ("what was the reasoning..."). Nevertheless this seems needed, as none of the replies actually answers that question. Some insights of note:

  • @immibis suggests any other form would break other protocols' models (eg. encrypted communication protocols would have to have a plaintext identification field)
  • @Eddie essentially states that the reason is convention (acceptance of the protocol chain design, though why that's the convention remains a mystery)
  • @Ricky stresses practicality as an overarching consideration
  • @Claudio suggests that were the protocol field a part of the encapsulated header there would be need for an additional header identification step, where in the current model that takes place during the IP header's parsing

So I'll rephrase: What's wrong with a model where instead of every header identifying the next header's type, every header identifies its own type in a predetermined location (eg. in the first header byte)? Why is such a model any less desirable than the current one?

Edit #2: It seems that the answer is a combination of several of the answers given (mainly those mentioned above along with @Eddie's second addendum):

  1. Simplicity: Breaking the principal of layer agnosticism in this particular case means the stack (or the model) as a whole can be simpler:

    • There's no "protocol identification" phase, neither implicit nor explicit
    • Layer independence is improved (eg. an encrypted communications handler doesn't have to share a layer with any helper protocol)

    Regulation is also greatly simplified, not having to enforce any requirements on client protocols.

  2. Performance: Stating the protocol of an encapsulated packet ahead of the packet itself allows several types of fast routing protocols (packet filtering, QOS, cut-through switching) to be integrated into the network (internet) layer itself; these can then make decisions as quickly as a hash table can be accessed, which is all the more important considering the limited hardware this protocol was designed to run on.

This model has its disadvantages, but it seems that for the common usage cases it's better suited than the alternatives.

share|improve this question
10  
If the protocol number is part of the encapsulated data, and you don't know the format of the encapsulated data (because you don't know the protocol), then how do you know where to find the protocol number? – immibis Feb 2 at 2:01
    
Good rephrase of your question. It makes more sense now what you are asking. I think I have an answer, but I'm going to give it a day or so to mull around in my head to make sure it makes sense. – Eddie Feb 2 at 13:28
5  
"What's wrong with a model where instead of every header identifying the next header's type, every header identifies its own type in a predetermined location?" Because then it's effectively just the last byte of the IPv4 (or whatever lower-level protocol) header in all but name. It's a "chicken or egg" problem. You can't parse a header if you don't know what protocol it is. – reirab Feb 2 at 15:28
    
Added my thoughts to my answer below. Also, I think @reirab brought up a fantastic point. – Eddie Feb 3 at 3:52
    
I think that probably no one can answer this question apart from the designers of these protocols, so I'm curious to know: Whats wrong with this design? Are you asking because it causes a problem for you, or you don't like it, or just curious? – jwbensley Feb 8 at 20:59
up vote 12 down vote accepted

Remember, bits arrive on a NIC as a series of 1's and 0's. Something has to exist to dictate how the next series of 1's and 0's should be interpreted.

Ethernet2 is the defacto standard for L2, as such it is assumed to interpret the first 56 bits as a Preamble, and the next 8 bits as the Preamble, and the next 48 bits as the Destination MAC, and the next 48 bits as the Source MAC, and so on and so forth.

The only variation might be the somewhat antiquated 802.3 L2 header, which predates the current Ethernet2 standard, but also included a SNAP header which served the same purpose. But, I digress.

The standard, Ethernet2 L2 header has a Type field, which tells the receiving node how to interpret the 1's and 0's that follow: Ethernet Header with Type field highlighted

Without this, how would the receiving entity know whether the L3 header is IP, or IPv6? (or AppleTalk, or IPX, or IPv8, etc...)

The L3 header (to the same frame as above) has the Protocol field, which tells the receiving node how to interpret the next set of 1's and 0's that follow the IP header: IP Header with Protocol field highlighted

Again, without this, how would the receiving entity know to interpret those bits as an ICMP packet? It could also be TCP, or UDP, or GRE, or another IP header, or a plethora of others.

This creates a sort of protocol chain to indicate to the receiving entity how to interpret the next set of bits. Without this, the receiving end would have to use heuristics (or other similar strategy) to first identify the type of header, and then interpret and process the bits. Which would add significant overhead at each layer, and noticeable delay in packet processing.

At this point, its tempting to look at the TCP header or UDP header and point out that those headers don't have a Type or Protocol field... but recall, once TCP/UDP have interpreted the bits, it passes its payload to the application. Which undoubtedly probably has some sort of marker to at least identify the version of the L5+ protocol. For example, HTTP has a version number built into the HTTP requests: (1.0 vs 1.1).


Edit to speak to the original poster's edit:

What's wrong with a model where instead of every header identifying the next header's type, every header identifies its own type in a predetermined location (eg. in the first header byte)? Why is such a model any less desirable than the current one?

Before getting into my attempt at an answer, I think its worth noting that there is probably no definitive million dollar answer as to why one way is better or the other. In both cases, protocol identifying itself vs protocol identifying what it encapsulates, the receiving entity would be able to interpret the bits correctly.

That said, I think there are a few reasons why the protocol identifying the next header makes more sense:

#1

If the standard was for the first byte of every header to identify itself, this would be setting a standard across every protocol at every layer. Which means if only one byte is dedicated we could only ever have 256 protocols. Even if you dedicated two bytes, that caps you at 65536. Either way, it puts an arbitrary cap on the number of protocols that could be developed.

Whereas if one protocol was only responsible for interpreting the next, and even if only one byte was dedicated to each protocol identification field, at the very least you 'scale' that 256 maximum to each layer.

#2

Protocols which order their fields in such a way to allow receiving entities the option to only inspect the bare minimum to make a decision only exists if the next protocol field exists in the previous header.

Ethernet2 and "Cut-Through" switching come to mind. This would be impossible if the first (few) bytes were forced to be a protocol identification block.

#3

Lastly, I don't want to take credit, but I think @reirab's answer in the comment in the comments of the original question is extremely viable:

Because then it's effectively just the last byte of the IPv4 (or whatever lower-level protocol) header in all but name. It's a "chicken or egg" problem. You can't parse a header if you don't know what protocol it is.

Quoted with Reirab's permission

share|improve this answer
3  
Yes, and there are also extant layer-4 protocols other than TCP or UDP. IP doesn't really care which it has in its payload, including protocols not yet invented.. – Ron Maupin Feb 2 at 5:06
2  
@Levi: that looks like WireShark. – Mat Feb 2 at 11:13
1  
@Levi it's hard to understate the value of knowing Wireshark for anyone involved in networking. They put out a great set of videos from their annual conference, SharkFest, that illustrates its value and teaches a lot of advanced concepts. – Jeff Meden Feb 2 at 17:07
1  
Feel free to quote or paraphrase what I said in your answer. It probably belongs in an answer rather than a comment, but I didn't want to write yet another answer just to address that point. – reirab Feb 3 at 4:53
1  
Also, you're exactly correct about why TCP and UDP don't have a protocol/payload type field. Ethernet and IP are designed to pass their payloads to the next higher level in the OS' network stack, whereas TCP and UDP are designed to pass their payload directly to an application on a particular socket. The application already knows what protocol to expect on that socket. The OS needs to know enough to know how to route the packet to the correct destination socket, but the owner of that socket should already know what the next-higher layer protocol should be. – reirab Feb 3 at 5:00

You may as well ask why an ethernet header has an Ether Type field. The network stack needs to know which protocol in the next higher layer gets the payload of the current layer.

Edit 1:

The reason that each datagram has the protocol of the next upper layer is to create the layer independence. Each layer doesn't care what is in the payload, and it shouldn't need to look in the payload to determine where to deliver the payload. Think of the protocol number in the header as an address where the payload is to be delivered. Much like TCP port numbers are TCP addresses, they tell TCP where to deliver its payload.

The destination MAC address tells the network switch which switch interface to deliver the frame. The Ether Type field tells layer-2 where to deliver its payload, the Protocol field in the IP header tells layer-3 where to deliver its payload, and the port numbers in TCP and UDP tell layer-4 where to deliver its payload.

Think of an 18-wheeler truck driver who hooks up to a trailer to deliver it somewhere. He doesn't need to worry what's in the trailer, or for what it will be used; he just looks at his paperwork and delivers it to the place in the paperwork.

You need to remember that each of the protocols was developed independently without knowing which emerging upper-layer protocols would be used. For a long time, the primary layer-3 protocol used on ethernet was IPX. Had ethernet been created specifically for IPX, would it be so ubiquitous today? Ethernet was built to carry any layer-3 protocol by having the Ether Type field which the network stack can use to decide where the ethernet payload goes. IP does the same thing, and so do TCP and UDP. It is an easy and logical method which is why each independently-developed layer in the network stack has an equivalent. You, and anyone else interested, are free to develop your own protocol(s) for any of the layers which can easily plug into the network stack because of this.

Edit 2:

It allows different layer-3 protocols to register with layer-2. You can simultaneously run IPX (0x8137), IPv4, (0x0800), ARP (0x0806), IPv6 (0x86DD), etc. protocols, and layer-2 will know which protocols have registered with it and pass the payload to the appropriate layer-3 protocol without knowing anything about the payload (or drop any packets which don't have a registered protocol). You don't want to have to have to install a different layer-2 protocol for each combination of layer-3 protocols you have, and that would be required if the layer-2 protocol must know more about the layer-3 protocol(s) in order to be able to read the packet headers. Even IPv4 and IPv6 packet headers are quite different.

Here is an incomplete list of values for different layer-3 protocols which may register with layer-2.

Layer-4 protocols also register with various layer-3 protocols, and applications register with layer-4 protocols.

Your original question posited that the layers should be independent of each other, and this sort of thing actually promotes layer independence, rather than breaking it as you suggest. Layer-2 doesn't know that the payload is IPv4, it only knows that the ethertype is 0x0800, and it should pass the payload to the layer-3 protocol which has registered that ethertype.

share|improve this answer
1  
This. It's a programming optimization. How do you know which data structure applies without something enumerating what it is. The logical place for it is in the IP Header ("forward declaration".) Remember IP was designed in an era where computers were far less capable. – Ricky Beam Feb 2 at 1:00
4  
@RickyBeam No, it's not an optimization. It's a type ID. You can't make it part of the higher protocol's data, because then you'd need to know the protocol to decode the data - obviously, this is a bit circular :) – Luaan Feb 2 at 9:18

Not a direct answer to your question, but:

On the one hand placing a "protocol" field in the IP header breaks the conceptual separation of interests that the OSI aimed for.

TCP/IP was developed without reference to the OSI model. While they share some commonalities, it was a separate development effort.

share|improve this answer
    
Thanks. I originally used "that the OSI model aims for", which is more accurate in this context. I'll rephrase. – Docom Feb 2 at 11:16

The simplest reason, is to help parsing when a packet is received.

If you know which protocol follow, you can develop stricter constraint. The only dynamic aspect in the IP packet is the size (the presence of IP options increase this size in multiple of four bytes).

In parsing phase, you can check ip header length, protocol. Then, in the low level packet validation, the packet data is read through a data struct (usually, icmp, tcp, udp headers) and with easy packet is validated.

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.