ユーザー空間でpingを検出し、それに応答します。

ユーザー空間でpingを検出し、それに応答します。

応答を送信する(または応答を送信しないこと)に加えて、Linuxシステムが他のデバイスからpingを送信するときに応答またはアクションを実行する方法はありますか?

ベストアンサー1

Linux netfilterを使用して、着信pingを傍受してユーザースペースに送信できます。これを行うことができます:

iptables -I INPUT -p icmp --icmp-type echo-request -j NFLOG

-s特定のpingのみをブロックし、他のpingはブロックしないように(source)などのあらゆる種類のiptables基準を追加できます。

これは元のpingのカーネル処理をキャンセルしないことに注意してください。ユーザー空間にのみコピーを送信します。ユーザースペースのpingに応答する予定の場合は、カーネルがそれを処理できないようにして、2つの応答がないようにする必要があります。これを達成するには、上記の他のiptablesルールに従って元のルールを削除してください。

iptables -I INPUT -p icmp --icmp-type echo-request -j DROP

ユーザー空間でpingを受け取るには、いくつかのCコードを書く必要があります。これlibnetfilter_logライブラリそれはあなたが必要とするすべてです。以下は、私が数年前に書いたいくつかのサンプルコードです。

#include <libnetfilter_log/libnetfilter_log.h>
[...]

    struct nflog_handle *h;
    struct nflog_g_handle *qh;
    ssize_t rv;
    char buf[4096];

    h = nflog_open();
    if (!h) {
            fprintf(stderr, "error during nflog_open()\n");
            return 1;
    }
    if (nflog_unbind_pf(h, AF_INET) < 0) {
            fprintf(stderr, "error nflog_unbind_pf()\n");
            return 1;
    }
    if (nflog_bind_pf(h, AF_INET) < 0) {
            fprintf(stderr, "error during nflog_bind_pf()\n");
            return 1;
    }
    qh = nflog_bind_group(h, 0);
    if (!qh) {
            fprintf(stderr, "no handle for group 0\n");
            return 1;
    }

    if (nflog_set_mode(qh, NFULNL_COPY_PACKET, 0xffff) < 0) {
            fprintf(stderr, "can't set packet copy mode\n");
            return 1;
    }

    nflog_callback_register(qh, &callback, NULL);

    fd = nflog_fd(h);

    while ((rv = recv(fd, buf, sizeof(buf), 0)) && rv >= 0) {
            nflog_handle_packet(h, buf, rv);
    }

callback各受信パケットに対して呼び出される関数です。その定義は次のとおりです。

static int
callback(struct nflog_g_handle *gh, struct nfgenmsg *nfmsg, struct nflog_data *ldata, void *data)
{
    payload_len = nflog_get_payload(ldata, (char **)(&ip));
    ....
    /* now "ip" points to the packet's IP header */
    /* ...do something with it... */
    ....
}

おすすめ記事