Search code examples
c++csocketsethernetsniffing

Raw Socket promiscuous mode not sniffing what I write


I am writing a program with a Raw Socket in promiscuous mode and I need the raw socket not sniff the packet I send. I need to read only the data over the ethernet rx wire (not the tx wire). It's posible?

Thanks a lot.


Solution

  • The solution is to look in the read packet if it is a PACKET_OUTGOING. Using this option you can diference the packet you put in the ethernet tx wire and the packet you read from the rx wire.

    Open the Socket in promiscuous mode:

    char* i = "eth0";
    int fd;
    struct ifreq ifr;
    struct sockaddr_ll interfaceAddr;
    struct packet_mreq mreq;
    
    if ((fd = socket(PF_PACKET,SOCK_RAW,htons(ETH_P_ALL))) < 0)
        return -1;
    
    memset(&interfaceAddr,0,sizeof(interfaceAddr));
    memset(&ifr,0,sizeof(ifr));
    memset(&mreq,0,sizeof(mreq));
    
    memcpy(&ifr.ifr_name,i,IFNAMSIZ);
    ioctl(fd,SIOCGIFINDEX,&ifr);
    
    interfaceAddr.sll_ifindex = ifr.ifr_ifindex;
    interfaceAddr.sll_family = AF_PACKET;
    
    if (bind(fd, (struct sockaddr *)&interfaceAddr,sizeof(interfaceAddr)) < 0)
        return -2;
    
    
    mreq.mr_ifindex = ifr.ifr_ifindex;
    mreq.mr_type = PACKET_MR_PROMISC;
    mreq.mr_alen = 6;
    
    if (setsockopt(fd,SOL_PACKET,PACKET_ADD_MEMBERSHIP,
         (void*)&mreq,(socklen_t)sizeof(mreq)) < 0)
            return -3;
    //...
    

    And read. Now, We can differentiate between the Rx and Tx ethernet wire:

    unsigned char buf[1500];
    struct sockaddr_ll addr;
    socklen_t addr_len = sizeof(addr);
    n = recvfrom(fd, buf, 2000, 0, (struct sockaddr*)&addr, &addr_len);
    if (n <= 0)
    {
        //Error reading
    }
    else if (addr.sll_pkttype == PACKET_OUTGOING)
    {
        //The read data are not writing by me.
        //Use only this data to copy in the other network.
    }
    

    And it's all. Using it I don't read the data I write. I avoid the loop when I copy the network 1 frames to network 2 and the network 2 frames to network 1.