Search code examples
cforkarp

linux child recvfrom not working as it should


I'm making a bunch of child processes and every child must make an arp package with a different IP for every child,send the package and receive a package from the machine with the corresponding IP if that machine is on.The problem is that i send the packages correctly(i check this with wireshark) but I don't know why,all my child processes receive the same package.

For example I have 192.167.0.1,88.4.3.2 and 100.20.3.20.Only the first IP is good.I have 3 child processes that each send a request and wait 8000000 nanoseconds for a response.The only response comes for the child with the first IP(because is is correct) but I don't know why all the children receive this package.Any suggestions ? Here is a piece of code.I'm sure that it sends the packages correctly because I tested it with wireshark.

    if (sendto(sock,&req,sizeof(req),0,(struct sockaddr*)&addr,sizeof(addr))==-1) {
      printf("%s",strerror(errno));
    }
    struct sockaddr_ll linkLayerAddr;
    char buf[32];
    int sockaddr_len=sizeof(linkLayerAddr);
    memset(&linkLayerAddr,0,sizeof(linkLayerAddr));
    fcntl(sock,F_SETFL,O_NONBLOCK);
    nanosleep(&time1,NULL);

     if(recvfrom(sock,buf,sizeof(buf),0,(struct sockaddr*)&linkLayerAddr,&sockaddr_len)==-1){

    info.status=0; 
    }
    else{
    info.status=1;

}

Thant thing with the info structure I use just to check something.


Solution

  • ARP packets does not contain port number or similar id for describing the destination application. So all received ARP packages are delivered to all ARP sockets.

    In your case: Threads should only pick wanted packet and ignore others.

    EDIT: You could loop until the wanted ARP-respone packet is received. This way:

    while ( !time_out )
    {
        <receive next ARP packet>
    
        if ( arph->ar_tip == wanted_ip )
        {
            // This is correct one. Handle it and break out from the loop.
            <process the package>
            break;
        }
        else
        {
            // This is not for me, ignore it silently.
        }    
    }