如何记录每条 ICMP 回复消息

发布于 2024-10-01 02:26:05 字数 47 浏览 4 评论 0原文

我遇到了一个问题,我们如何在GNU/Linux中找到ICMP回复消息的IP地址?

There is this question i ran into, how can we find the ip address of the ICMP reply message in GNU/Linux?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

暖风昔人 2024-10-08 02:26:05

查看 libpcap - 这是一个非常高效的网络嗅探库,它可以让您准确捕获指定类型的数据包(可能通过源/目标地址等进一步过滤)。然后,您可以解析数据包并提取源 IP 地址和目标 IP 地址。链接页面有文档和几个教程。

请注意,您需要在流量经过的计算机(源、目的地或中间的任何内容)上进行捕获,就像在现代以太网(通过交换机连接)中一样,您通常看不到所有网络流量。 请参阅 Wireshark(本质上是 libpcap 的 GUI)的问答,了解可能的解决方法。

Look into libpcap - it's a very efficient library for network sniffing, which lets you capture exactly the type of packets you specify (possibly filtered even further by source/destination address etc.). You can then parse the packet and extract the source and destination IP addresses. The linked page has documentation and several tutorials.

Note that you need to be doing the capture on a computer across which the traffic passes (source, destination, or anything in between) as in modern Ethernet networks (connected with switches), you normally don't see all network traffic. See this Q&A from Wireshark (which is essentially a GUI to libpcap) for possible workarounds.

舞袖。长 2024-10-08 02:26:05

您可以尝试 IPTables 日志记录

You can try IPTables logging.

枯叶蝶 2024-10-08 02:26:05

这是一个简单的循环(C Linux),用于拦截所有 ICMP 请求/回复:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>

int main(int argc, char **argv)
{
        int sock;
        int optval;
        int ret;
        int addrlen;
        struct sockaddr_in sIn;
        char *buffer;
        char *sAddr;
        char *dAddr;
        int proto;
        int type;

        buffer = malloc(sizeof(char) * 32);
        sAddr = malloc(sizeof(char) * 16);
        dAddr = malloc(sizeof(char) * 16);
        if ((sock = socket(AF_INET, SOCK_RAW, IPPROTO_ICMP)) != -1) {
            setsockopt(sock, IPPROTO_IP, IP_HDRINCL, &optval, sizeof(int));
            sIn.sin_family = AF_INET;
            sIn.sin_addr.s_addr = INADDR_ANY;
            addrlen = sizeof(sIn);
            memset(buffer, 0, 32);
            while ((ret = recvfrom(sock, buffer, 31, 0, (struct sockaddr *)&sIn, &addrlen)) != -1) {
                    if (ret > 20) {
                            proto = (unsigned char)buffer[9];
                            type = (unsigned char)buffer[20];
                            if (proto == 1 && (type == 8 || type == 0)) {
                                    memset(sAddr, 0, 16);
                                    memset(dAddr, 0, 16);
                                    sprintf(sAddr, "%d.%d.%d.%d",
                                            (unsigned char)buffer[12],
                                            (unsigned char)buffer[13],
                                            (unsigned char)buffer[14],
                                            (unsigned char)buffer[15]);
                                    sprintf(dAddr, "%d.%d.%d.%d",
                                            (unsigned char)buffer[16],
                                            (unsigned char)buffer[17],
                                            (unsigned char)buffer[18],
                                            (unsigned char)buffer[19]);
                                    if (type == 8)
                                            fprintf(stdout, "-> ICMP REQUEST FROM %s TO %s\n", sAddr, dAddr);
                                    else
                                            fprintf(stdout, "<- ICMP REPLY FROM %s TO %s\n", sAddr, dAddr);
                            }
                    }
                    memset(buffer, 0, 32);
            }
            close(sock);
        }
        free(buffer);
        free(sAddr);
        free(dAddr);
        return 0;
}

享受吧;)

This is a simple loop (C Linux) to intercept all ICMP REQUEST/REPLY:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>

int main(int argc, char **argv)
{
        int sock;
        int optval;
        int ret;
        int addrlen;
        struct sockaddr_in sIn;
        char *buffer;
        char *sAddr;
        char *dAddr;
        int proto;
        int type;

        buffer = malloc(sizeof(char) * 32);
        sAddr = malloc(sizeof(char) * 16);
        dAddr = malloc(sizeof(char) * 16);
        if ((sock = socket(AF_INET, SOCK_RAW, IPPROTO_ICMP)) != -1) {
            setsockopt(sock, IPPROTO_IP, IP_HDRINCL, &optval, sizeof(int));
            sIn.sin_family = AF_INET;
            sIn.sin_addr.s_addr = INADDR_ANY;
            addrlen = sizeof(sIn);
            memset(buffer, 0, 32);
            while ((ret = recvfrom(sock, buffer, 31, 0, (struct sockaddr *)&sIn, &addrlen)) != -1) {
                    if (ret > 20) {
                            proto = (unsigned char)buffer[9];
                            type = (unsigned char)buffer[20];
                            if (proto == 1 && (type == 8 || type == 0)) {
                                    memset(sAddr, 0, 16);
                                    memset(dAddr, 0, 16);
                                    sprintf(sAddr, "%d.%d.%d.%d",
                                            (unsigned char)buffer[12],
                                            (unsigned char)buffer[13],
                                            (unsigned char)buffer[14],
                                            (unsigned char)buffer[15]);
                                    sprintf(dAddr, "%d.%d.%d.%d",
                                            (unsigned char)buffer[16],
                                            (unsigned char)buffer[17],
                                            (unsigned char)buffer[18],
                                            (unsigned char)buffer[19]);
                                    if (type == 8)
                                            fprintf(stdout, "-> ICMP REQUEST FROM %s TO %s\n", sAddr, dAddr);
                                    else
                                            fprintf(stdout, "<- ICMP REPLY FROM %s TO %s\n", sAddr, dAddr);
                            }
                    }
                    memset(buffer, 0, 32);
            }
            close(sock);
        }
        free(buffer);
        free(sAddr);
        free(dAddr);
        return 0;
}

Enjoy ;)

才能让你更想念 2024-10-08 02:26:05

您当然可以打开一个套接字

socket(AF_INET, SOCK_RAW, IPPROTO_ICMP)

并记录到达的数据包的源地址。为此,您需要了解 ICMP 数据报的结构。参见 man 7 原始

You can certainly open a socket with

socket(AF_INET, SOCK_RAW, IPPROTO_ICMP)

And log the source address of packets arriving. You will need to know the structure of an ICMP datagram for this to work. See man 7 raw

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文