This is an assignment, it has to be with raw sockets. I need to program a simple icmp ping.
I used this as a base http://www.pdbuchan.com/rawsock/icmp4.c . At line 127 is wlan0, Im using eth0. In line 290 I coded this:
struct sockaddr_in rec;
unsigned char * pkt = (unsigned char *) malloc (IP_MAXPACKET * sizeof (unsigned char));
if (recvfrom (sd, (void*)pkt, IP4_HDRLEN + ICMP_HDRLEN+datalen , 0, NULL, (socklen_t*)sizeof (struct sockaddr)) < 0) {
perror ("recvfrom() failed ");
exit (EXIT_FAILURE);
}
struct ip *ip = (struct ip *)pkt;
struct icmphdr *icmp = (struct icmphdr *)(pkt + IP4_HDRLEN);
printf("%s %s %d\n",(char*)inet_ntoa(*(struct in_addr*)&ip->ip_dst),
(char*)inet_ntoa(*(struct in_addr*)&ip->ip_src),
icmp->type);
free (pkt);
The problem is that ip_dst and ip_src are being shown as my machines’s IP, and icmp type as 0 and not 8. Wireshark shows both icmp reply and request.
Probably my recvfrom is wrong, but I heard something about linux own TCP/IP might be handling the packets. If that’s true, what is the workaround for that?
edit: I checked this raw socket listener but it did not solve my problem.
I don’t think you can get a reply when using IPPROTO_RAW.
You have to use
With IPPROTO_ICMP you must only send an ICMP packet, not the whole IP packet.
When receiving however you’ll get the whole IP packet and have to extract the ICMP reply. Note that you will get a copy of all ICMP packets sent to the host so you must filter them.