8
  • コンパイラ: コード::ブロック (GNU GCC)
  • プラットフォーム: Windows(x86)
  • インクルード: winsock.h winsock2.h (ws2_32 もリンクされています)

私は現在、IP アドレスのリストを含むテキスト ファイルを読み取り、各 IP アドレスにそれぞれ ping を実行するプログラムを作成しようとしています。ホストが ping に応答すると、ホストの IP アドレスが、ユーザーが指定した 2 番目のファイルにコピーされます。残念なことに、C のソケット ライブラリを使用したのはこれが初めてで、C を使用して ping を実行する方法についての適切なチュートリアルが見つかりません。ICMP タイプ、コード、およびチェックサムを含む構造体である ICMP ヘッダーを IP データグラムに含める必要があります。しかし、どうすればいいのかわかりません。構造体を自分で宣言する必要がありますか、それともヘッダーファイルで宣言されていますか? 私はそれがヘッダーにあると仮定していますが、チュートリアルはそれが宣言されている正確な場所について互いに矛盾しています。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 ソリューションのみが必要な場合は、IcmpSendEcho に対する Anton の提案を 2 番目に使用します。ping を実装する必要がある場合は、POCO ICMP パッケージの実装方法を確認してください。これは移植可能なコードであり、Windows 上で正常に動作します。

具体的な質問については、次のとおりです。

どのヘッダー ファイルを含める必要がありますか

#include <winsock2.h>

ping パケットを作成する方法

IPv4 パケットの例については、ICMPv4PacketImpl::initPacket()を参照してください。

正しいチェックサム生成関数を使用していますか?

窓用ではありません。チェックサム関数の例については、ICMPPacketImpl::checksum()を参照してください。

ポート 80 に ping を送信する必要があります

いいえ。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 に答える