5 ms·
This is interesting, but falls just short of explaining what's going on. Why does UDP work for ICMP? What does the final packet look like, and how is ICMP diffe
by stavros 11mo ago
This is interesting, but falls just short of explaining what's going on. Why does UDP work for ICMP? What does the final packet look like, and how is ICMP different from UDP? None of that is explained, it's just "do you want ICMP? Just use UDP" and that's it.
It would have been OK if it were posted as a short reference to something common people might wonder about, but I don't know how often people try to reimplement rootless ping.
- vbezhenar 11mo agoICMP is just different protocol from UDP. There's field "Protocol" in IP packet. 0x01 = ICMP, 0x06 = TCP, 0x11 = UDP. I think that this article gets terminology wrong. It's not UDP socket that gets created here, but Datagram socket. Seems to be bad API naming in Rust library.
- stavros 11mo ago> It's not UDP socket that gets created here, but Datagram socket A datagram socket is a UDP socket, though. That's what the D stands for.
- jmgao 11mo agoWrong way around: UDP sockets are datagram sockets, there are datagram sockets that are not UDP.
- jdndbdbd 11mo agoNo? Why would you think a datagram socket is UDP?
- stavros 11mo agoWhat a reasonable question to be asked today.
- messe 11mo agoWhat networks are you using without ICMP? Presumably you're also using systems that don't support Unix Domain Sockets which can be configured as SOCK_STREAM, SOCK_DGRAM, and even gasp SOCK_SEQPACKET (equivalent to SOCK_DGRAM in this case admittedly).
- cstrahan 11mo agoLet me rephrase GP into (I hope) a more useful analogy. — actually, here’s the whole analogous exchange: “A rectangle is an equal-sided rectangle (i.e. “square”) though. That’s what the R stands for.” “No? Why would you think a rectangle is a square?” Just as not all rectangles are squares (squares are a specific subset of rectangles), not all datagram protocols are UDP (UDP is just one particular datagram protocol).
- stavros 11mo agoThe obvious answer is "I didn't know datagrams were a superset of UDP". I don't really understand how "how do you not know this" is a reasonable or useful question to ask.
- Quarrel 11mo agoTo give a more nuanced reply versus the "you're wrong" ones already here, the difference is that UDP adds send and receive ports, enabling most modern users (& uses) of UDP. Hence, it is the "User" datagram protocol. (it also adds a checksum, which used to be more important than it is nowadays, but still well worth it imho.)
- meindnoch 11mo agoNot every cola is Coca-Cola, even though "Cola" stands for cola.
- pwdisswordfishy 11mo agoIn related news, all rectangles are squares and all animals are dogs.
- dgl 11mo agoThe BSD socket API has 3 parameters when creating a socket with socket(), the family (e.g. inet) the kind (datagram in this case) and the protocol (often 0, but IPPROTO_ICMP in this case). Because when the protocol is 0 it means a UDP socket Rust has called its API for creating any(?) datagram sockets UdpSocket, partly resulting in this confusion. The kernel patch introducing the API also explains it was partly based on the UDP code, due to obviously sharing a lot of properties with it. https://lwn.net/Articles/420800/ https://lwn.net/Articles/420800/
- stavros 11mo agoThanks, that's quite the misnomer then.
- erk__ 11mo agoThe std api can only create UdpSockets, the trick here is that you use Socket2 which allows more kinds of sockets and then you tell UdpSocket that some raw file descriptor is a upd socket through a unsafe api with no checks and I guess it works because they use the same api on posix. Edit: It is possible in safe rust as well, see child comment. The macro used by socket2: https://docs.rs/socket2/0.6.1/src/socket2/lib.rs.html#108 https://docs.rs/socket2/0.6.1/src/socket2/lib.rs.html#108 The FromRawFd trait: https://doc.rust-lang.org/stable/std/os/fd/trait.FromRawFd.html https://doc.rust-lang.org/stable/std/os/fd/trait.FromRawFd.h...
- stingraycharles 11mo ago
- slugonamission 11mo agoSo in fairness, this doesn't actually use UDP at all (SOCK_DGRAM does not mean UDP!). The actual protocol in use, and what's supported, it matched by all of the address family (IPV4), the socket type (DGRAM), and the protocol (ICMP). The match structure for IPV4 is here in Linux at least: https://elixir.bootlin.com/linux/v6.18/source/net/ipv4/af_inet.c#L1155 https://elixir.bootlin.com/linux/v6.18/source/net/ipv4/af_in... So ultimately, it's not even UDP, it's just creating a standard ICMP socket.
- the8472 11mo agoThe semantic wrappers around file descriptors (File, UdpSocket, PidFd, PipeReader, etc.) are advisory and generally interconvertible. Since there's no dedicated IcmpSocket they're using UdpSocket which happens to provide the right functions to invoke the syscalls they need.
- jeroenhd 11mo agoThe rust API in use lets you feed an fd into a UdpSocket which calls the necessary send/recv/etc on it. The socket itself is an ICMP socket, but the ICMP shaped API just happened to fit into the UDP shaped hole. I'm sure some advanced UDP socket options will break or have weird side effects if your code tries to apply them.