简体   繁体   English

没有使用C中的原始套接字发送ICMP数据包

[英]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. 我有一个程序尝试使用原始套接字在C中发送ICMP数据包。但是,每次我发送ICMP数据包时,都会从sendto收到一个错误消息,指出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. 我知道我的系统上启用了原始套接字(我正在使用Ubuntu 16.04),并且我还尝试了dst的值(包括IP目标地址),但没有任何改变。 As a result, I've left dst->sin_port = 0 and dst->sin_family = 0 . 结果,我离开了dst->sin_port = 0dst->sin_family = 0

If anyone could shed light as to why this isn't working, I would appreciate it. 如果有人能阐明为什么它不起作用,我将不胜感激。

Turns out, with raw sockets, that sendto will return an error if any of the fields in the IP header are incorrect. 原来,使用原始套接字,如果IP标头中的任何字段不正确,则sendto将返回错误。 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 . 因此,故事的寓意是:如果收到sendto: Invalid argument原始套接字的sendto: Invalid argument错误sendto: Invalid argument ,请确保检查IP标头,而不只是检查sendto的目标结构。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM