stm32plus::net, ICMP Module

The Internet Control Message Protocol (ICMP) is one of the core transport protocols in the IP stack. It’s used to convey error messages between systems and to debug and probe network topology. It does not carry user data, unless you could describe the content of an echo request as user data but that would be stretching it a bit.

ICMP is often documented to be in the Network layer of the stack, however it requires IP to transport its messages and it certainly is a transport so I include it here in the transport layer.

ICMP is optional. You can get by without it and in this day and age many firewalls block it completely due to its ability to probe the existence of hosts which tends to limit its overall use to LANs. In the sensitive environments that I have worked ICMP has always been blocked to some extent; sometimes at the border of the local VLAN and always at the WAN level.

ICMP implementation

ICMP operates in the background and you don’t have to do anything to keep it running. Error messages and ping responses (if enabled) are generated automatically by IRQ code.

ICMP has no compile-time parameters, you can include it by adding its module name to your transport layer configuration like this:

typedef TransportLayer<Icmp> MyTransportLayer;

Note that this code fragment only shows Icmp in the transport layer. In practice a useful transport layer will include more than just ICMP.

Configuration Parameters

The following parameters are made available in the stack’s configuration object for customisation:

// true to respond to ping requests, default is true
bool icmp_enableEchoReply;  

The icmp_enableEchoReply parameter allows you to control whether the stack responds to echo requests (pings). Ping responses are the part of ICMP that gives the largest security issues and this switch gives you the ability to disable them while still keeping the error reporting features.

Methods exposed

bool icmpSendEchoRequest(const IpAddress& ipaddress,
                         uint16_t sequenceNumber,
                         const uint8_t *data,
                         uint32_t dataSize,
                         uint8_t ttl=0);

Just a single method is exposed by the ICMP module. icmpSendEchoRequest() allows the caller to send an echo request, commonly known as a ‘ping’ to a remote address. You are allowed to specify the sequence number, some data and a TTL value for the IP packet that carries the echo request.

If you specify zero for the ttl parameter then the default value configured into the IP module is used. This method returns as soon as the IP packet has been submitted to the MAC and does not wait for an echo reply.

Events raised

sender NetworkReceiveEventSender
event IcmpPacketEvent
identifier NetEventType::ICMP_PACKET
context IRQ
purpose ICMP packet received
		/**
		 * Event descriptor for an ICMP packet arrival
		 */

		struct IcmpPacketEvent : NetEventDescriptor {

			/**
			 * The IP packet reference
			 */

			IpPacket& ipPacket;


			/**
			 * The ICMP packet data encapsulated in the above packet
			 */

			IcmpPacket& icmpPacket;


			/**
			 * Constructor
			 * @param icmp The ICMP packet
			 * @param ip The IP packet holding the ICMP packet
			 */

			IcmpPacketEvent(IcmpPacket& icmp,IpPacket& ip)
				: NetEventDescriptor(NetEventType::ICMP_PACKET),
					ipPacket(ip),
					icmpPacket(icmp) {
			}
		};