在用户空间中检测并响应 ping

在用户空间中检测并响应 ping

除了发送回复(或不发送回复)之外,有没有办法让 Linux 系统在从另一个设备 ping 时做出反应或执行某些操作?

答案1

您可以使用 Linux netfilter 拦截传入的 ping 并将其发送到用户空间。这将做到这一点:

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

您可以添加任何类型的 iptables 标准,例如-s(源),以便仅拦截某些 ping,而不拦截其他 ping。

请注意,这不会取消内核对原始 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... */
    ....
}

答案2

我使用的简单方法是通过任何实用程序(wireshark、tcpdump、iptables 等)嗅探 ICMP 流量。
例如,您可以使用以下方法:关联

相关内容