I am trying to understand how recvfrom() works in linux.
I opened a raw socket and read ICMP packets on an interface.
What I thought was recvfrom() copies a packet from Kernel to the application.
I tried to read ICMP request packet and clear the buffer and expect I cannot receive ICMP reply.
But it seems I still receive ICMP reply.
Am I misunderstanding the network operation or there is something wrong in the code?
The default ICMP packet size was 98.
So, I have just used the packet length to check whether the packet read is ICMP or not.
What I want to do is receive an ICMP packet from an interface and clear or drop the packet buffer.
And that can actually break ICMP packet exchange or not.
I ran this program on the PC2 from the diagram below.
And send a ICMP packet from PC1 to PC3.
+-------+ +-------+ +-------+
| | | | | |
| PC 1 | ----- | PC 2 | ----- | PC 3 |
| | | | | |
+-------+ +-------+ +-------+
int main(int argc, char *argv[])
{
int32_t sock;
int8_t buf[1522];
int32_t ifindex;
int32_t ret;
int32_t bytes;
struct sockaddr_ll sll;
struct ifreq ifr;
time_t rawtime;
struct tm *info;
time(&rawtime);
info = localtime(&rawtime);
sock = socket(PF_PACKET, SOCK_RAW, htons(ETH_P_ALL));
if (sock == -1)
{
printf("socket open failedn");
return 1;
}
strncpy(ifr.ifr_name, "eth1", sizeof(ifr.ifr_name));
ret = ioctl(sock, SIOCGIFINDEX, &ifr);
if (ret < 0)
{
printf("failed to get indexn");
return -1;
}
sll.sll_family = AF_PACKET;
sll.sll_ifindex = ifr.ifr_ifindex;
sll.sll_protocol = htons(ETH_P_ALL);
ret = bind(sock, (struct sockaddr *)&sll, sizeof(struct sockaddr_ll));
if (ret < 0)
{
close(sock);
printf("interface binding errorn");
return 1;
}
while(1)
{
bytes = recvfrom(sock, buf, 1522, 0, NULL, NULL);
if (bytes < 0)
{
printf("error in recvfromn");
exit;
}
if (bytes == 98)
{
memset(buf, 0x0, 1522);
}
printf("%s : received bytes = %dn", bytes);
}
close(sock);
return 0;
}