User_890
User_890

Reputation: 189

recvfrom() returns -1 for RAW socket when used in a thread?

i want to use multithreading for capturing and processing the IP packets.one thread will only capture and store the packets for say 2 seconds and after that send(using pipe) this chunk to another thread where necessary informations will be extracted. to capture ip packets, am using RAW sockets and recvfrom() but recvfrom() returns -1 for each loop iteration. I think socket is not capturing the packets but i could not find out the reason...any help?? here is the Code...

void Capture()
{
    int rbytes, Rsock;

    struct sockaddr saddr;

    unsigned char *buffer = (unsigned char *)malloc(65536); /* hold packet */

    /* Create a raw socket that shall sniff */
    Rsock=socket(AF_PACKET , SOCK_RAW , htons(ETH_P_IP));
    if(Rsock < 0)
    {
        printf("Socket Error\n");
        return;
    }

    while(1)
    {   
        rbytes = recvfrom (Rsock , buffer , 65536 , 0 , &saddr ,(socklen_t *)sizeof saddr);
        if(rbytes <=0 )
            printf("failed to get packets!");
        else
            printf("Recv bytes %d: \n", rbytes);
    } 
}

and the main() is..

int main()
{
    pthread_t tid;

    int err = pthread_create(&(tid), NULL, (void*)&Capture, NULL);
        if (err != 0){
            printf("\ncan't create capturing thread :[%s]", strerror(err));
            return 0;
        }
        else
            printf("\nCapturing thread created!\n");

    pthread_join(tid, NULL);

    printf("Finished!!");
    return 0;
}

Upvotes: 0

Views: 444

Answers (1)

nos
nos

Reputation: 229088

Your two last arguments here is wrong,

rbytes = recvfrom (Rsock , buffer , 65536 , 0 , &saddr ,(socklen_t *)sizeof saddr);

Don't cast the last argument, you need to past in an actual pointer. You also need to pass in a pointer to a particular sockaddr type, not a pointer to a struct sockaddr and that argument you may need to cast.

struct sockaddr_storage saddr; //Or sockaddr_in if you are certain you
                               // only deal with IPv4...
socklen_t slen = sizeof saddr;

rbytes = recvfrom (Rsock , buffer , 65536 , 0 , (struct sockaddr*)&saddr ,&slen);

If recvfrom returns -1, you can inspect the errno value to learn what is wrong, or just print the error with e.g. perror("recvfrom failed");

Upvotes: 1

Related Questions