【问题标题】:Receive all IPv6 packets接收所有 IPv6 数据包
【发布时间】:2016-01-27 07:03:08
【问题描述】:

我如何在lo 接口上接收所有 IPv6 数据包(TCP、UDP、ICMP...)。我正在使用命令ping6 ::1 发送 ICMP 数据包,但没有收到。

谢谢

#include <linux/if_ether.h>
#include <error.h>
#include <stdlib.h>
#include <sys/types.h>


#include <unistd.h>
#include <netinet/in.h>
#include <netinet/ip6.h>
#include <string.h>
#include <stdio.h>
#include <sys/socket.h>
#include <arpa/inet.h>

int main() {
    int socket_fd;
    char buffer[1480];
    struct sockaddr_in6 sin6;
    struct sockaddr sin;

    socket_fd = socket(AF_INET6, SOCK_RAW, IPPROTO_RAW);
    setsockopt(socket_fd , SOL_SOCKET , SO_BINDTODEVICE , "lo" , strlen("lo")+ 1 );
    if (socket_fd < 0) {
        perror("Failed to create socket");
    }

    ssize_t data_size;

    // Why am I unable to receve any data?
    data_size = recvfrom(socket_fd, buffer, 1480, 0, &sin, (socklen_t *) &sin);
    return 0;
}

【问题讨论】:

    标签: c linux sockets ipv6


    【解决方案1】:

    RFC3542 说:

    我们注意到 IPPROTO_RAW 对于 IPv6 原始套接字(以及 IANA 当前用作下一个标头时保留 255 的值 字段)。

    所以 IPPROTO_RAW 不保留用于发送/接收 IPv6 数据包。

    使用 IPv4,您只能将 IPPROTO_RAW 用于发送,不能用于接收。见man raw(7):

    IPPROTO_RAW 套接字仅用于发送。如果你真的想收到 所有 IP 数据包,使用带有 ETH_P_IP 协议的 packet(7) 套接字。 请注意,与原始数据包不同,数据包套接字不会重新组装 IP 片段 插座。

    您可以使用以下内容:

    socket(PF_PACKET, SOCK_RAW, htons(ETH_P_ALL))
    

    但这可能会导致其他问题。

    如果您只是想监控流量,请查看pcap-library

    【讨论】:

      【解决方案2】:

      在您尝试从中读取数据之前,您没有bind()将您的套接字发送到某个地址。

      当使用 socket(2) 创建套接字时,它存在于名称空间(地址族)中,但没有分配给它的地址。 bind() 将 addr 指定的地址分配给文件描述符 sockfd 引用的套接字。 addrlen 指定 addr 指向的地址结构的大小(以字节为单位)。传统上,此操作称为“为套接字分配名称”。

      另见:how to bind raw socket to specific interface

      【讨论】:

      • 绑定在接口lo上; setsockopt(socket_fd , SOL_SOCKET , SO_BINDTODEVICE , "lo" , strlen("lo")+ 1 );
      猜你喜欢
      • 2018-04-27
      • 2021-01-08
      • 2015-02-17
      • 2012-01-26
      • 2015-11-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-09-09
      相关资源
      最近更新 更多