365 Days of Code - Day 050

Project Status

ProjectLanguageStatusDue DateLatest Update
Personal WebsiteHugoOngoingNoneThe site is live. Continuous improvements ongoing.
Laravel From ScratchLaravel (PHP)In-Progress2026-03-31Episode 8
PRMLaravel (PHP)In-Progress2026-03-31Working alongside other Laravel projects.
Client Website (J.L.)Laravel (PHP)In-Progress2026-03-31Working alongside other Laravel projects.
Project EulerCOngoingNoneWorking on P25. BigInt (AI gen) was a waste of time, need to rewrite
Practice JavaJavaPausedNoneInstalled, need to find a good project.
Practice PythonPythonPausedNoneInstalled, need to find a good project.
Learn GoGoPausedNoneInstalled, work on LDAP Injector from ippsec.
Learn RustRustHaven’t StartedNoneInstalled, will try network protocols after finishing in C and Zig.
Learn ElixirElixirHaven’t StartedNoneInstalled, need a good tutorial project.
Learn HaskellHaskellHaven’t StartedNoneInstalled, need a good tutorial project.
Learn ZigZigHaven’t StartedNoneInstalled, will try network protocols after finishing in C.
Linux+N/AIn-Progress2026-03-31Reading Chapter 4.
Cyber Quest 2026N/AIn-Progress2026-02-28Finished quiz 1 with 75%.
Operating SystemsN/AIn-Progress2026-03-31Reading Chapter 4: Abstraction
Grey-Hat HackingVariousIn-Progress2026-03-31Reading Chapter 8: Threat Hunting Lab
PHP Time TrackerPHPBeta FinishedNoneWorking on a basic level.
HTTP Status Code ReaderCComplete2026-02-18Complete.
ZSH Configurationbash/zshCompleteNoneSort of an ongoing process, but complete for now. Works good.
Network ProtocolsCIn-ProgressNoneWorking on V3, implementing IPv6.
Discinox WebsiteHTML, CSS, JSComplete2026-03-04The site is live.
DiroffTech WebsiteHTML, CSS, JSComplete2026-03-05The site is live. git-lfs needs to be initialized for images.
Automate BackupsbashComplete2026-03-08Backups done.

Ambiguities in RFC Language

While reimplementing my ICMP code for IP Protocol From Scratch (opens in a new tab), I spent some time (re)reading RFC 792 (opens in a new tab) for ICMP. I came across some interesting language used in the Echo or Echo Reply Message section.

plaintext
<snip>
Code

      0
<snip>
Identifier

      If code = 0, an identifier to aid in matching echos and replies,
      may be zero.

Sequence Number

      If code = 0, a sequence number to aid in matching echos and
      replies, may be zero.
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
<snip>
Code

      0
<snip>
Identifier

      If code = 0, an identifier to aid in matching echos and replies,
      may be zero.

Sequence Number

      If code = 0, a sequence number to aid in matching echos and
      replies, may be zero.

The specification clearly states that the code value for an Echo request or Echo Reply message is 0. However, both the Identifier and Sequence Number fields clearly state, “If code = 0…”. Which implies that the code doesn’t have to be 0. Since the code field is 8 bits, we could potentially have values from 0 to 255.

I did some research on this, first with Gemini:

Jon Postel likely included “If code = 0” as a defensive programming note, leaving the door cracked open for future protocol expansions that never ended up happening. In the 40+ years since RFC 792 was published, the Internet Assigned Numbers Authority (IANA) has never assigned a code other than 0 for ICMP Type 8 (Echo) or Type 0 (Echo Reply). Mathematically, you could fit 255 other values in that 8-bit space, but mathematically they mean absolutely nothing to the protocol. Because no valid Echo message ever uses a code other than 0, hackers and malware authors historically realized they could use codes 1-255 to secretly pass data past firewalls in a technique known as ICMP Tunneling. Today, if you send an ICMP Echo packet with Code = 9 (or anything other than 0), modern Intrusion Detection Systems (like Snort or Suricata) and strict OS kernels will instantly flag it as a covert channel or a malformed packet, and drop it.

ICMP Tunneling

