Core routers don't inspect that field, NAT/ISP boxes can. I believe that with two suitable dedicated linux servers it is very possible to send and receive single custom IP packet between them even using 253 or 254 (= Use for experimentation and testing [RFC3692]) as the protocol number
To save a skim (though it's an interesting list!), protocol codes 253 and 254 are suitable "for experimentation and testing".
There is sometimes drama with it, though. Awhile back, the OpenBSD guys created CARP as a fully open source router failover protocol, but couldn't get an official IP number and ended up using the same one as VRRP. There's also a lot of historical animosity that some companies got numbers for proprietary protocols (eg Cisco got one for its then-proprietary EIGRP).
I do hope we'll have stopped using IPv4 by then... But well, a decade after address exhaustion we are still on it, so who knows?
It uses them a little differently -- in IPv4, there is one protocol per packet, while in IPv6, "protocols" can be chained in a mechanism called extension headers -- but this actually makes the problem of number exhaustion more acute.
You left out ICMP, my favourite! (And a lot more important in IPv6 than in v4.)
Another pretty well known protocol that is neither TCP nor UDP is IPsec. (Which is really two new IP protocols.) People really did design proper IP protocols still in the 90s.
> Can I just make up a packet and send it to a host across the Internet?
You should be able to. But if you are on a corporate network with a really strict firewalling router that only forwards traffic it likes, then likely not. There are also really crappy home routers which gives similar problems from the other end of enterpriseness.
NAT also destroyed much of the end-to-end principle. If you don't have a real IP address and relies on a NAT router to forward your data, it needs to be in a protocol the router recognizes.
Anyway, for the past two decades people have grown tired of that and just piles hacks on top of TCP or UDP instead. That's sad. Or who am I kidding? Really it's on top of HTTP. HTTP will likely live on long past anything IP.
Not necessarily. Many protocols can survive being NATed if they don't carry IP/port related information inside their payload. FTP is a famous counterexample - it uses a control channel (TCP21) which contains commands to open data channels (TCP20), and those commands specify IP:port pairs, so, depending on the protocol, a NAT router has to rewrite them and/or open ports dynamically and/or create NAT entries on the fly. A lot of other stuff has no need for that and will happily go through without any rewriting.
TCP and UDP have port numbers that the NAT software can extract and keep state tables for, so we can send the return traffic to its intended destination.
For unknown IP protocols that is not possible. It may at best act like network diode, which is one way of violating the end-to-end principle.
The end-to-end principle at the IP layer (i.e. having the IP forwarding layer be agnostic to the transport layer protocols above it) is still violated.
A part of the problem with UDP is the lack of good platforms and tooling. Examples as well. I’m trying to help with that, but it’s an uphill battle for sure.
Some of this is hurt by the fact that v8, Node's runtime, has had first class JSON parsing support in but no support for binary protocol parsing. So writing Javascript to parse binary protocols is a lot slower than parsing JSON.
Even ICMP has a hard time traversing NATs and firewalls these days, for largely bad reasons. Try pinging anything in AWS, for example...
If any host is firewalling out ICMP then it won't be pingable but that does not depend on the hosting provider. AWS is no better or worse than any other in that regard, IME.
They absolutely don't. Routers are layer 3 devices; TCP & UDP are layer 4. The only impact is that the ECMP flow hashes will have less entropy, but that's purely an optimization thing.
Note TCP, UDP and ICMP are nowhere near all the protocols you'll commonly see on the internet — at minimum, SCTP, GRE, L2TP and ESP are reasonably widespread (even a tiny fraction of traffic is still a giant number considering internet scales).
You can send whatever protocol number with whatever contents your heart desires. Whether the other end will do anything useful with it is another question.
Idealized routers are, yes.
Actual IP paths these days usually involve at least one NAT, and these will absolutely throw away anything other than TCP, UDP, and if you're lucky ICMP.
And note the GP talked about "intermediate routers". That's the ones in a telco service site or datacenter by my book.
You might have more luck with an IPv6 packet.
Classic congestion control is done on the sender alone. The router's job is simply to drop packets when the queue is too large.
Maybe the router supports ECN, so if there's a queue going to the next hop, it will look for protocol specific ECN headers to manipulate.
Some network elements do more than the usual routing work. A traffic shaper might have per-user queues with outbound bandwidth limits. A network accelerator may effectively reterminate TCP in hopes of increasing acheivable bandwidth.
Often, the router has an aggregated connection to the next hop, so it'll use a hash on the addresses in the packet to choose which of the underlying connections to use. That hash could be based on many things, but it's not uncommon to use tcp or udp port numbers if available. This can also be used to chose between equally scored next hops and that's why you often see several different paths during a traceroute. Using port numbers is helpful to balance connections from IP A to IP B over multiple links. If you us an unknown protocol, even if it is multiplexed into ports or similar (like tcp and udp), the different streams will likely always hash onto the same link and you won't be able to exceed the bandwidth of a single link and a damaged or congested link will affect all or none of your connections.
If middleware decides to do packet inspection, it better make sure that any behavioral differences (relative to not doing any inspection) is strictly an optimization and does not impact the correctness of the link.
Also, although I'm not a network operator by any stretch, my understanding is that TCP congestion control is primarily a function of the endpoints of the TCP link, not the IP routers along the way. As Wikipedia explains [0]:
> Per the end-to-end principle, congestion control is largely a function of internet hosts, not the network itself.
A bunch of multicast stuff (IGMP, PIM)
A few routing protocols (OSPF, but notably not BGP which just uses TCP, and (usually) not MPLS which just goes over the wire - it sits at the same layer as IP and not above it)
A few VPN/encapsulation solutions like GRE, IP-in-IP, L2TP and probably others I can't remember
As usual, Wikipedia has got you covered, much better than my own recollection: https://en.wikipedia.org/wiki/List_of_IP_protocol_numbers
Behind a NA(P)T, you can obviously only use those protocols that the translator knows how to remap ports for.
As soon as you start thinking about having multiple services on a host you end up with the idea of having a service id or "port"
UDP or UDP Lite gives you exactly that at the cost of 8 bytes, so there's no real value in not just putting everything on top of UDP
*The protocol.
QUIC is still "their own protocol", just implemented as another protocol nested inside a UDP envelope, the same way that HTTP is another protocol typically nested inside a TCP connection. It makes some sense that they'd piggyback on UDP, since (1) it doesn't require an additional IP protocol header code to be assigned by IANA, (2) QUIC definitely wants to coexist with other services on any given node, and (3) it allows whatever middleware analyses that exist for UDP to apply naturally to QUIC applications.
(Regarding (3) specifically, I imagine NAT in particular requires cooperation from residential gateways, including awareness of both the IP and the TCP/UDP port. Allowing a well-known outer UDP header to surface port information, instead of re-implementing ports somewhere in the QUIC header, means all existing NAT implementations should work unchanged for QUIC.)
Some people here will argue that it actually really is, and that everybody experiencing issues is just on a really weird connection or using broken hardware, but those weird connections and bad hardware make up the overwhelming majority of Internet connections these days.
Most firewalls will drop unknown IP protocols. Many will drop a lot of TCP; some drop almost all UDP. This is why so much stuff runs over tcp ports 80 and 443; it's almost always open. QUIC/HTTP/3 encourages opening of udp/443, so it's a good port to run unrelated things over too.
Also, given that SCTP had similar goals to QUIC and never got much deployment or support in OSes and NATs and firewalls and etc. It's a clear win to just use UDP and get something that will just work on a large portion of networks.
Additionally, firewalls are also designed to filter out any weird packets. If the packet doesn't look like you wanted to receive it, it's dropped. It usually does this by tracking open ports just like NAT, therefore many firewalls also don't trust custom protocols.
There are many routers that don't care at all about what's going through them. But there aren't any firewalls that don't route anymore (not even at the endpoints).
(It's absolutely worth reading some of those old April Fools' RFCs, by the way [0]. I'm a big fan of RFC 7168, which introduced HTTP response code 418 "I'm a teapot".)
[0]: https://en.wikipedia.org/wiki/April_Fools%27_Day_Request_for...