A Packetsocket opened on a loopback device receives all packets twice. How to filter these duplicate entries?

when I open packetsocket on the loopback (lo) interface and listen that all packets are visible twice. why is that so?

But capturing on an interface using tcpdump correctly ignores duplicate entries. see "packets received by the filter" (which contains duplicate packets) and "captured packets". How is this filtering performed?

tcpdump -i lo -s 0

 tcpdump: verbose output suppressed, use -v or -vv for full protocol decode listening on lo, link-type EN10MB (Ethernet), capture size 65535 bytes 11:00:08.439542 IP 12.0.0.3 > localhost.localdomain: icmp 64: echo request seq 1 11:00:08.439559 IP localhost.localdomain > 12.0.0.3: icmp 64: echo reply seq 1 11:00:09.439866 IP 12.0.0.3 > localhost.localdomain: icmp 64: echo request seq 2 11:00:09.439884 IP localhost.localdomain > 12.0.0.3: icmp 64: echo reply seq 2 11:00:10.439389 IP 12.0.0.3 > localhost.localdomain: icmp 64: echo request seq 3 11:00:10.439410 IP localhost.localdomain > 12.0.0.3: icmp 64: echo reply seq 3 6 packets captured 12 packets received by filter 0 packets dropped by kernel 

My code is:

 int main() { int sockFd; if ( (sockFd=socket(PF_PACKET, SOCK_DGRAM, 0))<0 ) { perror("socket()"); return -1; } /* bind the packet socket */ struct sockaddr_ll addr; struct ifreq ifr; strncpy (ifr.ifr_name, "lo", sizeof(ifr.ifr_name)); if(ioctl(sockFd, SIOCGIFINDEX, &ifr) == -1) { perror("iotcl"); return -1; } memset(&addr, 0, sizeof(addr)); addr.sll_family=AF_PACKET; addr.sll_protocol=htons(ETH_P_ALL); addr.sll_ifindex=ifr.ifr_ifindex; if ( bind(sockFd, (struct sockaddr *)&addr, sizeof(addr)) ) { perror("bind()"); return -1; } char buffer[MAX_BUFFER+1]; int tmpVal = 1; while(tmpVal > 0) { tmpVal = recv (sockFd, buffer, MAX_BUFFER, 0); cout<<"Received Pkt with Bytes "<<tmpVal <<endl; } } 
+4
source share
1 answer

I found out the problem.

from libcaps code:

  * - The loopback device gives every packet twice; on 2.2[.x] kernels, * if we use PF_PACKET, we can filter out the transmitted version * of the packet by using data in the "sockaddr_ll" returned by * "recvfrom()", but, on 2.0[.x] kernels, we have to use * PF_INET/SOCK_PACKET, which means "recvfrom()" supplies a * "sockaddr_pkt" which doesn't give us enough information to let * us do that. 

the listener should filter the duplicate packet using if_index obtained from recvfrom api.

+4
source

Source: https://habr.com/ru/post/1487069/


All Articles