This is an interesting concept. Because ICMP is typically not blocked or inspected deeply, you can encapsulate data into the ICMP payload to infiltrate a network or exfiltrate data out of a network. I think this is most easily shown by the application icmptunnel (opens in a new tab). icmptunnel has been successfully used to bypass captive portals, bypass firewalls and establish an encrypted communication channel.

‘icmptunnel’ works by encapsulating your IP traffic in ICMP echo packets and sending them to your own proxy server. The proxy server decapsulates the packet and forwards the IP traffic. The incoming IP packets which are destined for the client are again encapsulated in ICMP reply packets and sent back to the client. The IP traffic is sent in the ‘data’ field of ICMP packets.

ICMP Header

To preserve the default condition for the ICMP code value, I will be defining a macro that is 0. However, this value will be configurable by the user.

  • icmpv4.h
c
/***
 * @file icmpv4.h
 * @brief RFC implementation of the ICMP protocol
 *
 * @note ICMP is the historical name. ICMPv4 is a retronym. Modified to make it
 * distinct from ICMPv6.
 *
 * ICMP: RFC 792
 *
 * @todo Add additional ICMP message types and fields (i.e. Destination Unreachable)
 */
#ifndef ICMPV4_H
#define ICMPV4_H

#include <stdint.h>

/**
 * @brief Standard code for Echo Request/Reply.
 * @note May be overridden by the user for security auditing (e.g., ICMP tunneling).
 */
#define ICMP_V4_ECHO_CODE 0

/**
 * @enum icmp_v4_message_type
 * @brief ICMPv4 message type field identifiers
 */
enum icmp_v4_message_type
{
    ICMPV4_ECHO_REPLY = 0,
    ICMPV4_ECHO = 8
};

/**
 * @struct icmp_v4_header
 * @brief ICMPv4 header (type/code/checksum), packed wire layout. Required for all ICMPv4 packets.
 */
struct icmp_v4_header
{
    uint8_t type;      /**< Message type */
    uint8_t code;      /**< Message code */
    uint16_t checksum; /**< ICMP checksum of ICMP header + ICMP data (ones' complement) */
} __attribute__((packed));

/**
 * @struct icmp_v4_echo
 * @brief ICMPv4 Echo message fixed fields, packed wire layout.
 */
struct icmp_v4_echo
{
    uint16_t id;       /**< Session identifier */
    uint16_t sequence; /**< Sequence number */
} __attribute__((packed));

#endif /* ICMPV4_H */
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
/***
 * @file icmpv4.h
 * @brief RFC implementation of the ICMP protocol
 *
 * @note ICMP is the historical name. ICMPv4 is a retronym. Modified to make it
 * distinct from ICMPv6.
 *
 * ICMP: RFC 792
 *
 * @todo Add additional ICMP message types and fields (i.e. Destination Unreachable)
 */
#ifndef ICMPV4_H
#define ICMPV4_H

#include <stdint.h>

/**
 * @brief Standard code for Echo Request/Reply.
 * @note May be overridden by the user for security auditing (e.g., ICMP tunneling).
 */
#define ICMP_V4_ECHO_CODE 0

/**
 * @enum icmp_v4_message_type
 * @brief ICMPv4 message type field identifiers
 */
enum icmp_v4_message_type
{
    ICMPV4_ECHO_REPLY = 0,
    ICMPV4_ECHO = 8
};

/**
 * @struct icmp_v4_header
 * @brief ICMPv4 header (type/code/checksum), packed wire layout. Required for all ICMPv4 packets.
 */
struct icmp_v4_header
{
    uint8_t type;      /**< Message type */
    uint8_t code;      /**< Message code */
    uint16_t checksum; /**< ICMP checksum of ICMP header + ICMP data (ones' complement) */
} __attribute__((packed));

/**
 * @struct icmp_v4_echo
 * @brief ICMPv4 Echo message fixed fields, packed wire layout.
 */
struct icmp_v4_echo
{
    uint16_t id;       /**< Session identifier */
    uint16_t sequence; /**< Sequence number */
} __attribute__((packed));

#endif /* ICMPV4_H */

Related content