I am working with network stack and get stuck with ICMP implementation. I use TAP device. I am sure I implemented ICMP correctly from the protocol side but maybe there are some incompatabilities between sockets. Iputils ping (default Linux ping implementation) doesn't receive any response. Some points:
- ARP works correctly (tested with: $ arping -I tap0 10.0.0.2)
- I made some debug of official ping and found that it returns -1 here: https://github.com/iputils/iputils/blob/master/ping/ping_common.c#L668 I see in Wireshark that I send response from my TAP correctly so it looks like ping socket doesn't understand my response at all.
- I tried alternative ping implementations, more particular this one: http://www.pdbuchan.com/rawsock/ping4_ll.c and it works correctly, ping receives ICMP response.
- I compared iputils ping and that alternative (pdbuchan.com) implementation sockets. iputils ping (which is not working):
socket(PF_INET, SOCK_RAW, IPPROTO_ICMP)pdbuchan.com ping (which works):socket(PF_PACKET, SOCK_RAW, htons(ETH_P_ALL))
In my opinion, the answer lies somewhere here between socket options. But I can't find it by myself. Any ideas?
Btw, this is shortened code how I open and configure my TAP descriptor:
// Open
fd = open("/dev/net/tun", O_RDWR);
// TAP, No protocol information, name
ifr.ifr_flags = IFF_TAP | IFF_NO_PI;
strncpy(ifr.ifr_name, dev, IFNAMSIZ);
ioctl(fd, TUNSETIFF, (void *) &ifr);
// Open socket descriptor for network configuration
sd = socket(PF_INET, SOCK_DGRAM, IPPROTO_IP);
strncpy(ifr.ifr_name, dev, IFNAMSIZ);
// Add address
ifr.ifr_addr.sa_family = AF_INET;
inet_pton(AF_INET, address, &addr->sin_addr);
ioctl(sd, SIOCSIFADDR, &ifr);
// Add subnet mask
inet_pton(AF_INET, subnet_mask, &broadaddr->sin_addr);
ioctl(sd, SIOCSIFNETMASK, &ifr);
// Make interface active
ifr.ifr_flags = (IFF_UP | IFF_RUNNING);
ioctl(sd, SIOCSIFFLAGS, &ifr);
Thank you.