One fun way to convince yourself that the Linux kernel handles it directly is to observe the kernel settings for it with:
tail /proc/sys/net/ipv4/icmp*
which might output something like:
==> /proc/sys/net/ipv4/icmp_echo_enable_probe <==
0
==> /proc/sys/net/ipv4/icmp_echo_ignore_all <==
0
==> /proc/sys/net/ipv4/icmp_echo_ignore_broadcasts <==
1
==> /proc/sys/net/ipv4/icmp_errors_use_inbound_ifaddr <==
0
==> /proc/sys/net/ipv4/icmp_ignore_bogus_error_responses <==
1
==> /proc/sys/net/ipv4/icmp_msgs_burst <==
50
==> /proc/sys/net/ipv4/icmp_msgs_per_sec <==
1000
==> /proc/sys/net/ipv4/icmp_ratelimit <==
1000
==> /proc/sys/net/ipv4/icmp_ratemask <==
6168
This already indicates that ICMP is handled by the kernel, since /proc/sys
is a special filesystem used to configure and inspect kernel state: What is in /dev, /proc and /sys?
Next, if you connect 2 computers on the same LAN behind a typical home modem router, and then you manage to ping
from computer A to computer B with something like:
ping 192.168.1.102
you can then go on computer B and turn off ping replies with:
echo 1 | sudo tee /proc/sys/net/ipv4/icmp_echo_ignore_all
and as soon as you do that, ping
from computer A will start to fail. And to re-enable:
echo 0 | sudo tee /proc/sys/net/ipv4/icmp_echo_ignore_all
So we were able to directly control ICMP just by talking to the kernel.
References to icmp_echo_ignore_all
can be seen in the kernel code pointed to by Ruslan in a comment https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/net/ipv4/icmp.c?id=24cac7009cb1b211f1c793ecb6a462c03dc35818#n935
static bool icmp_echo(struct sk_buff *skb)
{
struct net *net;
net = dev_net(skb_dst(skb)->dev);
if (!net->ipv4.sysctl_icmp_echo_ignore_all) {
struct icmp_bxm icmp_param;
icmp_param.data.icmph = *icmp_hdr(skb);
icmp_param.data.icmph.type = ICMP_ECHOREPLY;
icmp_param.skb = skb;
icmp_param.offset = 0;
icmp_param.data_len = skb->len;
icmp_param.head_len = sizeof(struct icmphdr);
icmp_reply(&icmp_param, skb);
}
/* should there be an ICMP stat for ignored echos? */
return true;
}
Tested with two Ubuntu 23.10 machines running Linux 6.5.0 connected on a home wireless LAN.
/var/log/messages
,/var/log/boot.log
- https://www.cyberciti.biz/faq/linux-log-files-location-and-how-do-i-view-logs-files/ – Pedro Lobito May 02 '18 at 14:59