I've never liked the way packet sockets are exposed on any operating system though. Exposing them is such an afterthought that the only way to use them is to basically act like the rest of the networking system plain doesn't exist. I shouldn't have to have raw network permissions to send and receive any packet just to be able to mark that I want to send and receive e.g. LLDP (or, on Windows, make a driver that even allows me a way to send such packets from user space in the first place). Operating systems truly offer "TCP/IP" (and UDP and maybe a few other select protocols, depending what you load) stacks not "network stacks" which give you access to each piece equally. Even plain raw IP sockets are increasingly ignored.
/rant of a network guy.
You need privileges to open a raw socket (or a packet socket, or anything else that would let you program at the IP layer) because otherwise unprivileged processes could hijack traffic for other applications on the system.
All of that aside, none of this would explain why I need to write a custom network driver in Windows to send more than a couple predefined ethertypes from user space at all or why, in Linux, the network filter layer can't apply to any family used in the sendto() syscall instead of just sendto() calls with AF_INET set. These kinds of decisions aren't rooted in a limited scope of what packet sockets can be for or how they must interact with the rest of the network stack, it's just how they are currently built and exposed. This is great if your use case is to ignore the OS stack, but that doesn't mean doing so is the only conceivable way of packet sockets being built.
If BPF were treated slightly differently in terms of how/when certain abilities were exposed it could be a great answer to all of this. As of right now, it's just a better way to ignore the OS network stack even more than normal though.
It's a similar story in the ARP use case you mention when maybe you want to e.g. anonymously probe if a VIP is actively in use by using a 0.0.0.0 source (useful for redundant responder setups). DHCP and ICMP I could see the case for similar improvements to the RAW IP sockets (AF_INET in Linux) type as packet sockets (e.g. ability to request and permit limited scope sockets or the other enhancements mentioned above). Just that is still too limited though as the world has more than IP protocols, e.g. AF_INET gets you OSPF but not ISIS.
The idea that "no, you can't possibly mean you'd like to send Ethernet packets while still caring about what the rest of the OS network stack is doing as if you mean to just extend it instead of take its place" is precisely the issue I've found myself annoyed with. No, I don't want to use DPDK to make a custom IP forwarding stack, I just want to be registered as the app to send and receive a certain EtherType without saying I want full rights to all packets.
On the other hand, you might take away from this that the near universal limitation on first-class programmatic access to raw Ethernet (or even raw IP) has constrained the evolution of the protocols themselves --- if it were easier to code directly to IP rather than to UDP or TCP, we might have a greater diversity of IP protocols. And that might not be a good thing! We might have benefited from how clunky the socket interface is. :)
Host-based firewalls are, indeed, fake firewalls, and it's unfortunate that they chose to use the same term for functions that superficially look like they do the same thing, but are way less effective, and encourage bad network design.
The classic architecture for security was: edge router -> firewall -> DMZ -> bastion -> DMZ -> office router
You could put more firewalls, and switches and stuff, in there, but it is really important to have a bastion host as a chokepoint in the DMZ. You could have an IPS doing this instead. Or you could have a proxy server such as SOCKS.
But your firewall is pretty far away from any host that could get bright ideas about messing with it. (Because it is possible for client hosts to mess with router "firewall" settings via UPnP.)
This collapsing of topology also happens with other stuff, like NIDS/HIDS intrusion detection. Yeah, IDS can be more effective in certain ways when it has access to host-based logs and resources. But it's different than an isolated IDS listening on a TAP/SPAN where nobody logs into it and doomscrolls Facebook.
The ISC DHCP server though listens for raw packets and thus completely by-pass the netfilter rules.
This is similar to how you can use wireshark to see raw packets received on the physical port, before any filtering.
Any Linux process running with CAP_NET_RAW can by-pass the firewall in such a way, this includes your typical DHCP server running as root.
The question then should be why is ISC DHCP server using raw sockets? That is probably because DHCP sits in-between OSI layers, it bridges the gap between the mac address world and IP address world.
I'm not sure of the exact technical reason though. The linked SO answers talk about some case where NAT rules could be altering packets, not sure how common NAT+DHCP is used...
In the case of a DHCP client, you do need raw sockets because the Linux IP layer will not let a normal socket send packets with a NULL IP source address.
I don’t know much about Linux network stack, but probably it’s because DHCPDISCOVER messages sent to ff:FF:FF:FF:FF:FF, and Linux network driver only accepts frames sent to the interface address? Not sure if that’s true though.
There is an ISC dhcp article here with more info on why they need it: https://kb.isc.org/docs/aa-00379
But I just thought about it some more.. In a normal unix socket, you don't set the destination mac address when sending a packet. You just set the destination IP address and the kernel figures out the destination MAC address using a static, cached or dynamic ARP lookup.
But since the dhcp client has not been assigned the IP yet, ARP would fail.
The DHCP server would need to set a static ARP entry before sending the response, and hope the kernel properly fills the destination MAC. This causes more problems..
Its much easier and reliable to just craft the exact headers required as-per the RFC, especially in a cross-platform piece of software like the ISC dhcp server.
Applications such as tcpdump and dhcp require special privileges to open raw sockets. Note that ebtables (and now by extension nftables) can be used to operate at this level.
All of these major Linux firewall features have been around for over two decades and the use of multi-stage rule routing with filters is day-to-day for anyone in network ops. Cisco switches I messed with in the 90s had DHCP helpers for relaying packets across VLANs among other similar features. FTP helpers were extremely common before SSL/TLS/sftp became standard due to NAT and how the port directions work in that protocol.