This is literally what iputils' ping.c does on Linux: open an IPPROTO_ICMP raw socket, fill type/code/id/sequence, and checksum the result before sending. Getting the checksum wrong is not academic — nmap's -PE host discovery and countless CTF pwn challenges hinge on crafting a byte-perfect ICMP echo that a real kernel will accept.