Packet socket in promiscuous mode only receiving local traffic

nonpolynomial237 picture nonpolynomial237 · Aug 25, 2009 · Viewed 12.4k times · Source

I have a socket created with socket(PF_PACKET, SOCK_RAW, htons(ETH_P_ALL)), and I've set it into promiscuous mode using:

struct ifreq ifr;
strncpy((char*)ifr.ifr_name, interface, IF_NAMESIZE);
if(ioctl(sock, SIOCGIFINDEX, &ifr)<0) fail(2);

struct packet_mreq mr;
memset(&mr, 0, sizeof(mr));
mr.mr_ifindex = ifr.ifr_ifindex;
mr.mr_type = PACKET_MR_PROMISC;
if(setsockopt(sock, SOL_PACKET, PACKET_ADD_MEMBERSHIP, &mr, sizeof(mr)) < 0) fail(2);

The problem is that when I do a read() from the socket, it only returns data that's going from or coming to my computer.

How can I get it to read and process all packets on the network?

Wireshark shows all the packets fine, so I know it isn't my computer or NIC. ifconfig reports that it's PROMISC when it is running.

Answer

Andrew Edgecombe picture Andrew Edgecombe · Aug 25, 2009

Along with Rob Jones' suggestion, try a tool like Wireshark to make sure that you're receiving the packets that you expect at the interface. At least that will confirm (or deny) that you have a problem with your code.

Also need to make sure that the interface itself is set to promiscuous mode. If not then you can use the ioctl() to set it:

ifr.ifr_flags |= IFF_PROMISC;
if( ioctl(sock, SIOCSIFFLAGS, &ifr) != 0 )
{
    // handle error here
}

While your application is running, make sure that ifconfig reports the PROMISC flag for that interface.

Note that this will need to be executed as a privileged user.


Tried out the code as presented. Works for me. Of course (due to the test on line 102) this will only print details for TCP traffic.