Why has sending ICMP echo requests traditionally required a raw socket and elevated privilege, and what do unprivileged ICMP echo sockets change?
answer
- ICMP has no ports
- build header and checksum yourself
- raw sockets can forge anything
- kernel-assigned identifier
basics
~20 sICMP has no ports, so transport sockets cannot send it; classic ping built echo packets on a raw socket, which systems restrict because it can forge any packet. Unprivileged echo sockets let the kernel own identifier and checksum, allowing only echo.
solid answer
~40 sThe ordinary socket API exposes TCP and UDP endpoints addressed by port, and ICMP (IP protocol `1`) has neither ports nor a transport layer to build its header. So a classic ping opened a raw IP socket, wrote type `8`, the `Identifier`, `Sequence Number`, data and checksum itself, and filtered its own replies out of every ICMP message the stack copied to it. Raw sockets can forge arbitrary headers and read others' ICMP, so systems reserve them for privileged processes and ping binaries ran with elevated rights. Some systems, Linux for example, now offer an unprivileged datagram ICMP socket limited to echo: the kernel assigns the identifier like a port, computes the checksum and delivers only matching replies. In a sandbox that has neither, echo fails for a permission reason, not a network one.
go deeper
Recall that ICMP has no ports, so ping cannot use an ordinary TCP or UDP socket, and that classic ping needed elevated privilege for that reason.
Explain what a raw-socket prober builds itself, why it filters replies by identifier, and what the kernel takes over in an unprivileged echo socket.
Diagnose echo failing inside restricted environments as a sender permission problem, and argue for unprivileged echo sockets over privileged binaries on least-privilege grounds.
Set policy on raw-socket privilege across a platform: which workloads truly need packet crafting, and how probing and health checks should work without granting it.
## Why ICMP does not fit the ordinary socket model The everyday socket interface hands applications **transport** endpoints: a TCP connection or a UDP socket, both addressed by **port**. ICMP (IP protocol `1`) is not a transport protocol and has no ports. There is nothing to bind an echo session to, and the transport layer will not build an ICMP header for you. RFC 1122 §3.2.2.6 says a host SHOULD offer an application-layer interface for sending echo requests and receiving replies, but leaves how to the implementation. ## The classic answer: a raw socket Historically the interface was a **raw IP socket** for protocol `1`, in the classic socket API that most systems share. With it the program does the work the transport layer would otherwise do: 1. Build the ICMP header itself: type `8`, code `0`, its chosen `Identifier` and `Sequence Number`, and the data. 2. Compute the 16-bit ones'-complement **checksum** over the ICMP message. 3. Hand the result to the IP layer, which adds the IPv4 header. 4. Read **every** incoming ICMP message the stack copies to raw ICMP sockets, and pick out its own replies by type `0` and the identifier it chose. That last step explains a classic convention: the identifier was commonly derived from the process ID so that two probers running at once could each filter out the other's replies. It also explains why the prober can report the reply's TTL — on an IPv4 raw socket the received data typically includes the IP header. ## Why raw sockets are privileged A raw socket lets a program write arbitrary protocol headers and read traffic it did not originate: - forge ICMP messages of any type, including error messages aimed at other connections; - craft packets with spoofed source addresses; - observe all ICMP arriving at the host, including other users' probes. So most operating systems reserve raw sockets for administrators or a specific granted privilege, as an implementation policy. Ping programs were therefore installed with elevated privilege (set-user-ID or a narrowly granted capability) so ordinary users could run them — at the cost of a privileged binary parsing untrusted network input. ## The modern alternative: an unprivileged ICMP echo socket Several operating systems now offer a **datagram-style ICMP socket** restricted to echo, as an implementation feature — Linux, for example, provides one that an administrator can enable for chosen user groups. Its rules change who does what: | Task | Raw socket | Unprivileged echo socket | |---|---|---| | Privilege needed | Administrator or granted capability | None beyond the allowed group | | Messages it may send | Any ICMP type | Echo requests only | | Who sets the `Identifier` | The program | The kernel, like an ephemeral port | | Who computes the checksum | The program | The kernel | | Replies delivered | Copies of all incoming ICMP | Only traffic for this socket's identifier | The kernel treats the identifier exactly as RFC 792 suggested — like a port — and demultiplexes replies itself, so one user's probes cannot see or forge another's. ## Consequences you meet in practice - **Least privilege**: an unprivileged echo socket removes a privileged binary from the system, and it lets processes running without raw-socket privilege still send echo requests. - **Restricted environments**: a sandbox or container that drops raw-socket privilege and has no unprivileged echo socket enabled cannot send echo at all, even though TCP connections work — so a failing echo there may be a permission problem on the sender, not a network fault. - **Fallback probes**: tools that cannot open either kind of ICMP socket often probe with a TCP connection attempt instead, which needs no privilege but tests a port, not ICMP. - **Identifiers are not yours**: with the kernel choosing identifiers, a program cannot rely on a fixed identifier value, and must match on what the socket reports. IPv6 uses the same split for ICMPv6 Echo Request `128` and Echo Reply `129` (RFC 4443).
- On a raw ICMP socket, how does a prober avoid treating another prober's replies as its own?Every raw ICMP socket typically receives a copy of each incoming ICMP message, so the program must filter. It checks for type 0 and for the identifier it put in its requests, then uses the sequence number to pair each reply with a probe. The classic convention of deriving the identifier from the process ID exists to keep concurrent probers distinct.
- Why is a privileged ping binary itself a security concern?Granting raw-socket privilege to a widely runnable program means a parser of untrusted network input runs with powers ordinary users lack. A memory-safety bug in reply handling could then let any local user escalate. Unprivileged echo sockets remove that by moving header construction, checksum and demultiplexing into the kernel and confining the program to echo.
saying these in an interview costs you the question
- Any user process may craft raw ICMP packets without special privilege.
- Ping sends its echo request through a UDP socket to a well-known port.
- A raw ICMP socket only receives replies to its own requests.
- If echo fails inside a sandbox, the network path must be broken.