这段代码为什么捕捉不到任何数据包?

2023-04-21 09:18:43 +08:00
 lysS

linux:

// clang -o raw raw.c && ./raw
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netinet/ip.h>
#include <arpa/inet.h>

#define BUFFER_SIZE 65536

int main(int argc, char *argv[])
{
    printf("Starting raw socket\n");

    int sockfd, n;
    char buffer[BUFFER_SIZE];
    struct sockaddr_in addr;
    struct iphdr *ip_header;

    // 创建 socket
    sockfd = socket(AF_INET, SOCK_RAW, IPPROTO_RAW);
    if (sockfd < 0) {
        perror("socket");
        exit(EXIT_FAILURE);
    }

    // 设置 socket 选项
    int on = 1;
    if (setsockopt(sockfd, IPPROTO_IP, IP_HDRINCL, &on, sizeof(on)) < 0) {
        perror("setsockopt");
        exit(EXIT_FAILURE);
    }

    // 绑定地址
    memset(&addr, 0, sizeof(addr));
    addr.sin_family = AF_INET;
    addr.sin_addr.s_addr = INADDR_ANY;
    if (bind(sockfd, (struct sockaddr *)&addr, sizeof(addr)) < 0) {
        perror("bind");
        exit(EXIT_FAILURE);
    }

    // 接收数据
    printf("Waiting for packet\n");
    while (1) {
        n = recv(sockfd, buffer, BUFFER_SIZE, 0);
        if (n < 0) {
            perror("recv");
            exit(EXIT_FAILURE);
        }

        // 解析 IP 头部
        ip_header = (struct iphdr *)buffer;
        printf("Received packet from %s\n", inet_ntoa(*(struct in_addr *)&ip_header->saddr));
    }

    return 0;
}
1461 次点击
所在节点    问与答
11 条回复
holycrazy
2023-04-21 09:34:03 +08:00
绑定的网卡不对吧
opengps
2023-04-21 09:42:30 +08:00
ip 用 0.0.0.0 ,接受本地所有网卡的数据
lysS
2023-04-21 09:59:53 +08:00
@opengps bind 的地址就是 4 个 0 啊
lysS
2023-04-21 10:00:18 +08:00
proto 是 IPPROTO_TCP|IPPROTO_UDP|IPPROTO_ICMP 也不行
Zss77
2023-04-21 10:29:02 +08:00
客户端在本机的话,走的是本地环路吧………x_x
BingoXuan
2023-04-21 10:33:17 +08:00
@lysS
印象中,我记得不能用 0.0.0.0 。要指定对应的网卡 ip
MozzieW
2023-04-21 10:37:25 +08:00
少了 listen ?看着是 TCP 的,流程应该是
bind(server)
client = listen(server)
receive(client)
bind 的 Socket 是用来 listen 的,listen 获得的 client 才是好客户端传说的 Socket 。
idealhs
2023-04-21 10:46:19 +08:00
GPT4:
根据您提供的信息,这段关于使用原始套接字的 C 代码无法捕获到任何数据包。问题可能产生在以下几个方面:

1. 原始套接字权限问题:请确保您的程序具有创建原始套接字所需的足够权限。一般来说,在 Linux 系统下,需要以 root 用户身份运行程序,或使用 setuid 技术来提升程序权限。

2. 选择正确的协议和类型:创建原始套接字时,请确保您选择了正确的协议类型(如 IPPROTO_TCP 或 IPPROTO_UDP )及套接字类型(如 SOCK_RAW )。如果选择的协议或类型不正确,可能导致无法捕获到相应的数据包。

3. 数据包过滤条件:请检查您的代码中是否设置了合适的数据包过滤条件。例如,如果您希望捕获特定的 IP 地址或端口的数据包,应确保代码中设置了合适的过滤条件。

4. 网络接口(网卡)问题:请确保您选择正确的网络接口来捕获数据包。例如,在 Linux 系统下,请确保您已打开待捕获数据包的网卡的混杂模式( promiscuous mode )。

5. 代码逻辑问题:请检查您的代码中是否存在未处理的错误返回,或未捕获数据包的逻辑。尝试扩展代码中的错误处理,添加详细的日志输出,从而找出问题所在。

以上几点仅是针对您所提供的信息给出的一些建议,并不一定能完全解释您遇到的问题。我建议您仔细检查代码逻辑,结合调试信息,找出问题所在。如有其他问题,欢迎随时提问。
feedcode
2023-04-21 10:55:09 +08:00
你这程序从哪里看来的?你要抓包要用 packet socket https://man7.org/linux/man-pages/man7/packet.7.html
lysS
2023-04-21 11:31:22 +08:00
@MozzieW 不是,要捕捉所有 IP 包,无论 tcp udp 还是 icmp
lysS
2023-04-21 16:21:43 +08:00
@feedcode chat 给的

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/934207

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX