8
  • 编译器:代码::块(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。

    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()(checksum generator) 是未定义的。

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

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

    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));
4

2 回答 2

5

如果您不必从头开始执行 ping,并且只需要 Windows 解决方案,我会支持 Anton 对 IcmpSendEcho 的建议。如果一定要实现ping,看POCO ICMP包是怎么实现的。它是可移植的代码,在 Windows 上运行良好。

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

我应该包含哪些头文件

#include <winsock2.h>

如何创建 ping 数据包

有关IPv4 数据包的示例,请参阅ICMPv4PacketImpl::initPacket() 。

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

不适用于窗户。有关校验和函数的示例,请参见ICMPPacketImpl::checksum() 。

是否应该将 ping 定向到端口 80

不,对于 ICMP,没有端口之类的东西。请参阅ICMP 是否使用特定端口?

我使用的套接字应该是 RAW 还是 DGRAM

它应该是RAW。

于 2013-01-14T18:55:09.807 回答
4

看起来您想要一个真正的解决方案,而不仅仅是为了它而重新实现 PING。

我建议使用 IP 帮助程序(WinXP 之前的系统上的 ICMP.dll),特别是IcmpSendEcho(或其增强版本,IcmpSendEcho2, IcmpSendEcho2Ex,用于异步操作)。

MSDN上有一个“ping”主机的完整示例。这可能是一个很好的起点。

更新:对于 GCC (mingw),与 -liphlpapi 链接。

于 2013-01-13T19:41:22.567 回答