S. Sharma
S. Sharma

Reputation: 213

ICMP Packets not being sent with raw socket in C

I have a program that attempts to use raw sockets to send an ICMP packet in C. However, everytime I send an ICMP packet, I receive an error from sendto stating, Invalid argument.

Here's the main portion:

int main(int argc, char *argv[])
{
    if (argc != 3)
     {
            fprintf(stderr, "Usage: ./main [src] [dst]\n");
            return -1;
     }

    struct sockaddr_in src, dst;
    memset(&src, 0, sizeof(struct sockaddr_in));
    memset(&dst, 0, sizeof(struct sockaddr_in));

    inet_pton(AF_INET, argv[1], &src.sin_addr);
    inet_pton(AF_INET, argv[2], &dst.sin_addr);

    int s = socket(AF_INET, SOCK_RAW, IPPROTO_RAW);
    if (s == -1)
     {
            perror("socket");
            return -1;
     }


    void *pkt = create_pkt(&src, &dst, IPPROTO_ICMP);
    if (!pkt)
     {
            close(s);
            return -1;
     }

    send_pkt(s, pkt, sizeof(ICMP) + sizeof(IP), &dst);
    return 0;
}

Here's the function where the error happens:

void send_pkt(int s, void *pkt,
        int size, struct sockaddr_in *dst)
{
        if (sendto(s, pkt, size, 0,
                (struct sockaddr *) dst, sizeof(struct sockaddr)) == -1)
         {
                perror("sendto");
                return;
         }
}

I know I have raw sockets enabled on my system (I'm using Ubuntu 16.04) and I've also experimented with the values in dst including the IP destination address, but nothing has resulted in significant change. As a result, I've left dst->sin_port = 0 and dst->sin_family = 0.

If anyone could shed light as to why this isn't working, I would appreciate it.

Upvotes: 0

Views: 1057

Answers (1)

S. Sharma
S. Sharma

Reputation: 213

Turns out, with raw sockets, that sendto will return an error if any of the fields in the IP header are incorrect. In my case, I switched the positioning of the IHL and the version (I had combined them into one field because of endian issues). So, moral of the story: If you receive a sendto: Invalid argument error for a raw socket, be sure to check the IP header, not just your destination structure for sendto.

Upvotes: 2

Related Questions