Skip to content

socket() with IPPROTO_ICMP uses UDP #32

@iAmGroute

Description

@iAmGroute

I compile the following to send ICMP packets:

#include <stdio.h>
#include <errno.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <string.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <unistd.h>
#define ICMP_ECHO       8   /* Echo Request         */
int main() {
	struct sockaddr_in to;
	memset(&to, 0, sizeof(to));
	to.sin_family      = AF_INET;
	//to.sin_addr.s_addr = inet_addr("172.44.0.3");
	to.sin_addr.s_addr = inet_addr("1.1.1.1");
	to.sin_port        = 0;
	char packet[150] = { 0 };
	packet[0] = ICMP_ECHO;
	int fd = socket(AF_INET, SOCK_DGRAM, IPPROTO_ICMP);
	while (1) {
		int r = sendto(fd, packet, sizeof(packet), 0, (struct sockaddr *)&to, sizeof(to));
		printf("%d %d\n", r, errno);
		sleep(4);
	}
}

with: gcc -static-pie -fPIC -Wall -o icmp_test icmp_test.c

  • If I then run it on Linux 5.15.0-69-generic, it sends ICMP echo reply packets (as expected), as seen in tcpdump:
$ sudo tcpdump -nn -v -i wlp3s0 host 1.1.1.1
tcpdump: listening on wlp3s0, link-type EN10MB (Ethernet), snapshot length 262144 bytes
17:26:30.999548 IP (tos 0x0, ttl 64, id 25840, offset 0, flags [DF], proto ICMP (1), length 170)
    ${my_ip} > 1.1.1.1: ICMP echo request, id 25, seq 0, length 150
...
  • If I run it with app-elfloader:
    ../../run-app-elfloader/run_elfloader -r rootfs/ -k build/*_kvm-x86_64 -n icmp_test,
    it doesn't send out ICMP packets, but UDP.
    We can see this in the lwip debug output (proto=17 which is UDP, while ICMP would be 1):
[    6.461028] dbg:  [liblwip] <ip4.c @ 1097> IP header:
[    6.463983] dbg:  [liblwip] <ip4.c @ 1098> +-------------------------------+
[    6.467685] dbg:  [liblwip] <ip4.c @ 1099> | 4 | 5 |  0x00 |       178     | (v, hl, tos, len)
[    6.472054] dbg:  [liblwip] <ip4.c @ 1104> +-------------------------------+
[    6.475470] dbg:  [liblwip] <ip4.c @ 1105> |       22      |000|       0   | (id, flags, offset)
[    6.480519] dbg:  [liblwip] <ip4.c @ 1111> +-------------------------------+
[    6.484549] dbg:  [liblwip] <ip4.c @ 1112> |  255  |   17  |    0x0cf5     | (ttl, proto, chksum)
[    6.489074] dbg:  [liblwip] <ip4.c @ 1116> +-------------------------------+
[    6.493351] dbg:  [liblwip] <ip4.c @ 1117> |  172  |   44  |    0  |    2  | (src)
[    6.498078] dbg:  [liblwip] <ip4.c @ 1122> +-------------------------------+
[    6.501923] dbg:  [liblwip] <ip4.c @ 1123> |    1  |    1  |    1  |    1  | (dest)
[    6.505931] dbg:  [liblwip] <ip4.c @ 1128> +-------------------------------+

I can't see any references to IPPROTO_ICMP in this repo (when built), so I guess that's why.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    Status

    No status

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions