如何使用C套接字ping [英] How to ping using C sockets

查看:148
本文介绍了如何使用C套接字ping的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

  • 编译器:代码::: Blocks(GNU GCC)
  • 平台:Windows(x86)
  • 包括:winsock.h winsock2.h(ws2_32也已链接)

我当前正在尝试编写一个程序,该程序将读取包含IP地址列表的文本文件并分别ping每个IP地址.如果主机响应ping,则主机的IP地址将被复制到用户指定的第二个文件中.毫不夸张地说,这是我第一次使用C的套接字库,但是找不到关于如何使用C ping的好的教程.据我对我发现的几本教程的了解.我需要在IP数据报中包括一个ICMP标头,该标头包含ICMP类型,代码和校验和.但是我不知道该怎么做,我应该自己声明该结构还是在头文件中声明该结构?我假设它在标题中,但是教程在声明它的确切位置上相互矛盾.我包括icmp.h和netinet/icmp.h都很累,但是我的编译器抱怨它们不存在,所以我创建了自己的结构.

I am currently trying to write a program that will read a text file containing a list of IP-Addresses and ping each IP-Addresses respectively. If the host responds to the ping then the host's IP-Address will be copied to a seconded file specified by the user. Unfourtantly this is the first time I have used C's socket library and I cannot find a good tutorial about how to ping using C. From what I understand of the couple tutorials I did find. I need to included a ICMP header, which is a struct containg the ICMP type, code, and checksum, in a IP datagram. But I have no idea how to go about doing so, should I declare the struct myself or is it declared in a header file? I am assuming that it is in a header but the tutorials contradicted each other about exactly where it is declared. I tired including icmp.h and netinet/icmp.h but my compiler complained that they don't exist so I created my own struct.

    struct echo_request
    {
        char type; // Type
        char code; // Code
        short checksum; // Checksum
        short id; // Identification
        short seq; // Sequence
        int time; // Time
        char data[16]; // Data
    };

我认为我也许可以摆脱它,但是我什至无法编译程序,因为我的编译器说in_cksum()(校验和生成器)未定义.

I thought that I might be able to get away with it but I wasn't even able to compile my program because my compiler says that in_cksum()(checksum generator) is undefined.

总结一下我的问题,我应该包括哪些头文件,如何创建ping数据包,我是否使用了正确的校验和生成器功能,应该将ping定向到端口80,并且应该使用的套接字是RAW?还是DGRAM?

To sum up my questions, what header files should I include, how do I create a ping packet, am I using the correct checksum generator function, should a ping be directed to port 80, and should the socket I use be RAW or DGRAM?

到目前为止,这是我所拥有的,请注意,我故意省略了错误检查.

This is what I have so far, please note that I have purposely left out error checking.

    int socket_descriptor = socket(AF_INET, SOCK_RAW, IPPROTO_ICMP);

    struct sockaddr_in address; //Initialize address struct
    memset(&address, 0, sizeof(address)); //Clear address struct

    //Declare address
    address.sin_family = AF_INET;
    address.sin_addr.s_addr = inet_addr(ipaddress);
    address.sin_port = htons(80);

    //Bind socket to address
    bind(socket_descriptor, (struct sockaddr *)&address, sizeof(address));

    //Create packet
    struct echo_request packet; //See above for declaration of struct
    memset(packet.data, 1, 16);
    packet.type = 8; //ECHO_REQUEST
    packet.code = 0;
    packet.time = gettime();
    packet.checksum = 0;
    packet.checksum = in_cksum(packet, sizeof(packet));

推荐答案

如果您不必从头开始执行ping操作,并且只需要Windows解决方案,那么我会第二次推荐Anton对IcmpSendEcho的建议.如果必须实施ping,请查看如何实现 POCO ICMP程序包.它是可移植的代码,并且可以在Windows上正常运行.

If you don't have to implement the ping from scratch and you want only Windows solution, I'd second Anton's suggestion for IcmpSendEcho. If you have to implement ping, look at how POCO ICMP package is implemented. It is portable code and it runs fine on Windows.

关于具体问题,以下是答案:

In regards to the specific questions, here are the answers:

我应该包含哪些头文件

what header files should I include

#include <winsock2.h>

如何创建ping数据包

how do I create a ping packet

请参见 ICMPv4PacketImpl: :initPacket()来获取IPv4数据包的示例.

See ICMPv4PacketImpl::initPacket() for an example of IPv4 packet.

我使用了正确的校验和生成器功能

am I using the correct checksum generator function

不适用于Windows.参见 ICMPPacketImpl :: checksum( )作为校验和功能的示例.

Not for windows. See ICMPPacketImpl::checksum() for an example of checksum function.

应该将ping命令定向到端口80

should a ping be directed to port 80

不.关于ICMP,没有端口之类的东西.请参见 ICMP是否使用特定端口?

No. There's no such thing as port when it comes to ICMP. See Does ICMP use a specific port?

我使用的插座应该是RAW还是DGRAM

should the socket I use be RAW or DGRAM

应该是RAW.

这篇关于如何使用C套接字ping的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