V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
V2EX 提问指南
lysS
V2EX  ›  问与答

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

  •  
  •   lysS · 364 天前 · 1214 次点击
    这是一个创建于 364 天前的主题,其中的信息可能已经有所发展或是发生改变。

    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;
    }
    
    11 条回复    2023-04-21 16:21:43 +08:00
    holycrazy
        1
    holycrazy  
       364 天前
    绑定的网卡不对吧
    opengps
        2
    opengps  
       364 天前
    ip 用 0.0.0.0 ,接受本地所有网卡的数据
    lysS
        3
    lysS  
    OP
       364 天前
    @opengps bind 的地址就是 4 个 0 啊
    lysS
        4
    lysS  
    OP
       364 天前
    proto 是 IPPROTO_TCP|IPPROTO_UDP|IPPROTO_ICMP 也不行
    Zss77
        5
    Zss77  
       364 天前
    客户端在本机的话,走的是本地环路吧………x_x
    BingoXuan
        6
    BingoXuan  
       364 天前
    @lysS
    印象中,我记得不能用 0.0.0.0 。要指定对应的网卡 ip
    MozzieW
        7
    MozzieW  
       364 天前
    少了 listen ?看着是 TCP 的,流程应该是
    bind(server)
    client = listen(server)
    receive(client)
    bind 的 Socket 是用来 listen 的,listen 获得的 client 才是好客户端传说的 Socket 。
    idealhs
        8
    idealhs  
       364 天前
    GPT4:
    根据您提供的信息,这段关于使用原始套接字的 C 代码无法捕获到任何数据包。问题可能产生在以下几个方面:

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

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

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

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

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

    以上几点仅是针对您所提供的信息给出的一些建议,并不一定能完全解释您遇到的问题。我建议您仔细检查代码逻辑,结合调试信息,找出问题所在。如有其他问题,欢迎随时提问。
    feedcode
        9
    feedcode  
       364 天前
    你这程序从哪里看来的?你要抓包要用 packet socket https://man7.org/linux/man-pages/man7/packet.7.html
    lysS
        10
    lysS  
    OP
       364 天前
    @MozzieW 不是,要捕捉所有 IP 包,无论 tcp udp 还是 icmp
    lysS
        11
    lysS  
    OP
       363 天前
    @feedcode chat 给的
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   我们的愿景   ·   实用小工具   ·   5279 人在线   最高记录 6543   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 31ms · UTC 05:50 · PVG 13:50 · LAX 22:50 · JFK 01:50
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.