#pragma once #include #include struct ICMPType { enum { EchoReply = 0, EchoRequest = 8, }; }; class [[gnu::packed]] ICMPHeader { public: ICMPHeader() {} ~ICMPHeader() {} u8 type() const { return m_type; } void set_type(u8 b) { m_type = b; } u8 code() const { return m_code; } void set_code(u8 b) { m_code = b; } u16 checksum() const { return m_checksum; } void set_checksum(u16 w) { m_checksum = w; } const void* payload() const { return this + 1; } void* payload() { return this + 1; } private: u8 m_type { 0 }; u8 m_code { 0 }; NetworkOrdered m_checksum { 0 }; // NOTE: The rest of the header is 4 bytes }; static_assert(sizeof(ICMPHeader) == 4); struct [[gnu::packed]] ICMPEchoPacket { ICMPHeader header; NetworkOrdered identifier; NetworkOrdered sequence_number; void* payload() { return this + 1; } const void* payload() const { return this + 1; } };