When Raw Network Sockets Aren’t Raw: Raw Sockets in MacOS and Linux

When Raw Network Sockets Aren’t Raw: Raw Sockets in MacOS and Linux

Raw network sockets are a curious beasts, as unless you have a strong urge to implement your own low-level network protocol, it’s a topic that is probably best left to the (well-paid) experts. That said, you can totally use raw sockets in virtually every operating system, but one should be aware of a few things, the lack of portability being one of them. This is what tripped [Swagnik] up while trying to write a low-level network ping (ICMP) utility, by reading the Linux socket documentation while testing on MacOS. It’s all BSD-style sockets, after all, right?


As it turns out, the network stacks in Linux and MacOS have some subtle differences, which become apparent when you read the friendly manuals. For Linux, the raw(7) man entry for IPv4 sockets make it clear that the IP_HDRINCL socket option is default by default for IPPROTO_RAW sockets. This is different from MacOS, which is effectively FreeBSD with glossy makeup. Like FreeBSD, the MacOS man page makes it clear that the IP_HDRINCL option is not set by default.


So that’s easy, right? Just fire off a setsockopt() call on the raw socket and that’s done. Not quite. The Linux man page notes that it cannot receive all IP protocols, while the FreeBSD/MacOS version makes no such exceptions. There is also the issue of endianness, which is where [Swagnik]’s blog post seems to err. The claim is that on MacOS the received I ..

Support the originator by clicking the read the rest link below.