Abhishek Sagar
Abhishek Sagar

Reputation: 1326

NO correct data being received on Raw socket

I have written the simplest of Raw socket example to send data from one appl to another through RAW socket with protcol no = 5 (not being used up by standard protocols).

Here are my codes :

sender

void sendRawData(char sendString[] )
{

    int sock;
    struct sockaddr_in server_addr;
    struct hostent *host;                   //hostent predefined structure use to store info about host        host = (struct hostent *) gethostbyname(server);//gethostbyname returns a pointer to hostent
    if ((sock = socket(AF_INET, SOCK_RAW, 5)) == -1)
    {
            perror("socket");
            exit(1);
    }

    //destination address structure
    server_addr.sin_family = AF_INET;
    server_addr.sin_port = htons(NOT_REQ); // NOT_REQ is 2000 but for SOCK_RAW sockets, it should be useless.
    server_addr.sin_addr = *((struct in_addr *)host->h_addr);       //host->h_addr gives address of host
    bzero(&(server_addr.sin_zero),8);
    sendto(sock, sendString, strlen(sendString), 0,(struct sockaddr *)&server_addr, sizeof(struct sockaddr));

    //sendto() function shall send a message through a connectionless-mode socket.
    printf("\nFORWARD REQUEST : '%s' has been forwarded to server\n",sendString);
    close(sock);
}

reciever

int main(int argc, char **argv){
    int sock = 0, len, addr_len;
    char rec_buff[5000];

    struct sockaddr_in address,
                    server_addr_udp,
                    client_addr;

    if ((sock = socket(AF_INET, SOCK_RAW, 5)) == -1)          //Creating a UDP Socket
    {

            perror("Socket");
            exit(1);
    }

    server_addr_udp.sin_family = AF_INET;
    server_addr_udp.sin_port = htons(2004); // again it should be useless
    server_addr_udp.sin_addr.s_addr = INADDR_ANY;
    bzero(&(server_addr_udp.sin_zero),8);
    addr_len = sizeof(struct sockaddr);
     if (bind(sock,(struct sockaddr *)&server_addr_udp, sizeof(struct sockaddr)) == -1)//Binding UDP socket
    {
        perror("Bind");
        exit(1);
    }

    len = recvfrom(sock, rec_buff,5000,0,(struct sockaddr *)&client_addr, &addr_len);
    printf("ip = %s, port = %d\n", inet_ntoa(client_addr.sin_addr),ntohs(client_addr.sin_port));
    printf("%s\n", rec_buff);
    main(0, NULL);
    return 0;
}

What i am observing is on receiving side, i am receiving incorrect data. If i change the socket type to SOCK_DGRAM and protocol = IPPROTO_UDP, then everything works perfect. My intention is to use custom protocol number (5) since every packet in the world need not be UDP/TCP packet.

Can somebody enlighten me where i am going wrong.

output

ip = 127.0.0.1, port = 0
E

Upvotes: 0

Views: 353

Answers (1)

SergeyA
SergeyA

Reputation: 62583

The answer is surprisingly simple :). When you receive a raw IP datagram, it always contains IP header in it. (Hint - checking returned value of recvfrom() and comparing it with returned value of sendto() would help you to realize this, as I indicated in my earlier comment).

So you can either properly parse IP header to arrive at your payload, or you can assume that IP header size is always 20 bytes and simply fast-forward to it.

Upvotes: 1

Related Questions